nlopt_opt make_opt(const mxArray *opts, unsigned n) { nlopt_opt opt = NULL, local_opt = NULL; nlopt_algorithm algorithm; double *tmp = NULL; unsigned i; algorithm = (nlopt_algorithm) struct_val_default(opts, "algorithm", NLOPT_NUM_ALGORITHMS); CHECK1(((int)algorithm) >= 0 && algorithm < NLOPT_NUM_ALGORITHMS, "invalid opt.algorithm"); tmp = (double *) mxCalloc(n, sizeof(double)); opt = nlopt_create(algorithm, n); CHECK1(opt, "nlopt: out of memory"); nlopt_set_lower_bounds(opt, struct_arrval(opts, "lower_bounds", n, fill(tmp, n, -HUGE_VAL))); nlopt_set_upper_bounds(opt, struct_arrval(opts, "upper_bounds", n, fill(tmp, n, +HUGE_VAL))); nlopt_set_stopval(opt, struct_val_default(opts, "stopval", -HUGE_VAL)); nlopt_set_ftol_rel(opt, struct_val_default(opts, "ftol_rel", 0.0)); nlopt_set_ftol_abs(opt, struct_val_default(opts, "ftol_abs", 0.0)); nlopt_set_xtol_rel(opt, struct_val_default(opts, "xtol_rel", 0.0)); nlopt_set_xtol_abs(opt, struct_arrval(opts, "xtol_abs", n, fill(tmp, n, 0.0))); nlopt_set_maxeval(opt, struct_val_default(opts, "maxeval", 0.0) < 0 ? 0 : struct_val_default(opts, "maxeval", 0.0)); nlopt_set_maxtime(opt, struct_val_default(opts, "maxtime", 0.0)); nlopt_set_population(opt, struct_val_default(opts, "population", 0)); nlopt_set_vector_storage(opt, struct_val_default(opts, "vector_storage", 0)); if (struct_arrval(opts, "initial_step", n, NULL)) nlopt_set_initial_step(opt, struct_arrval(opts, "initial_step", n, NULL)); if (mxGetField(opts, 0, "local_optimizer")) { const mxArray *local_opts = mxGetField(opts, 0, "local_optimizer"); CHECK1(mxIsStruct(local_opts), "opt.local_optimizer must be a structure"); CHECK1(local_opt = make_opt(local_opts, n), "error initializing local optimizer"); nlopt_set_local_optimizer(opt, local_opt); nlopt_destroy(local_opt); local_opt = NULL; } mxFree(tmp); return opt; }
Shredder::Shredder(double lower_limit, double upper_limit, double tolerance) : lower_limit(lower_limit) , upper_limit(upper_limit) , tolerance(tolerance) , opt(NULL) { opt = nlopt_create(NLOPT_LD_SLSQP, 1); nlopt_set_lower_bounds(opt, &lower_limit); nlopt_set_upper_bounds(opt, &upper_limit); nlopt_set_max_objective(opt, shredder_opt_objective, reinterpret_cast<void*>(this)); nlopt_set_maxeval(opt, 20); nlopt_set_ftol_abs(opt, 1e-7); nlopt_set_xtol_abs(opt, &tolerance); }
void Shredder::set_tolerance(double tolerance) { this->tolerance = tolerance; nlopt_set_xtol_abs(opt, &this->tolerance); }
int main(int argc, char *argv[]) { double XTOL = -1; /* to be set by "user" */ int NHITS = -1; int c; while ((c = getopt(argc, argv, "N:t:")) != -1) switch (c) { case 'N': NHITS = atoi(optarg); break; case 't': XTOL = atof(optarg); break; case '?': if (optopt == 'N' || optopt == 't') fprintf(stderr, "Option -%c requires argument.\n", optopt); else fprintf(stderr, "unknown option -%c\n", optopt); return 1; default: ; } if (XTOL < 0 || NHITS < 0) { fprintf(stderr, "please specify NHITS and XTOL with -N and -t\n"); return 1; } /* geometry like SNO+'s (as close to 9,000 PMTS as possible) */ int NTHETA = 67; int NPHI = 134; struct pmtmap pmtmap; pmtmap.N = NPHI*NTHETA; pmtmap.nphi = NPHI; pmtmap.ntheta = NTHETA; struct event e1; struct pos_data data; data.p = &pmtmap; data.e = &e1; init_random(); init_pmtmap(&data); make_event(&e1, NHITS); fill_pmt_info(&data); nlopt_opt opt; opt = nlopt_create(NLOPT_GN_ISRES, 3); double lb[3] = {-6, -6, -6}; double ub[3] = {6, 6, 6}; nlopt_set_lower_bounds(opt, lb); nlopt_set_upper_bounds(opt, ub); nlopt_set_min_objective(opt, mf_p, &data); double tols[3] = {XTOL, XTOL, XTOL}; nlopt_set_xtol_abs(opt, tols); nlopt_set_maxtime(opt, 10.0); /* unstick this */ nlopt_set_maxeval(opt, 4e5); /* if timing doesn't unstick it*/ nlopt_add_inequality_constraint(opt, radius_check, &data, 1e-10); double x[3] = {0, 0, 0}; double fval = mf_p(3, x, NULL, &data); nlopt_result ret; ret = nlopt_optimize(opt, x, &fval); if (ret > 0) printf("%g %g %g\n", x[0] - e1.spawn_pos[0], x[1] - e1.spawn_pos[1], x[2] - e1.spawn_pos[2]); else fprintf(stderr, "optimizing failed with code %d\n", ret); return 0; }
nlopt_result NLOPT_STDCALL nlopt_minimize_econstrained( nlopt_algorithm algorithm, int n, nlopt_func_old f, void *f_data, int m, nlopt_func_old fc, void *fc_data_, ptrdiff_t fc_datum_size, int p, nlopt_func_old h, void *h_data_, ptrdiff_t h_datum_size, const double *lb, const double *ub, /* bounds */ double *x, /* in: initial guess, out: minimizer */ double *minf, /* out: minimum */ double minf_max, double ftol_rel, double ftol_abs, double xtol_rel, const double *xtol_abs, double htol_rel, double htol_abs, int maxeval, double maxtime) { char *fc_data = (char *) fc_data_; char *h_data = (char *) h_data_; nlopt_opt opt; nlopt_result ret; int i; if (n < 0 || m < 0 || p < 0) return NLOPT_INVALID_ARGS; opt = nlopt_create(algorithm, (unsigned) n); if (!opt) return NLOPT_INVALID_ARGS; ret = nlopt_set_min_objective(opt, (nlopt_func) f, f_data); if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; } for (i = 0; i < m; ++i) { ret = nlopt_add_inequality_constraint(opt, (nlopt_func) fc, fc_data + i*fc_datum_size, 0.0); if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; } } (void) htol_rel; /* unused */ for (i = 0; i < p; ++i) { ret = nlopt_add_equality_constraint(opt, (nlopt_func) h, h_data + i*h_datum_size, htol_abs); if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; } } ret = nlopt_set_lower_bounds(opt, lb); if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; } ret = nlopt_set_upper_bounds(opt, ub); if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; } ret = nlopt_set_stopval(opt, minf_max); if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; } ret = nlopt_set_ftol_rel(opt, ftol_rel); if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; } ret = nlopt_set_ftol_abs(opt, ftol_abs); if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; } ret = nlopt_set_xtol_rel(opt, xtol_rel); if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; } ret = nlopt_set_xtol_abs(opt, xtol_abs); if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; } ret = nlopt_set_maxeval(opt, maxeval); if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; } ret = nlopt_set_maxtime(opt, maxtime); if (ret != NLOPT_SUCCESS) { nlopt_destroy(opt); return ret; } ret = nlopt_optimize(opt, x, minf); nlopt_destroy(opt); return ret; }
/* unlike nlopt_optimize() below, only handles minimization case */ static nlopt_result nlopt_optimize_(nlopt_opt opt, double *x, double *minf) { const double *lb, *ub; nlopt_algorithm algorithm; nlopt_func f; void *f_data; unsigned n, i; int ni; nlopt_stopping stop; if (!opt || !x || !minf || !opt->f || opt->maximize) return NLOPT_INVALID_ARGS; /* reset stopping flag */ nlopt_set_force_stop(opt, 0); opt->force_stop_child = NULL; /* copy a few params to local vars for convenience */ n = opt->n; ni = (int) n; /* most of the subroutines take "int" arg */ lb = opt->lb; ub = opt->ub; algorithm = opt->algorithm; f = opt->f; f_data = opt->f_data; if (n == 0) { /* trivial case: no degrees of freedom */ *minf = opt->f(n, x, NULL, opt->f_data); return NLOPT_SUCCESS; } *minf = HUGE_VAL; /* make sure rand generator is inited */ nlopt_srand_time_default(); /* default is non-deterministic */ /* check bound constraints */ for (i = 0; i < n; ++i) if (lb[i] > ub[i] || x[i] < lb[i] || x[i] > ub[i]) return NLOPT_INVALID_ARGS; stop.n = n; stop.minf_max = opt->stopval; stop.ftol_rel = opt->ftol_rel; stop.ftol_abs = opt->ftol_abs; stop.xtol_rel = opt->xtol_rel; stop.xtol_abs = opt->xtol_abs; stop.nevals = 0; stop.maxeval = opt->maxeval; stop.maxtime = opt->maxtime; stop.start = nlopt_seconds(); stop.force_stop = &(opt->force_stop); switch (algorithm) { case NLOPT_GN_DIRECT: case NLOPT_GN_DIRECT_L: case NLOPT_GN_DIRECT_L_RAND: if (!finite_domain(n, lb, ub)) return NLOPT_INVALID_ARGS; return cdirect(ni, f, f_data, lb, ub, x, minf, &stop, 0.0, (algorithm != NLOPT_GN_DIRECT) + 3 * (algorithm == NLOPT_GN_DIRECT_L_RAND ? 2 : (algorithm != NLOPT_GN_DIRECT)) + 9 * (algorithm == NLOPT_GN_DIRECT_L_RAND ? 1 : (algorithm != NLOPT_GN_DIRECT))); case NLOPT_GN_DIRECT_NOSCAL: case NLOPT_GN_DIRECT_L_NOSCAL: case NLOPT_GN_DIRECT_L_RAND_NOSCAL: if (!finite_domain(n, lb, ub)) return NLOPT_INVALID_ARGS; return cdirect_unscaled(ni, f, f_data, lb, ub, x, minf, &stop, 0.0, (algorithm != NLOPT_GN_DIRECT) + 3 * (algorithm == NLOPT_GN_DIRECT_L_RAND ? 2 : (algorithm != NLOPT_GN_DIRECT)) + 9 * (algorithm == NLOPT_GN_DIRECT_L_RAND ? 1 : (algorithm != NLOPT_GN_DIRECT))); case NLOPT_GN_ORIG_DIRECT: case NLOPT_GN_ORIG_DIRECT_L: { direct_return_code dret; if (!finite_domain(n, lb, ub)) return NLOPT_INVALID_ARGS; opt->work = malloc(sizeof(double) * nlopt_max_constraint_dim(opt->m, opt->fc)); if (!opt->work) return NLOPT_OUT_OF_MEMORY; dret = direct_optimize(f_direct, opt, ni, lb, ub, x, minf, stop.maxeval, -1, stop.start, stop.maxtime, 0.0, 0.0, pow(stop.xtol_rel, (double) n), -1.0, stop.force_stop, stop.minf_max, 0.0, NULL, algorithm == NLOPT_GN_ORIG_DIRECT ? DIRECT_ORIGINAL : DIRECT_GABLONSKY); free(opt->work); opt->work = NULL; switch (dret) { case DIRECT_INVALID_BOUNDS: case DIRECT_MAXFEVAL_TOOBIG: case DIRECT_INVALID_ARGS: return NLOPT_INVALID_ARGS; case DIRECT_INIT_FAILED: case DIRECT_SAMPLEPOINTS_FAILED: case DIRECT_SAMPLE_FAILED: return NLOPT_FAILURE; case DIRECT_MAXFEVAL_EXCEEDED: case DIRECT_MAXITER_EXCEEDED: return NLOPT_MAXEVAL_REACHED; case DIRECT_MAXTIME_EXCEEDED: return NLOPT_MAXTIME_REACHED; case DIRECT_GLOBAL_FOUND: return NLOPT_MINF_MAX_REACHED; case DIRECT_VOLTOL: case DIRECT_SIGMATOL: return NLOPT_XTOL_REACHED; case DIRECT_OUT_OF_MEMORY: return NLOPT_OUT_OF_MEMORY; case DIRECT_FORCED_STOP: return NLOPT_FORCED_STOP; } break; } case NLOPT_GD_STOGO: case NLOPT_GD_STOGO_RAND: #ifdef WITH_CXX if (!finite_domain(n, lb, ub)) return NLOPT_INVALID_ARGS; if (!stogo_minimize(ni, f, f_data, x, minf, lb, ub, &stop, algorithm == NLOPT_GD_STOGO ? 0 : (int) POP(2*n))) return NLOPT_FAILURE; break; #else return NLOPT_INVALID_ARGS; #endif #if 0 /* lacking a free/open-source license, we no longer use Rowan's code, and instead use by "sbplx" re-implementation */ case NLOPT_LN_SUBPLEX: { int iret, freedx = 0; if (!opt->dx) { freedx = 1; if (nlopt_set_default_initial_step(opt, x) != NLOPT_SUCCESS) return NLOPT_OUT_OF_MEMORY; } iret = nlopt_subplex(f_bound, minf, x, n, opt, &stop, opt->dx); if (freedx) { free(opt->dx); opt->dx = NULL; } switch (iret) { case -2: return NLOPT_INVALID_ARGS; case -20: return NLOPT_FORCED_STOP; case -10: return NLOPT_MAXTIME_REACHED; case -1: return NLOPT_MAXEVAL_REACHED; case 0: return NLOPT_XTOL_REACHED; case 1: return NLOPT_SUCCESS; case 2: return NLOPT_MINF_MAX_REACHED; case 20: return NLOPT_FTOL_REACHED; case -200: return NLOPT_OUT_OF_MEMORY; default: return NLOPT_FAILURE; /* unknown return code */ } break; } #endif case NLOPT_LN_PRAXIS: { double step; if (initial_step(opt, x, &step) != NLOPT_SUCCESS) return NLOPT_OUT_OF_MEMORY; return praxis_(0.0, DBL_EPSILON, step, ni, x, f_bound, opt, &stop, minf); } case NLOPT_LD_LBFGS: return luksan_plis(ni, f, f_data, lb, ub, x, minf, &stop, opt->vector_storage); case NLOPT_LD_VAR1: case NLOPT_LD_VAR2: return luksan_plip(ni, f, f_data, lb, ub, x, minf, &stop, opt->vector_storage, algorithm == NLOPT_LD_VAR1 ? 1 : 2); case NLOPT_LD_TNEWTON: case NLOPT_LD_TNEWTON_RESTART: case NLOPT_LD_TNEWTON_PRECOND: case NLOPT_LD_TNEWTON_PRECOND_RESTART: return luksan_pnet(ni, f, f_data, lb, ub, x, minf, &stop, opt->vector_storage, 1 + (algorithm - NLOPT_LD_TNEWTON) % 2, 1 + (algorithm - NLOPT_LD_TNEWTON) / 2); case NLOPT_GN_CRS2_LM: if (!finite_domain(n, lb, ub)) return NLOPT_INVALID_ARGS; return crs_minimize(ni, f, f_data, lb, ub, x, minf, &stop, (int) POP(0), 0); case NLOPT_G_MLSL: case NLOPT_G_MLSL_LDS: case NLOPT_GN_MLSL: case NLOPT_GD_MLSL: case NLOPT_GN_MLSL_LDS: case NLOPT_GD_MLSL_LDS: { nlopt_opt local_opt = opt->local_opt; nlopt_result ret; if (!finite_domain(n, lb, ub)) return NLOPT_INVALID_ARGS; if (!local_opt && (algorithm == NLOPT_G_MLSL || algorithm == NLOPT_G_MLSL_LDS)) return NLOPT_INVALID_ARGS; if (!local_opt) { /* default */ nlopt_algorithm local_alg = (algorithm == NLOPT_GN_MLSL || algorithm == NLOPT_GN_MLSL_LDS) ? nlopt_local_search_alg_nonderiv : nlopt_local_search_alg_deriv; /* don't call MLSL recursively! */ if (local_alg >= NLOPT_GN_MLSL && local_alg <= NLOPT_GD_MLSL_LDS) local_alg = (algorithm == NLOPT_GN_MLSL || algorithm == NLOPT_GN_MLSL_LDS) ? NLOPT_LN_COBYLA : NLOPT_LD_MMA; local_opt = nlopt_create(local_alg, n); if (!local_opt) return NLOPT_FAILURE; nlopt_set_ftol_rel(local_opt, opt->ftol_rel); nlopt_set_ftol_abs(local_opt, opt->ftol_abs); nlopt_set_xtol_rel(local_opt, opt->xtol_rel); nlopt_set_xtol_abs(local_opt, opt->xtol_abs); nlopt_set_maxeval(local_opt, nlopt_local_search_maxeval); } if (opt->dx) nlopt_set_initial_step(local_opt, opt->dx); for (i = 0; i < n && stop.xtol_abs[i] > 0; ++i) ; if (local_opt->ftol_rel <= 0 && local_opt->ftol_abs <= 0 && local_opt->xtol_rel <= 0 && i < n) { /* it is not sensible to call MLSL without *some* nonzero tolerance for the local search */ nlopt_set_ftol_rel(local_opt, 1e-15); nlopt_set_xtol_rel(local_opt, 1e-7); } opt->force_stop_child = local_opt; ret = mlsl_minimize(ni, f, f_data, lb, ub, x, minf, &stop, local_opt, (int) POP(0), algorithm >= NLOPT_GN_MLSL_LDS && algorithm != NLOPT_G_MLSL); opt->force_stop_child = NULL; if (!opt->local_opt) nlopt_destroy(local_opt); return ret; } case NLOPT_LD_MMA: case NLOPT_LD_CCSAQ: { nlopt_opt dual_opt; nlopt_result ret; #define LO(param, def) (opt->local_opt ? opt->local_opt->param : (def)) dual_opt = nlopt_create(LO(algorithm, nlopt_local_search_alg_deriv), nlopt_count_constraints(opt->m, opt->fc)); if (!dual_opt) return NLOPT_FAILURE; nlopt_set_ftol_rel(dual_opt, LO(ftol_rel, 1e-14)); nlopt_set_ftol_abs(dual_opt, LO(ftol_abs, 0.0)); nlopt_set_maxeval(dual_opt, LO(maxeval, 100000)); #undef LO if (algorithm == NLOPT_LD_MMA) ret = mma_minimize(n, f, f_data, opt->m, opt->fc, lb, ub, x, minf, &stop, dual_opt); else ret = ccsa_quadratic_minimize( n, f, f_data, opt->m, opt->fc, opt->pre, lb, ub, x, minf, &stop, dual_opt); nlopt_destroy(dual_opt); return ret; } case NLOPT_LN_COBYLA: { nlopt_result ret; int freedx = 0; if (!opt->dx) { freedx = 1; if (nlopt_set_default_initial_step(opt, x) != NLOPT_SUCCESS) return NLOPT_OUT_OF_MEMORY; } return cobyla_minimize(n, f, f_data, opt->m, opt->fc, opt->p, opt->h, lb, ub, x, minf, &stop, opt->dx); if (freedx) { free(opt->dx); opt->dx = NULL; } return ret; } case NLOPT_LN_NEWUOA: { double step; if (initial_step(opt, x, &step) != NLOPT_SUCCESS) return NLOPT_OUT_OF_MEMORY; return newuoa(ni, 2*n+1, x, 0, 0, step, &stop, minf, f_noderiv, opt); } case NLOPT_LN_NEWUOA_BOUND: { double step; if (initial_step(opt, x, &step) != NLOPT_SUCCESS) return NLOPT_OUT_OF_MEMORY; return newuoa(ni, 2*n+1, x, lb, ub, step, &stop, minf, f_noderiv, opt); } case NLOPT_LN_BOBYQA: { nlopt_result ret; int freedx = 0; if (!opt->dx) { freedx = 1; if (nlopt_set_default_initial_step(opt, x) != NLOPT_SUCCESS) return NLOPT_OUT_OF_MEMORY; } ret = bobyqa(ni, 2*n+1, x, lb, ub, opt->dx, &stop, minf, opt->f, opt->f_data); if (freedx) { free(opt->dx); opt->dx = NULL; } return ret; } case NLOPT_LN_NELDERMEAD: case NLOPT_LN_SBPLX: { nlopt_result ret; int freedx = 0; if (!opt->dx) { freedx = 1; if (nlopt_set_default_initial_step(opt, x) != NLOPT_SUCCESS) return NLOPT_OUT_OF_MEMORY; } if (algorithm == NLOPT_LN_NELDERMEAD) ret= nldrmd_minimize(ni,f,f_data,lb,ub,x,minf,opt->dx,&stop); else ret= sbplx_minimize(ni,f,f_data,lb,ub,x,minf,opt->dx,&stop); if (freedx) { free(opt->dx); opt->dx = NULL; } return ret; } case NLOPT_AUGLAG: case NLOPT_AUGLAG_EQ: case NLOPT_LN_AUGLAG: case NLOPT_LN_AUGLAG_EQ: case NLOPT_LD_AUGLAG: case NLOPT_LD_AUGLAG_EQ: { nlopt_opt local_opt = opt->local_opt; nlopt_result ret; if ((algorithm == NLOPT_AUGLAG || algorithm == NLOPT_AUGLAG_EQ) && !local_opt) return NLOPT_INVALID_ARGS; if (!local_opt) { /* default */ local_opt = nlopt_create( algorithm == NLOPT_LN_AUGLAG || algorithm == NLOPT_LN_AUGLAG_EQ ? nlopt_local_search_alg_nonderiv : nlopt_local_search_alg_deriv, n); if (!local_opt) return NLOPT_FAILURE; nlopt_set_ftol_rel(local_opt, opt->ftol_rel); nlopt_set_ftol_abs(local_opt, opt->ftol_abs); nlopt_set_xtol_rel(local_opt, opt->xtol_rel); nlopt_set_xtol_abs(local_opt, opt->xtol_abs); nlopt_set_maxeval(local_opt, nlopt_local_search_maxeval); } if (opt->dx) nlopt_set_initial_step(local_opt, opt->dx); opt->force_stop_child = local_opt; ret = auglag_minimize(ni, f, f_data, opt->m, opt->fc, opt->p, opt->h, lb, ub, x, minf, &stop, local_opt, algorithm == NLOPT_AUGLAG_EQ || algorithm == NLOPT_LN_AUGLAG_EQ || algorithm == NLOPT_LD_AUGLAG_EQ); opt->force_stop_child = NULL; if (!opt->local_opt) nlopt_destroy(local_opt); return ret; } case NLOPT_GN_ISRES: if (!finite_domain(n, lb, ub)) return NLOPT_INVALID_ARGS; return isres_minimize(ni, f, f_data, (int) (opt->m), opt->fc, (int) (opt->p), opt->h, lb, ub, x, minf, &stop, (int) POP(0)); // case NLOPT_GN_ESCH: // if (!finite_domain(n, lb, ub)) return NLOPT_INVALID_ARGS; // return chevolutionarystrategy(n, f, f_data, // lb, ub, x, minf, &stop, // (unsigned) POP(0), // (unsigned) (POP(0)*1.5)); case NLOPT_LD_SLSQP: return nlopt_slsqp(n, f, f_data, opt->m, opt->fc, opt->p, opt->h, lb, ub, x, minf, &stop); default: return NLOPT_INVALID_ARGS; } return NLOPT_SUCCESS; /* never reached */ }
void omxInvokeNLOPT(double *est, GradientOptimizerContext &goc) { goc.optName = "SLSQP"; goc.setupSimpleBounds(); goc.useGradient = true; FitContext *fc = goc.fc; int oldWanted = fc->wanted; fc->wanted = 0; omxState *globalState = fc->state; nlopt_opt opt = nlopt_create(NLOPT_LD_SLSQP, fc->numParam); goc.extraData = opt; //local_opt = nlopt_create(NLOPT_LD_SLSQP, n); // Subsidiary algorithm //nlopt_set_local_optimizer(opt, local_opt); nlopt_set_lower_bounds(opt, goc.solLB.data()); nlopt_set_upper_bounds(opt, goc.solUB.data()); int eq, ieq; globalState->countNonlinearConstraints(eq, ieq); if (fc->CI) { nlopt_set_xtol_rel(opt, 5e-3); std::vector<double> tol(fc->numParam, std::numeric_limits<double>::epsilon()); nlopt_set_xtol_abs(opt, tol.data()); } else { // The *2 is there to roughly equate accuracy with NPSOL. nlopt_set_ftol_rel(opt, goc.ControlTolerance * 2); nlopt_set_ftol_abs(opt, std::numeric_limits<double>::epsilon()); } nlopt_set_min_objective(opt, SLSQP::nloptObjectiveFunction, &goc); double feasibilityTolerance = Global->feasibilityTolerance; SLSQP::context ctx(goc); if (eq + ieq) { ctx.origeq = eq; if (ieq > 0){ goc.inequality.resize(ieq); std::vector<double> tol(ieq, feasibilityTolerance); nlopt_add_inequality_mconstraint(opt, ieq, SLSQP::nloptInequalityFunction, &goc, tol.data()); } if (eq > 0){ goc.equality.resize(eq); std::vector<double> tol(eq, feasibilityTolerance); nlopt_add_equality_mconstraint(opt, eq, SLSQP::nloptEqualityFunction, &ctx, tol.data()); } } int priorIterations = fc->iterations; int code = nlopt_optimize(opt, est, &fc->fit); if (ctx.eqredundent) { nlopt_remove_equality_constraints(opt); eq -= ctx.eqredundent; std::vector<double> tol(eq, feasibilityTolerance); nlopt_add_equality_mconstraint(opt, eq, SLSQP::nloptEqualityFunction, &ctx, tol.data()); code = nlopt_optimize(opt, est, &fc->fit); } if (goc.verbose >= 2) mxLog("nlopt_optimize returned %d", code); nlopt_destroy(opt); fc->wanted = oldWanted; if (code == NLOPT_INVALID_ARGS) { Rf_error("NLOPT invoked with invalid arguments"); } else if (code == NLOPT_OUT_OF_MEMORY) { Rf_error("NLOPT ran out of memory"); } else if (code == NLOPT_FORCED_STOP) { if (fc->iterations - priorIterations <= 1) { goc.informOut = INFORM_STARTING_VALUES_INFEASIBLE; } else { goc.informOut = INFORM_ITERATION_LIMIT; } } else if (code == NLOPT_ROUNDOFF_LIMITED) { if (fc->iterations - priorIterations <= 2) { Rf_error("%s: Failed due to singular matrix E or C in LSQ subproblem or " "rank-deficient equality constraint subproblem or " "positive directional derivative in line search", goc.optName); } else { goc.informOut = INFORM_NOT_AT_OPTIMUM; // is this correct? TODO } } else if (code < 0) { Rf_error("NLOPT fatal error %d", code); } else if (code == NLOPT_MAXEVAL_REACHED) { goc.informOut = INFORM_ITERATION_LIMIT; } else { goc.informOut = INFORM_CONVERGED_OPTIMUM; } }
int main(int argc, char *argv[]) { /* default values */ int NHITS = 10; double XTOL = .1; int c; while ((c = getopt(argc, argv, "N:t:")) != -1) switch (c) { case 'N': NHITS = atoi(optarg); break; case 't': XTOL = atof(optarg); break; case '?': if (optopt == 'N' || optopt == 't') fprintf(stderr, "Option -%c requires argument.\n", optopt); else fprintf(stderr, "unknown option -%c\n", optopt); return 1; default: ; } /* initialize random number resources */ init_random(); /* generate event */ struct event e1; make_event(&e1, NHITS); sort_event(&e1); nlopt_opt opt; opt = nlopt_create(NLOPT_GN_ISRES, 4); nlopt_result ret; double lb[4] = {-6, -6, -6, -10*scint_time}; double ub[4] = {6, 6, 6, e1.hits[0].hit_time}; nlopt_set_lower_bounds(opt, lb); nlopt_set_upper_bounds(opt, ub); struct pos_data data; data.p = NULL; /* no pmtmap required for timing fit */ data.e = &e1; nlopt_set_min_objective(opt, mf_t, &data); // nlopt_set_maxtime(opt, .5); double tols[4] = {XTOL, XTOL, XTOL, XTOL/light_speed}; nlopt_set_xtol_abs(opt, tols); ret = nlopt_add_inequality_constraint(opt, radius_check, &data, 1e-10); ret = nlopt_add_inequality_constraint(opt, time_check, &data, 1e-15); double x[4]; x[0] = x[1] = x[2] = x[3] = 0; double fval = mf_t(4, x, NULL, &data); ret = nlopt_optimize(opt, x, &fval); printf("actual location: \n"); printf("(x0, y0, z0, t0) = (%g, %g, %g, %g)\n", e1.spawn_pos[0], e1.spawn_pos[1], e1.spawn_pos[2], e1.spawn_time); printf("fitted to:\n"); printf("(x0, y0, z0, t0) = (%g, %g, %g, %g)\n", x[0], x[1], x[2], x[3]); printf("with log-likelihood %g\n", fval); printf("and return value %d\n", ret); printf("log-likelihood at actual value is %g\n", mf_t(4, e1.spawn_pos, NULL, &data)); free_random(); return 0; }
static int test_function(int ifunc) { nlopt_opt opt; testfunc func; int i, iter; double *x, minf, minf_max, f0, *xtabs, *lb, *ub; nlopt_result ret; double start = nlopt_seconds(); int total_count = 0, max_count = 0, min_count = 1 << 30; double total_err = 0, max_err = 0; bounds_wrap_data bw; if (ifunc < 0 || ifunc >= NTESTFUNCS) { fprintf(stderr, "testopt: invalid function %d\n", ifunc); listfuncs(stderr); return 0; } func = testfuncs[ifunc]; x = (double *) malloc(sizeof(double) * func.n * 5); if (!x) { fprintf(stderr, "testopt: Out of memory!\n"); return 0; } lb = x + func.n * 3; ub = lb + func.n; xtabs = x + func.n * 2; bw.lb = lb; bw.ub = ub; bw.f = func.f; bw.f_data = func.f_data; for (i = 0; i < func.n; ++i) xtabs[i] = xtol_abs; minf_max = minf_max_delta > (-HUGE_VAL) ? minf_max_delta + func.minf : (-HUGE_VAL); printf("-----------------------------------------------------------\n"); printf("Optimizing %s (%d dims) using %s algorithm\n", func.name, func.n, nlopt_algorithm_name(algorithm)); printf("lower bounds at lb = ["); for (i = 0; i < func.n; ++i) printf(" %g", func.lb[i]); printf("]\n"); printf("upper bounds at ub = ["); for (i = 0; i < func.n; ++i) printf(" %g", func.ub[i]); printf("]\n"); memcpy(lb, func.lb, func.n * sizeof(double)); memcpy(ub, func.ub, func.n * sizeof(double)); for (i = 0; i < func.n; ++i) if (fix_bounds[i]) { printf("fixing bounds for dim[%d] to xmin[%d]=%g\n", i, i, func.xmin[i]); lb[i] = ub[i] = func.xmin[i]; } if (force_constraints) { for (i = 0; i < func.n; ++i) { if (nlopt_iurand(2) == 0) ub[i] = nlopt_urand(lb[i], func.xmin[i]); else lb[i] = nlopt_urand(func.xmin[i], ub[i]); } printf("adjusted lower bounds at lb = ["); for (i = 0; i < func.n; ++i) printf(" %g", lb[i]); printf("]\n"); printf("adjusted upper bounds at ub = ["); for (i = 0; i < func.n; ++i) printf(" %g", ub[i]); printf("]\n"); } if (fabs(func.f(func.n, func.xmin, 0, func.f_data) - func.minf) > 1e-8) { fprintf(stderr, "BUG: function does not achieve given lower bound!\n"); fprintf(stderr, "f(%g", func.xmin[0]); for (i = 1; i < func.n; ++i) fprintf(stderr, ", %g", func.xmin[i]); fprintf(stderr, ") = %0.16g instead of %0.16g, |diff| = %g\n", func.f(func.n, func.xmin, 0, func.f_data), func.minf, fabs(func.f(func.n, func.xmin, 0, func.f_data) - func.minf)); free(x); return 0; } for (iter = 0; iter < iterations; ++iter) { double val; testfuncs_counter = 0; printf("Starting guess x = ["); for (i = 0; i < func.n; ++i) { if (center_start) x[i] = (ub[i] + lb[i]) * 0.5; else if (xinit_tol < 0) { /* random starting point near center of box */ double dx = (ub[i] - lb[i]) * 0.25; double xm = 0.5 * (ub[i] + lb[i]); x[i] = nlopt_urand(xm - dx, xm + dx); } else { x[i] = nlopt_urand(-xinit_tol, xinit_tol) + (1 + nlopt_urand(-xinit_tol, xinit_tol)) * func.xmin[i]; if (x[i] > ub[i]) x[i] = ub[i]; else if (x[i] < lb[i]) x[i] = lb[i]; } printf(" %g", x[i]); } printf("]\n"); f0 = func.f(func.n, x, x + func.n, func.f_data); printf("Starting function value = %g\n", f0); if (iter == 0 && testfuncs_verbose && func.has_gradient) { printf("checking gradient:\n"); for (i = 0; i < func.n; ++i) { double f; x[i] *= 1 + 1e-6; f = func.f(func.n, x, NULL, func.f_data); x[i] /= 1 + 1e-6; printf(" grad[%d] = %g vs. numerical derivative %g\n", i, x[i + func.n], (f - f0) / (x[i] * 1e-6)); } } testfuncs_counter = 0; opt = nlopt_create(algorithm, func.n); nlopt_set_min_objective(opt, bounds_wrap_func, &bw); nlopt_set_lower_bounds(opt, lb); nlopt_set_upper_bounds(opt, ub); nlopt_set_stopval(opt, minf_max); nlopt_set_ftol_rel(opt, ftol_rel); nlopt_set_ftol_abs(opt, ftol_abs); nlopt_set_xtol_rel(opt, xtol_rel); nlopt_set_xtol_abs(opt, xtabs); nlopt_set_maxeval(opt, maxeval); nlopt_set_maxtime(opt, maxtime); ret = nlopt_optimize(opt, x, &minf); printf("finished after %g seconds.\n", nlopt_seconds() - start); printf("return code %d from nlopt_minimize\n", ret); if (ret < 0 && ret != NLOPT_ROUNDOFF_LIMITED && ret != NLOPT_FORCED_STOP) { fprintf(stderr, "testopt: error in nlopt_minimize\n"); free(x); return 0; } printf("Found minimum f = %g after %d evaluations (numevals = %d).\n", minf, testfuncs_counter, nlopt_get_numevals(opt)); nlopt_destroy(opt); total_count += testfuncs_counter; if (testfuncs_counter > max_count) max_count = testfuncs_counter; if (testfuncs_counter < min_count) min_count = testfuncs_counter; printf("Minimum at x = ["); for (i = 0; i < func.n; ++i) printf(" %g", x[i]); printf("]\n"); if (func.minf == 0) printf("|f - minf| = %g\n", fabs(minf - func.minf)); else printf("|f - minf| = %g, |f - minf| / |minf| = %e\n", fabs(minf - func.minf), fabs(minf - func.minf) / fabs(func.minf)); total_err += fabs(minf - func.minf); if (fabs(minf - func.minf) > max_err) max_err = fabs(minf - func.minf); printf("vs. global minimum f = %g at x = [", func.minf); for (i = 0; i < func.n; ++i) printf(" %g", func.xmin[i]); printf("]\n"); val = func.f(func.n, x, NULL, func.f_data); if (fabs(val - minf) > 1e-12) { fprintf(stderr, "Mismatch %g between returned minf=%g and f(x) = %g\n", minf - val, minf, val); free(x); return 0; } } if (iterations > 1) printf("average #evaluations = %g (%d-%d)\naverage |f-minf| = %g, max |f-minf| = %g\n", total_count * 1.0 / iterations, min_count, max_count, total_err / iterations, max_err); free(x); return 1; }