Warning: this documentation for the development version is under construction.
00001 // Copyright (c) 2007-2010 Massachusetts Institute of Technology 00002 // Modifications by Marc Fragu, copyright (C) 2011 INRIA 00003 // 00004 // Permission is hereby granted, free of charge, to any person obtaining a 00005 // copy of this software and associated documentation files (the "Software"), 00006 // to deal in the Software without restriction, including without limitation 00007 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 // and/or sell copies of the Software, and to permit persons to whom the 00009 // Software is furnished to do so, subject to the following conditions: 00010 // 00011 // The above copyright notice and this permission notice shall be included in 00012 // all copies or substantial portions of the Software. 00013 // 00014 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00019 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00020 // DEALINGS IN THE SOFTWARE. 00021 00022 00023 #ifndef SELDON_COMPUTATION_OPTIMIZATION_NLOPT_HXX 00024 #define SELDON_COMPUTATION_OPTIMIZATION_NLOPT_HXX 00025 00026 00027 #include <nlopt.hpp> 00028 00029 00030 namespace nlopt 00031 { 00032 00033 00034 typedef double (*svfunc)(const Seldon::Vector<double> &x, 00035 Seldon::Vector<double> &grad, void *data); 00036 00037 class SeldonOpt 00038 { 00039 00040 private: 00041 00042 nlopt_opt o; 00043 00044 void mythrow(nlopt_result ret) const 00045 { 00046 switch (ret) 00047 { 00048 case NLOPT_FAILURE: 00049 throw Seldon::Error("SeldonOpt", "Nlopt failure."); 00050 case NLOPT_OUT_OF_MEMORY: 00051 throw Seldon::NoMemory("SeldonOpt", 00052 "Nlopt failed to allocate the" 00053 " requested storage space."); 00054 case NLOPT_INVALID_ARGS: 00055 throw Seldon::WrongArgument("SeldonOpt", "Nlopt invalid argument."); 00056 case NLOPT_ROUNDOFF_LIMITED: 00057 throw Seldon::Error("SeldonOpt", "Nlopt roundoff-limited."); 00058 case NLOPT_FORCED_STOP: 00059 throw Seldon::Error("SeldonOpt", "Nlopt forced stop."); 00060 default: 00061 break; 00062 } 00063 } 00064 00065 00066 typedef struct 00067 { 00068 SeldonOpt* o; 00069 mfunc mf; 00070 func f; 00071 void* f_data; 00072 svfunc vf; 00073 nlopt_munge munge_destroy, munge_copy; 00074 } myfunc_data; 00075 00076 00077 static void *free_myfunc_data(void *p) 00078 { 00079 myfunc_data *d = (myfunc_data *) p; 00080 if (d) 00081 { 00082 if (d->f_data && d->munge_destroy) 00083 d->munge_destroy(d->f_data); 00084 delete d; 00085 } 00086 return NULL; 00087 } 00088 00089 00090 static void *dup_myfunc_data(void *p) 00091 { 00092 myfunc_data *d = (myfunc_data *) p; 00093 if (d) 00094 { 00095 void *f_data; 00096 if (d->f_data && d->munge_copy) { 00097 f_data = d->munge_copy(d->f_data); 00098 if (!f_data) 00099 return NULL; 00100 } 00101 else 00102 f_data = d->f_data; 00103 myfunc_data *dnew = new myfunc_data; 00104 if (dnew) 00105 { 00106 *dnew = *d; 00107 dnew->f_data = f_data; 00108 } 00109 return (void*) dnew; 00110 } 00111 else 00112 return NULL; 00113 } 00114 00115 00116 static double myfunc(unsigned n, const double *x, double *grad, 00117 void *d_) 00118 { 00119 myfunc_data *d = reinterpret_cast<myfunc_data*>(d_); 00120 return d->f(n, x, grad, d->f_data); 00121 } 00122 00123 00124 static void mymfunc(unsigned m, double *result, 00125 unsigned n, const double *x, 00126 double *grad, void *d_) 00127 { 00128 myfunc_data *d = reinterpret_cast<myfunc_data*>(d_); 00129 d->mf(m, result, n, x, grad, d->f_data); 00130 return; 00131 } 00132 00133 00134 Seldon::Vector<double> xtmp, gradtmp, gradtmp0; 00135 00136 00137 static double myvfunc(unsigned n, const double *x, double *grad, 00138 void *d_) 00139 { 00140 myfunc_data *d = reinterpret_cast<myfunc_data*>(d_); 00141 Seldon::Vector<double> &xv = d->o->xtmp; 00142 if (n) 00143 memcpy(xv.GetData(), x, n * sizeof(double)); 00144 00145 double val=d->vf(xv, grad ? d->o->gradtmp : d->o->gradtmp0, 00146 d->f_data); 00147 if (grad && n) 00148 { 00149 Seldon::Vector<double> &gradv = d->o->gradtmp; 00150 memcpy(grad, gradv.GetData(), n * sizeof(double)); 00151 } 00152 return val; 00153 } 00154 00155 00156 void alloc_tmp() 00157 { 00158 if (xtmp.GetSize() != int(nlopt_get_dimension(o))) 00159 { 00160 xtmp = Seldon::Vector<double>(nlopt_get_dimension(o)); 00161 gradtmp = Seldon::Vector<double>(nlopt_get_dimension(o)); 00162 } 00163 } 00164 00165 00166 result last_result; 00167 double last_optf; 00168 nlopt_result forced_stop_reason; 00169 00170 00171 public: 00172 00173 SeldonOpt() : o(NULL), xtmp(0), gradtmp(0), gradtmp0(0), 00174 last_result(nlopt::FAILURE), last_optf(HUGE_VAL), 00175 forced_stop_reason(NLOPT_FORCED_STOP) 00176 { 00177 } 00178 00179 00180 ~SeldonOpt() 00181 { 00182 nlopt_destroy(o); 00183 } 00184 00185 00186 SeldonOpt(algorithm a, unsigned n) : 00187 o(nlopt_create(nlopt_algorithm(a), n)), 00188 xtmp(0), gradtmp(0), gradtmp0(0), 00189 last_result(nlopt::FAILURE), last_optf(HUGE_VAL), 00190 forced_stop_reason(NLOPT_FORCED_STOP) 00191 { 00192 if (!o) 00193 throw Seldon::NoMemory("SeldonOpt(algorithm a, unsigned n)", 00194 "Nlopt failed to allocate the" 00195 " requested storage space."); 00196 nlopt_set_munge(o, free_myfunc_data, dup_myfunc_data); 00197 } 00198 00199 00200 SeldonOpt(const SeldonOpt& f) : 00201 o(nlopt_copy(f.o)), 00202 xtmp(f.xtmp), gradtmp(f.gradtmp), 00203 gradtmp0(0), 00204 last_result(f.last_result), 00205 last_optf(f.last_optf), 00206 forced_stop_reason(f.forced_stop_reason) 00207 { 00208 if (f.o && !o) 00209 throw Seldon::NoMemory("SeldonOpt(const SeldonOpt& f)", 00210 "Nlopt failed to allocate the" 00211 " requested storage space."); 00212 } 00213 00214 00215 SeldonOpt& operator=(SeldonOpt const& f) 00216 { 00217 if (this == &f) 00218 return *this; 00219 nlopt_destroy(o); 00220 o = nlopt_copy(f.o); 00221 if (f.o && !o) 00222 throw Seldon::NoMemory("SeldonOpt::operator=(const SeldonOpt& f)", 00223 "Nlopt failed to allocate the" 00224 " requested storage space."); 00225 xtmp = f.xtmp; 00226 gradtmp = f.gradtmp; 00227 last_result = f.last_result; 00228 last_optf = f.last_optf; 00229 forced_stop_reason = f.forced_stop_reason; 00230 return *this; 00231 } 00232 00233 00234 result optimize(Seldon::Vector<double>& x, double& opt_f) 00235 { 00236 if (o && int(nlopt_get_dimension(o)) != x.GetSize()) 00237 throw Seldon::WrongArgument("SeldonOpt::optimize(" 00238 "Seldon::Vector<double>& x," 00239 " double& opt_f)", "Dimension mismatch."); 00240 forced_stop_reason = NLOPT_FORCED_STOP; 00241 nlopt_result ret = 00242 nlopt_optimize(o, x.GetSize() == 0 ? NULL : x.GetData(), 00243 &opt_f); 00244 last_result = result(ret); 00245 last_optf = opt_f; 00246 if (ret == NLOPT_FORCED_STOP) 00247 mythrow(forced_stop_reason); 00248 mythrow(ret); 00249 return last_result; 00250 } 00251 00252 00253 Seldon::Vector<double> optimize(const Seldon::Vector<double> &x0) 00254 { 00255 Seldon::Vector<double> x(x0); 00256 last_result = optimize(x, last_optf); 00257 return x; 00258 } 00259 00260 00261 result last_optimize_result() const 00262 { 00263 return last_result; 00264 } 00265 00266 00267 double last_optimum_value() const 00268 { 00269 return last_optf; 00270 } 00271 00272 00273 algorithm get_algorithm() const 00274 { 00275 if (!o) 00276 throw Seldon::Error("SeldonOpt::get_algorithm() const", 00277 "Uninitialized nlopt::SeldonOpt."); 00278 return algorithm(nlopt_get_algorithm(o)); 00279 } 00280 00281 00282 const char *get_algorithm_name() const 00283 { 00284 if (!o) 00285 Seldon::Error("SeldonOpt::get_algorithm() const", 00286 "Uninitialized nlopt::SeldonOpt."); 00287 return nlopt_algorithm_name(nlopt_get_algorithm(o)); 00288 } 00289 00290 00291 unsigned get_dimension() const 00292 { 00293 if (!o) 00294 Seldon::Error("SeldonOpt::get_algorithm() const", 00295 "Uninitialized nlopt::SeldonOpt."); 00296 return nlopt_get_dimension(o); 00297 } 00298 00299 00300 void set_min_objective(func f, void *f_data) 00301 { 00302 myfunc_data *d = new myfunc_data; 00303 if (!d) 00304 throw Seldon::NoMemory("SeldonOpt::set_min_objective(func f, " 00305 "void *f_data)", "Nlopt failed to allocate the" 00306 " requested storage space."); 00307 d->o = this; 00308 d->f = f; 00309 d->f_data = f_data; 00310 d->mf = NULL; 00311 d->vf = NULL; 00312 d->munge_destroy = d->munge_copy = NULL; 00313 mythrow(nlopt_set_min_objective(o, myfunc, d)); 00314 } 00315 00316 00317 void set_min_objective(svfunc vf, void *f_data) { 00318 myfunc_data *d = new myfunc_data; 00319 if (!d) 00320 throw Seldon::NoMemory("SeldonOpt::set_min_objective(func f, " 00321 "void *f_data)", "Nlopt failed to allocate the" 00322 " requested storage space."); 00323 d->o = this; 00324 d->f = NULL; 00325 d->f_data = f_data; 00326 d->mf = NULL; 00327 d->vf = vf; 00328 d->munge_destroy = d->munge_copy = NULL; 00329 mythrow(nlopt_set_min_objective(o, myvfunc, d)); 00330 alloc_tmp(); 00331 } 00332 00333 00334 void set_max_objective(func f, void *f_data) { 00335 myfunc_data *d = new myfunc_data; 00336 if (!d) 00337 throw Seldon::NoMemory("SeldonOpt::set_min_objective(func f, " 00338 "void *f_data)", "Nlopt failed to allocate the" 00339 " requested storage space."); 00340 d->o = this; 00341 d->f = f; 00342 d->f_data = f_data; 00343 d->mf = NULL; 00344 d->vf = NULL; 00345 d->munge_destroy = d->munge_copy = NULL; 00346 mythrow(nlopt_set_max_objective(o, myfunc, d)); 00347 } 00348 00349 00350 void set_max_objective(svfunc vf, void *f_data) 00351 { 00352 myfunc_data *d = new myfunc_data; 00353 if (!d) 00354 throw Seldon::NoMemory("SeldonOpt::set_max_objective(func f, " 00355 "void *f_data)", "Nlopt failed to allocate the" 00356 " requested storage space."); 00357 d->o = this; 00358 d->f = NULL; 00359 d->f_data = f_data; 00360 d->mf = NULL; 00361 d->vf = vf; 00362 d->munge_destroy = d->munge_copy = NULL; 00363 mythrow(nlopt_set_max_objective(o, myvfunc, d)); 00364 alloc_tmp(); 00365 } 00366 00367 00368 void set_min_objective(func f, void *f_data, 00369 nlopt_munge md, nlopt_munge mc) 00370 { 00371 myfunc_data *d = new myfunc_data; 00372 if (!d) 00373 throw Seldon::NoMemory("SeldonOpt::set_min_objective(func f, " 00374 "void *f_data)", "Nlopt failed to allocate the" 00375 " requested storage space."); 00376 d->o = this; 00377 d->f = f; 00378 d->f_data = f_data; 00379 d->mf = NULL; 00380 d->vf = NULL; 00381 d->munge_destroy = md; 00382 d->munge_copy = mc; 00383 mythrow(nlopt_set_min_objective(o, myfunc, d)); 00384 } 00385 00386 00387 void set_max_objective(func f, void *f_data, 00388 nlopt_munge md, nlopt_munge mc) 00389 { 00390 myfunc_data *d = new myfunc_data; 00391 if (!d) 00392 throw Seldon::NoMemory("SeldonOpt::set_max_objective(func f, " 00393 "void *f_data)", "Nlopt failed to allocate the" 00394 " requested storage space."); 00395 d->o = this; 00396 d->f = f; 00397 d->f_data = f_data; 00398 d->mf = NULL; 00399 d->vf = NULL; 00400 d->munge_destroy = md; 00401 d->munge_copy = mc; 00402 mythrow(nlopt_set_max_objective(o, myfunc, d)); 00403 } 00404 00405 00406 void remove_inequality_constraints() 00407 { 00408 nlopt_result ret = nlopt_remove_inequality_constraints(o); 00409 mythrow(ret); 00410 } 00411 00412 00413 void add_inequality_constraint(func f, void *f_data, double tol = 0) 00414 { 00415 myfunc_data *d = new myfunc_data; 00416 if (!d) 00417 throw Seldon::NoMemory("SeldonOpt::add_inequality_constraint(func f, " 00418 "void *f_data, double tol = 0)", 00419 "Nlopt failed to allocate the" 00420 " requested storage space."); 00421 d->o = this; 00422 d->f = f; 00423 d->f_data = f_data; 00424 d->mf = NULL; 00425 d->vf = NULL; 00426 d->munge_destroy = d->munge_copy = NULL; 00427 mythrow(nlopt_add_inequality_constraint(o, myfunc, d, tol)); 00428 } 00429 00430 00431 void add_inequality_constraint(svfunc vf, void *f_data, 00432 double tol = 0) 00433 { 00434 myfunc_data *d = new myfunc_data; 00435 if (!d) 00436 throw Seldon::NoMemory("SeldonOpt::add_inequality_constraint(func f, " 00437 "void *f_data, double tol = 0)", 00438 "Nlopt failed to allocate the" 00439 " requested storage space."); 00440 d->o = this; 00441 d->f = NULL; 00442 d->f_data = f_data; 00443 d->mf = NULL; 00444 d->vf = vf; 00445 d->munge_destroy = d->munge_copy = NULL; 00446 mythrow(nlopt_add_inequality_constraint(o, myvfunc, d, tol)); 00447 alloc_tmp(); 00448 } 00449 00450 00451 void add_inequality_mconstraint(mfunc mf, void *f_data, 00452 const Seldon::Vector<double> &tol) 00453 { 00454 myfunc_data *d = new myfunc_data; 00455 if (!d) 00456 throw Seldon::NoMemory("SeldonOpt::add_inequality_mconstraint(func f," 00457 " void *f_data, double tol = 0)", 00458 "Nlopt failed to allocate the" 00459 " requested storage space."); 00460 d->o = this; 00461 d->mf = mf; 00462 d->f_data = f_data; 00463 d->f = NULL; 00464 d->vf = NULL; 00465 d->munge_destroy = d->munge_copy = NULL; 00466 mythrow(nlopt_add_inequality_mconstraint(o, tol.GetSize(), 00467 mymfunc, d, 00468 tol.GetSize() == 0 00469 ? NULL : tol.GetData())); 00470 } 00471 00472 00473 void remove_equality_constraints() 00474 { 00475 nlopt_result ret = nlopt_remove_equality_constraints(o); 00476 mythrow(ret); 00477 } 00478 00479 00480 void add_equality_constraint(func f, void *f_data, double tol = 0) 00481 { 00482 myfunc_data *d = new myfunc_data; 00483 if (!d) 00484 throw Seldon::NoMemory("SeldonOpt::add_equality_constraint(func f, " 00485 "void *f_data, double tol = 0)", 00486 "Nlopt failed to allocate the" 00487 " requested storage space."); 00488 d->o = this; 00489 d->f = f; 00490 d->f_data = f_data; 00491 d->mf = NULL; 00492 d->vf = NULL; 00493 d->munge_destroy = d->munge_copy = NULL; 00494 nlopt_add_equality_constraint(o, myfunc, d, tol); 00495 mythrow(nlopt_add_equality_constraint(o, myfunc, d, tol)); 00496 } 00497 00498 00499 void add_equality_constraint(svfunc vf, void *f_data, double tol = 0) 00500 { 00501 myfunc_data *d = new myfunc_data; 00502 if (!d) 00503 throw Seldon::NoMemory("SeldonOpt::add_equality_constraint(func f, " 00504 "void *f_data, double tol = 0)", 00505 "Nlopt failed to allocate the" 00506 " requested storage space."); 00507 d->o = this; 00508 d->f = NULL; 00509 d->f_data = f_data; 00510 d->mf = NULL; 00511 d->vf = vf; 00512 d->munge_destroy = d->munge_copy = NULL; 00513 mythrow(nlopt_add_equality_constraint(o, myvfunc, d, tol)); 00514 alloc_tmp(); 00515 } 00516 00517 00518 void add_equality_mconstraint(mfunc mf, void *f_data, 00519 const Seldon::Vector<double> &tol) 00520 { 00521 myfunc_data *d = new myfunc_data; 00522 if (!d) 00523 throw Seldon::NoMemory("SeldonOpt::add_equality_mconstraint(func f, " 00524 "void *f_data, double tol = 0)", 00525 "Nlopt failed to allocate the" 00526 " requested storage space."); 00527 d->o = this; 00528 d->mf = mf; 00529 d->f_data = f_data; 00530 d->f = NULL; 00531 d->vf = NULL; 00532 d->munge_destroy = d->munge_copy = NULL; 00533 mythrow(nlopt_add_equality_mconstraint(o, tol.GetSize(), 00534 mymfunc, d, 00535 tol.GetSize() == 0 ? 00536 NULL : tol.GetData())); 00537 } 00538 00539 00540 // For internal use in SWIG wrappers (see also above) 00541 void add_inequality_constraint(func f, void *f_data, 00542 nlopt_munge md, nlopt_munge mc, 00543 double tol=0) 00544 { 00545 myfunc_data *d = new myfunc_data; 00546 if (!d) 00547 throw Seldon::NoMemory("SeldonOpt::add_inequality_constraint(func f, " 00548 "void *f_data, double tol = 0)", 00549 "Nlopt failed to allocate the" 00550 " requested storage space."); 00551 d->o = this; 00552 d->f = f; 00553 d->f_data = f_data; 00554 d->mf = NULL; 00555 d->vf = NULL; 00556 d->munge_destroy = md; 00557 d->munge_copy = mc; 00558 mythrow(nlopt_add_inequality_constraint(o, myfunc, d, tol)); 00559 } 00560 00561 00562 void add_equality_constraint(func f, void *f_data, 00563 nlopt_munge md, nlopt_munge mc, 00564 double tol=0) 00565 { 00566 myfunc_data *d = new myfunc_data; 00567 if (!d) 00568 throw Seldon::NoMemory("SeldonOpt::add_inequality_constraint(func f, " 00569 "void *f_data, double tol = 0)", 00570 "Nlopt failed to allocate the" 00571 " requested storage space."); 00572 d->o = this; 00573 d->f = f; 00574 d->f_data = f_data; 00575 d->mf = NULL; 00576 d->vf = NULL; 00577 d->munge_destroy = md; 00578 d->munge_copy = mc; 00579 mythrow(nlopt_add_equality_constraint(o, myfunc, d, tol)); 00580 } 00581 00582 00583 void add_inequality_mconstraint(mfunc mf, void *f_data, 00584 nlopt_munge md, nlopt_munge mc, 00585 const Seldon::Vector<double> &tol) 00586 { 00587 myfunc_data *d = new myfunc_data; 00588 if (!d) 00589 throw Seldon::NoMemory("SeldonOpt::add_inequality_mconstraint(func f," 00590 " void *f_data, double tol = 0)", 00591 "Nlopt failed to allocate the" 00592 " requested storage space."); 00593 d->o = this; 00594 d->mf = mf; 00595 d->f_data = f_data; 00596 d->f = NULL; 00597 d->vf = NULL; 00598 d->munge_destroy = md; d->munge_copy = mc; 00599 mythrow(nlopt_add_inequality_mconstraint(o, tol.GetSize(), 00600 mymfunc, d, 00601 tol.GetSize() == 0 00602 ? NULL : tol.GetData())); 00603 } 00604 00605 00606 void add_equality_mconstraint(mfunc mf, void *f_data, 00607 nlopt_munge md, nlopt_munge mc, 00608 const Seldon::Vector<double> &tol) 00609 { 00610 myfunc_data *d = new myfunc_data; 00611 if (!d) 00612 throw Seldon::NoMemory("SeldonOpt::add_equality_mconstraint(mfunc mf," 00613 " void *f_data," 00614 "nlopt_munge md, nlopt_munge mc," 00615 "const Seldon::Vector<double> &tol)", 00616 "Nlopt failed to allocate the" 00617 " requested storage space."); 00618 d->o = this; 00619 d->mf = mf; 00620 d->f_data = f_data; 00621 d->f = NULL; 00622 d->vf = NULL; 00623 d->munge_destroy = md; 00624 d->munge_copy = mc; 00625 mythrow(nlopt_add_equality_mconstraint(o, tol.GetSize(), mymfunc, 00626 d, tol.GetSize() == 0 00627 ? NULL : 00628 tol.GetData())); 00629 } 00630 00631 00632 #define SELDON_NLOPT_GETSET_VEC(name) \ 00633 void set_##name(double val) { \ 00634 mythrow(nlopt_set_##name##1(o, val)); \ 00635 } \ 00636 void get_##name(Seldon::Vector<double> &v) const { \ 00637 if (o && int(nlopt_get_dimension(o)) != v.GetSize()) \ 00638 throw Seldon::WrongArgument("SeldonOpt::get_" #name "(Vector&)" \ 00639 " const", \ 00640 "Nlopt invalid argument."); \ 00641 mythrow(nlopt_get_##name(o, v.GetSize() == 0 ? NULL : \ 00642 v.GetData())); \ 00643 } \ 00644 Seldon::Vector<double> get_##name() const { \ 00645 if (!o) throw \ 00646 Seldon::Error("SeldonOpt::get_" #name "() const", \ 00647 "Uninitialized nlopt::SeldonOpt."); \ 00648 Seldon::Vector<double> v(nlopt_get_dimension(o)); \ 00649 get_##name(v); \ 00650 return v; \ 00651 } \ 00652 void set_##name(const Seldon::Vector<double> &v) { \ 00653 if (o && int(nlopt_get_dimension(o)) != v.GetSize()) \ 00654 throw Seldon::WrongArgument("SeldonOpt::get_" #name "(Vector&)" \ 00655 " const", \ 00656 "Nlopt invalid argument."); \ 00657 mythrow(nlopt_set_##name(o, v.GetSize() == 0 ? \ 00658 NULL : v.GetData())); \ 00659 } 00660 00661 SELDON_NLOPT_GETSET_VEC(lower_bounds) 00662 SELDON_NLOPT_GETSET_VEC(upper_bounds) 00663 00664 00665 #define SELDON_NLOPT_GETSET(T, name) \ 00666 T get_##name() const { \ 00667 if (!o) throw \ 00668 Seldon::Error("SeldonOpt::get_" #name "() const", \ 00669 "Uninitialized nlopt::SeldonOpt."); \ 00670 return nlopt_get_##name(o); \ 00671 } \ 00672 void set_##name(T name) { \ 00673 mythrow(nlopt_set_##name(o, name)); \ 00674 } 00675 00676 00677 SELDON_NLOPT_GETSET(double, stopval) 00678 SELDON_NLOPT_GETSET(double, ftol_rel) 00679 SELDON_NLOPT_GETSET(double, ftol_abs) 00680 SELDON_NLOPT_GETSET(double, xtol_rel) 00681 SELDON_NLOPT_GETSET_VEC(xtol_abs) 00682 SELDON_NLOPT_GETSET(int, maxeval) 00683 SELDON_NLOPT_GETSET(double, maxtime) 00684 00685 SELDON_NLOPT_GETSET(int, force_stop) 00686 00687 00688 void force_stop() 00689 { 00690 set_force_stop(1); 00691 } 00692 00693 00694 void set_local_optimizer(const SeldonOpt &lo) 00695 { 00696 nlopt_result ret = nlopt_set_local_optimizer(o, lo.o); 00697 mythrow(ret); 00698 } 00699 00700 00701 SELDON_NLOPT_GETSET(unsigned, population) 00702 SELDON_NLOPT_GETSET_VEC(initial_step) 00703 00704 00705 void set_default_initial_step(const Seldon::Vector<double>& x) 00706 { 00707 nlopt_result ret 00708 = nlopt_set_default_initial_step(o, x.GetSize() == 0 ? 00709 NULL : x.GetData()); 00710 mythrow(ret); 00711 } 00712 00713 00714 void get_initial_step(const Seldon::Vector<double> &x, 00715 Seldon::Vector<double> &dx) const 00716 { 00717 if (o && (int(nlopt_get_dimension(o)) != x.GetSize() 00718 || int(nlopt_get_dimension(o)) != dx.GetSize())) 00719 throw Seldon::WrongArgument("SeldonOpt::get_initial_step(" 00720 "Vector<double>& x, double& dx)", 00721 "Dimension mismatch."); 00722 nlopt_result ret = nlopt_get_initial_step(o, x.GetSize() == 0 ? 00723 NULL : x.GetData(), 00724 dx.GetSize() == 0 ? 00725 NULL : dx.GetData()); 00726 mythrow(ret); 00727 } 00728 00729 00730 Seldon::Vector<double> get_initial_step_(const Seldon::Vector<double>& x) 00731 const 00732 { 00733 if (!o) 00734 throw Seldon::Error("SeldonOpt::get_initial_step_" 00735 "(const Seldon::Vector<double>& x)", 00736 "Uninitialized nlopt::SeldonOpt."); 00737 Seldon::Vector<double> v(nlopt_get_dimension(o)); 00738 get_initial_step(x, v); 00739 return v; 00740 } 00741 }; 00742 00743 00744 #undef SELDON_NLOPT_GETSET 00745 #undef SELDON_NLOPT_GETSET_VEC 00746 00747 00748 } 00749 00750 #endif