chiark / gitweb /
Fix math layout
[nlopt.git] / doc / docs / NLopt_C-plus-plus_Reference.md
1 ---
2 # NLopt C-plus-plus Reference
3 ---
4
5 NLopt is written in C and the C NLopt programming interface (API), as described in the [NLopt Reference](NLopt_Reference.md), is directly callable from C++.
6
7 However, we also provide a C++ header file, nlopt.hpp, that wraps a more natural C++ interface around the NLopt API, which may be more convenient for C++ programmers. (This C++ API is also the basis for the NLopt wrappers in some other languages, such as [Python](NLopt_Python_Reference.md).)
8
9 The main distinctions of the C++ API are:
10
11 -   Use of the `nlopt::` namespace.
12 -   Use of a bona-fide C++ `nlopt::opt` class, instead of `nlopt_opt`, with constructors, destructors, etcetera.
13 -   Use of `std::vector`<double> instead of array arguments.
14 -   Use of exceptions instead of returning error codes, and exception-safety in the objective/constraint functions.
15 -   Overloading and related C++ features to simplify some parts of the API.
16
17 The main purpose of this section is to document the syntax and unique features of the C++ API; for more detail on the underlying features, please refer to the C documentation in the [NLopt Reference](NLopt_Reference.md).
18
19 Compiling and linking your program to NLopt
20 -------------------------------------------
21
22 An NLopt program in C++ should include the NLopt C++ header file:
23
24 `#include `<nlopt.hpp>
25
26 On Unix, you would normally link your program exactly as for the C API, with a command something like:
27
28 *`compiler`*` `*`...source/object` `files...`*` -lnlopt -lm -o myprogram`
29
30 where *compiler* is `g++` or whatever is appropriate for your machine/system.
31
32 The `nlopt::opt` object
33 -----------------------
34
35 The NLopt API revolves around an object of type `nlopt::opt`. Via methods of this object, all of the parameters of the optimization are specified (dimensions, algorithm, stopping criteria, constraints, objective function, etcetera), and then one finally calls the `nlopt::opt::optimize` method in order to perform the optimization. The object should normally be created via the constructor:
36
37 ```
38 nlopt::opt(nlopt::algorithm, unsigned n);
39 ```
40
41
42 given an `algorithm` (see [NLopt Algorithms](NLopt_Algorithms.md) for possible values) and the dimensionality of the problem (`n`, the number of optimization parameters). Whereas the C algorithms are specified by `nlopt_algorithm` constants of the form `NLOPT_MMA`, `NLOPT_COBYLA`, etcetera, the C++ `nlopt::algorithm` values are of the form `nlopt::MMA`, `nlopt::COBYLA`, etcetera (with the `NLOPT_` prefix replaced by the `nlopt::` namespace).
43
44 There are also a copy constructor `nlopt::opt(nlopt::opt` `const&)` and an assignment `operator=(nlopt::opt` `const&)`, both of which make a copy of a given object (equivalent to `nlopt_copy` in the C API).
45
46 If there is an error in the constructor (or copy constructor, or assignment), a `std::bad_alloc` exception is thrown.
47
48 There is, of course, a `~nlopt::opt()` destructor, so the object will be automatically deallocated once it goes out of scope.
49
50 The algorithm and dimension parameters of the object are immutable (cannot be changed without constructing a new object), but you can query them for a given object by the methods:
51
52 ```
53 nlopt::algorithm nlopt::opt::get_algorithm() const;
54 unsigned nlopt::opt::get_dimension() const;
55 ```
56
57
58 You can get a (0-terminated) C-style string description of the algorithm via:
59
60 ```
61 const char *nlopt::opt::get_algorithm_name() const;
62 ```
63
64
65 (These accessor methods, along with the other methods below, will throw an exception if you use them on an object initialized with the default no-argument constructor, i.e. if you didn't specify an algorithm or dimensionality yet.)
66
67 Objective function
68 ------------------
69
70 The objective function is specified by calling one of the methods:
71
72 ```
73 void nlopt::opt::set_min_objective(nlopt::vfunc f, void* f_data);
74 void nlopt::opt::set_max_objective(nlopt::vfunc f, void* f_data);
75 ```
76
77
78 depending on whether one wishes to minimize or maximize the objective function `f`, respectively. The function `f` should be of the form:
79
80 ```
81  double f(const std::vector`<double>` &x, std::vector`<double>` &grad, void* f_data);
82 ```
83
84
85 The return value should be the value of the function at the point `x`, where `x` is a vector of length `n` of the optimization parameters (the same as the dimension passed to the constructor).
86
87 In addition, if the argument `grad` is not empty, i.e. `!grad.empty()` or equivalently `grad.size()>0`, then `grad` is a vector of length `n` which should (upon return) be set to the gradient of the function with respect to the optimization parameters at `x`. That is, `grad[i]` should upon return contain the partial derivative $\partial f / \partial x_i$, for $0 \leq i < n$, if `grad` is non-empty. Not all of the optimization algorithms (below) use the gradient information: for algorithms listed as "derivative-free," the `grad` argument will always be empty and need never be computed. (For algorithms that do use gradient information, however, `grad` may still be empty for some calls.)
88
89 The `f_data` argument is the same as the one passed to `nlopt_set_min_objective` or `nlopt_set_max_objective`, and may be used to pass any additional data through to the function. (That is, it may be a pointer to some caller-defined data structure/type containing information your function needs, which you convert from `void*` by a typecast.) You can just pass `NULL` for `f_data` if you don't want to pass any additional information. Note that the `nlopt::opt` object does *not* make a copy of whatever is pointed to by your `f_data` pointer; you must not deallocate its contents until *after* you are done calling `nlopt::opt::optimize`. (There is a low-level way to make the nlopt::opt object "take ownership" of the f_data pointer, which is mainly used for wrapping other languages.) 
90
91 Technically, in order to use `std::vector`<double> arguments for your objective function, wrapping the C API which only uses `double*`, NLopt has to make a copy of the C `double*` array to convert it to `std::vector`<double>. This incurs a slight memory and time overhead, which is likely to be negligible in most applications, but can be avoided by instead passing a C-style objective function:
92
93 ```
94 void nlopt::opt::set_min_objective(nlopt::func f, void* f_data);
95 void nlopt::opt::set_max_objective(nlopt::func f, void* f_data);
96 ```
97
98
99 where `f` is of the same form as the [C objective function](NLopt_Reference#Objective_function.md).
100
101 Bound constraints
102 -----------------
103
104 The [bound constraints](NLopt_Reference#Bound_constraints.md) can be specified by calling the methods:
105
106 ```
107 void nlopt::opt::set_lower_bounds(const std::vector`<double>` &lb);
108 void nlopt::opt::set_upper_bounds(const std::vector`<double>` &ub);
109 ```
110
111
112 where `lb` and `ub` are vectors of length *n* (the same as the dimension passed to the `nlopt::opt` constructor). For convenience, these are overloaded with functions that take a single number as arguments, in order to set the lower/upper bounds for all optimization parameters to a single constant:
113
114 ```
115 void nlopt::opt::set_lower_bounds(double lb);
116 void nlopt::opt::set_upper_bounds(double ub);
117 ```
118
119
120 To retrieve the values of the lower/upper bounds, you can call one of:
121
122 ```
123 void nlopt::opt::get_lower_bounds(std::vector`<double>` &lb);
124 void nlopt::opt::get_upper_bounds(std::vector`<double>` &ub);
125 std::vector`<double>` nlopt::opt::get_lower_bounds();
126 std::vector`<double>` nlopt::opt::get_upper_bounds();
127 ```
128
129
130 where the first two functions set their arguments (which must be vectors of length `n`) to copies of the bounds, and the second two functions return copies of the bounds as new vectors.
131
132 Nonlinear constraints
133 ---------------------
134
135 Just as for [nonlinear constraints in C](NLopt_Reference#Nonlinear_constraints.md), you can specify nonlinear inequality and equality constraints by the methods:
136
137 ```
138 void nlopt::opt::add_inequality_constraint(nlopt::vfunc fc, void *fc_data, double tol=0);
139 void nlopt::opt::add_equality_constraint(nlopt::vfunc h, void *h_data, double tol=0);
140 ```
141
142
143 where the arguments `fc` and `h` have the same form as the objective function above. Just as for the objective function, these constraint functions can either take `std::vector`<double> arguments or can take double\* arguments exactly as in the C API.
144
145 To remove all of the inequality and/or equality constraints from a given problem, you can call the following methods:
146
147 ```
148 void nlopt::opt::remove_inequality_constraints();
149 void nlopt::opt::remove_equality_constraints();
150 ```
151
152
153 ### Vector-valued constraints
154
155 Just as for [nonlinear constraints in C](NLopt_Reference#Vector-valued_constraints.md), you can specify nonlinear inequality and equality constraints by the methods:
156
157 ```
158 void nlopt::opt::add_inequality_mconstraint(nlopt::mfunc c, void *c_data, const vector`<double>` &tol);
159 void nlopt::opt::add_equality_mconstraint(nlopt::mfunc c, void *c_data, const vector`<double>` &tol);
160 ```
161
162
163 Here, `tol` is a vector of the tolerances in each constraint dimension; the dimensionality *m* of the constraint is determined by `tol.size()`. The constraint function `c` is of the same form as in C.
164
165 (You can add multiple vector-valued constraints and/or scalar constraints in the same problem.)
166
167 Stopping criteria
168 -----------------
169
170 As explained in the [C API Reference](NLopt_Reference#Stopping_criteria.md) and the [Introduction](NLopt_Introduction#Termination_conditions.md)), you have multiple options for different stopping criteria that you can specify. (Unspecified stopping criteria are disabled; i.e., they have innocuous defaults.)
171
172 For each stopping criteria, there are (at least) two method: a `set` method to specify the stopping criterion, and a `get` method to retrieve the current value for that criterion. The meanings of each criterion are exactly the same as in the C API.
173
174 ```
175 void nlopt::opt::set_stopval(double stopval);
176 double nlopt::opt::get_stopval() const;
177 ```
178
179
180 Stop when an objective value of at least stopval is found.
181
182 ```
183 void nlopt::opt::set_ftol_rel(double tol);
184 double nlopt::opt::get_ftol_rel() const;
185 ```
186
187
188 Set relative tolerance on function value.
189
190 ```
191 void nlopt::opt::set_ftol_abs(double tol);
192 double nlopt::opt::get_ftol_abs() const;
193 ```
194
195
196 Set absolute tolerance on function value.
197
198 ```
199 void nlopt::opt::set_xtol_rel(double tol);
200 double nlopt::opt::get_xtol_rel() const;
201 ```
202
203
204 Set relative tolerance on optimization parameters.
205
206 ```
207 void nlopt::opt::set_xtol_abs(const std::vector`<double>` &tol);
208 void nlopt::opt::set_xtol_abs(double tol);
209 void nlopt::opt::get_xtol_abs(std::vector`<double>` &tol) const;
210 std::vector`<double>` nlopt::opt::get_xtol_abs() const;
211 ```
212
213
214 Set absolute tolerances on optimization parameters. The `tol` vector must be of length `n` (the dimension specified in the `nlopt::opt` constructor). The second `set_xtol_abs` variant sets all `n` tolerances to the same value `tol`. The first `get_xtol_abs` variant modifies its argument to a copy of the current tolerances, whereas the second variant returns a copy.
215
216 ```
217 void nlopt::opt::set_maxeval(int maxeval);
218 int nlopt::opt::get_maxeval() const;
219 ```
220
221
222 Stop when the number of function evaluations exceeds `maxeval`.
223
224 ```
225 void nlopt::opt::set_maxtime(double maxtime);
226 double nlopt::opt::get_maxtime() const;
227 ```
228
229
230 Stop when the optimization time (in seconds) exceeds `maxtime`.
231
232 ```
233 int nlopt::opt::get_numevals() const;
234 ```
235
236
237 Request the number of evaluations.
238
239 ### Forced termination
240
241 In certain cases, the caller may wish to *force* the optimization to halt, for some reason unknown to NLopt. For example, if the user presses Ctrl-C, or there is an error of some sort in the objective function. You can do this by throwing *any* exception inside your objective/constraint functions: the exception will be caught, the optimization will be halted gracefully, and another exception (possibly not the same one) will be rethrown. See [Exceptions](#Exceptions.md), below. The C++ equivalent of `nlopt_forced_stop` from the [C API](NLopt_Reference#Forced_termination.md) is to throw an `nlopt::forced_stop` exception.
242
243 Performing the optimization
244 ---------------------------
245
246 Once all of the desired optimization parameters have been specified in a given object `opt`, you can perform the optimization by calling:
247
248 ```
249 nlopt::result nlopt::opt::optimize(std::vector`<double>` &x, double &opt_f);
250 ```
251
252
253 On input, `x` is a vector of length `n` (the dimension of the problem from the `nlopt::opt` constructor) giving an initial guess for the optimization parameters. On successful return, `x` contains the optimized values of the optimization parameters, and `opt_f` contains the corresponding value of the objective function.
254
255 The return value (see below) is positive on success, indicating the reason for termination. On failure (negative return codes), it throws an exception (see [Exceptions](#Exceptions.md), below).
256
257 You can also call the following methods to retrieve the `opt_f` value from the last `optimize` call, and the return value (including negative/failure return values) from the last `optimize` call:
258
259 ```
260 double nlopt::opt::last_optimum_value() const;
261 nlopt::result nlopt::opt::last_optimize_result() const;
262 ```
263
264
265 ### Return values
266
267 The possible return values are the same as the [return values in the C API](NLopt_Reference#Return_values.md), except that the `NLOPT_` prefix is replaced with the `nlopt::` namespace. That is, `NLOPT_SUCCESS` becomes `nlopt::SUCCESS`, etcetera.
268
269 Exceptions
270 ----------
271
272 The [Error codes (negative return values)](NLopt_Reference#Error_codes_(negative_return_values).md) in the C API are replaced in the C++ API by thrown exceptions. The following exceptions are thrown by the various routines:
273
274 ```
275 std::runtime_error
276 ```
277
278 Generic failure, equivalent to `NLOPT_FAILURE`.
279
280 ```
281 std::invalid_argument
282 ```
283
284 Invalid arguments (e.g. lower bounds are bigger than upper bounds, an unknown algorithm was specified, etcetera), equivalent to `NLOPT_INVALID_ARGS`.
285
286 ```
287 std::bad_alloc
288 ```
289
290 Ran out of memory (a memory allocation failed), equivalent to `NLOPT_OUT_OF_MEMORY`.
291
292 `nlopt::roundoff_limited` (subclass of `std::runtime_error`)
293 Halted because roundoff errors limited progress, equivalent to `NLOPT_ROUNDOFF_LIMITED`.
294
295 `nlopt::forced_stop` (subclass of `std::runtime_error`)
296 Halted because of a [forced termination](#Forced_termination.md): the user called `nlopt::opt::force_stop()` from the user’s objective function or threw an `nlopt::forced_stop` exception. Equivalent to `NLOPT_FORCED_STOP`.
297
298 If your objective/constraint functions throw *any* exception during the execution of `nlopt::opt::optimize`, it will be caught by NLopt and the optimization will be halted gracefully, and `nlopt::opt::optimize` will re-throw an exception. However, the exception that is re-thrown by `nlopt::opt::optimize` will be one of the five exceptions above; if the exception thrown by your code was not one of these five, it will be converted to a generic `std::runtime_error` exception. (The reason for this is that C++ has no clean way to save an arbitrary exception and rethrow it later, outside the original `catch` statement.) Therefore, if you want to do something special in response to a particular exception that is not one of these five, you should catch it yourself in your function, handle it however you want, and re-throw if desired.
299
300 Local/subsidiary optimization algorithm
301 ---------------------------------------
302
303 Some of the algorithms, especially MLSL and AUGLAG, use a different optimization algorithm as a subroutine, typically for local optimization. You can change the local search algorithm and its tolerances by calling:
304
305 ```
306 void nlopt::opt::set_local_optimizer(const nlopt::opt &local_opt);
307 ```
308
309
310 Here, `local_opt` is another `nlopt::opt` object whose parameters are used to determine the local search algorithm, its stopping criteria, and other algorithm parameters. (However, the objective function, bounds, and nonlinear-constraint parameters of `local_opt` are ignored.) The dimension `n` of `local_opt` must match that of `opt`.
311
312 This function makes a copy of the `local_opt` object, so you can freely destroy your original `local_opt` afterwards.
313
314 Initial step size
315 -----------------
316
317 Just as in the C API, you can [get and set the initial step sizes](NLopt_Reference#Initial_step_size.md) for derivative-free optimization algorithms. The C++ equivalents of the C functions are the following methods:
318
319 ```
320 void nlopt::opt::set_initial_step(const std::vector`<double>` &dx);
321 void nlopt::opt::set_initial_step(double dx);
322 void nlopt::opt::get_initial_step(const std::vector`<double>` &x, std::vector`<double>` &dx) const;
323 std::vector`<double>` nlopt::opt::get_initial_step(const std::vector`<double>` &x) const;
324 ```
325
326
327 Stochastic population
328 ---------------------
329
330 Just as in the C API, you can [get and set the initial population](NLopt_Reference#Stochastic_population.md) for stochastic optimization algorithms, by the methods:
331
332 ```
333 void nlopt::opt::set_population(unsigned pop);
334 unsigned nlopt::opt::get_population() const;
335 ```
336
337
338 (A `pop` of zero implies that the heuristic default will be used.)
339
340 Pseudorandom numbers
341 --------------------
342
343 For stochastic optimization algorithms, we use pseudorandom numbers generated by the [Mersenne Twister](https://en.wikipedia.org/wiki/Mersenne_twister) algorithm, based on code from Makoto Matsumoto. By default, the [seed](https://en.wikipedia.org/wiki/Random_seed) for the random numbers is generated from the system time, so that you will get a different sequence of pseudorandom numbers each time you run your program. If you want to use a "deterministic" sequence of pseudorandom numbers, i.e. the same sequence from run to run, you can set the seed by calling:
344
345 ```
346 void nlopt::srand(unsigned long seed);
347 ```
348
349
350 To reset the seed based on the system time, you can call:
351
352 ```
353 void nlopt::srand_time();
354 ```
355
356
357 (Normally, you don't need to call this as it is called automatically. However, it might be useful if you want to "re-randomize" the pseudorandom numbers after calling `nlopt::srand` to set a deterministic seed.)
358
359 Vector storage for limited-memory quasi-Newton algorithms
360 ---------------------------------------------------------
361
362 Just as in the C API, you can get and set the [number *M* of stored vectors](NLopt_Reference#Vector_storage_for_limited-memory_quasi-Newton_algorithms.md) for limited-memory quasi-Newton algorithms, via the methods:
363
364 ```
365 void nlopt::opt::set_vector_storage(unsigned M);
366 unsigned nlopt::opt::get_vector_storage() const;
367 ```
368
369
370 (The default is *M*=0, in which case NLopt uses a heuristic nonzero value.)
371
372 Version number
373 --------------
374
375 To determine the version number of NLopt at runtime, you can call:
376
377 ```
378 void nlopt::version(int &major, int &minor, int &bugfix);
379 ```
380
381
382 For example, NLopt version 3.1.4 would return `major=3`, `minor=1`, and `bugfix=4`. You can also retrieve these three values individually by calling:
383
384 ```
385 int nlopt::version_major();
386 int nlopt::version_minor();
387 int nlopt::version_bugfix();
388 ```
389
390
391 [Category:NLopt](index.md)