static void listalgs(FILE *f) { int i; fprintf(f, "Available algorithms:\n"); for (i = 0; i < NLOPT_NUM_ALGORITHMS; ++i) fprintf(f, " %2d: %s\n", i, nlopt_algorithm_name((nlopt_algorithm) i)); }
int CNLopt::run(double (*error_func)(unsigned int nParams, const double* params, double* grad, void* misc)) { // Create a member function pointer unsigned int n_data = mWorkerThread->GetDataSize(); mOpt = nlopt_create(mAlgorithm, mNParams); // xopt = new double [mNParams]; lb = new double [mNParams]; ub = new double [mNParams]; // Copy out the initial values for the parameters: CModelListPtr model_list = mWorkerThread->GetModelList(); model_list->GetFreeParameters(mParams, mNParams, false); vector<string> names = model_list->GetFreeParamNames(); vector< pair<double, double> > min_max = model_list->GetFreeParamMinMaxes(); // Init parameter values for(int i = 0; i < mNParams; i++) { lb[i] = min_max[i].first; ub[i] = min_max[i].second; // xopt = mParams[i]; } nlopt_set_lower_bounds(mOpt,lb); nlopt_set_upper_bounds(mOpt,ub); nlopt_set_ftol_rel(mOpt, 1e-4); // stopping criterion = when chi2 changes by less than 0.1% nlopt_set_min_objective(mOpt, error_func, (void*)this); int major=0, minor=0, bugfix=0; nlopt_version(&major, &minor, &bugfix); printf("Starting NLopt version %d.%d.%d\n", major, minor, bugfix); printf("Algorithm = %s \n", nlopt_algorithm_name(mAlgorithm)); if(mAlgorithm == NLOPT_G_MLSL_LDS) // set local optimizer to be used with a global search { printf("Secondary Algorithm = %s \n", nlopt_algorithm_name(mAlgorithmSecondary)); mOptSecondary = nlopt_create(mAlgorithmSecondary, mNParams); nlopt_set_lower_bounds(mOptSecondary,lb); nlopt_set_upper_bounds(mOptSecondary,ub); nlopt_set_ftol_rel(mOptSecondary, 1e-4); // stopping criterion = when chi2 changes by less than 0.1% nlopt_set_min_objective(mOptSecondary, error_func, (void*)this); nlopt_set_local_optimizer(mOpt, mOptSecondary); } mIsRunning = true; mEvals = 0; double minf; // Call NLopt. Note, the results are saved in mParams upon completion. nlopt_result result = nlopt_optimize(mOpt, mParams, &minf); mIsRunning = false; printresult(mParams, mNParams, n_data, names, minf, result); delete(lb); delete(ub); nlopt_destroy(mOpt); if(mAlgorithm == NLOPT_G_MLSL_LDS) // also destroy local optimizer { nlopt_destroy(mOptSecondary); } return mEvals; }
static int test_function(int ifunc) { 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)); 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; ret = nlopt_minimize(algorithm, func.n, bounds_wrap_func, &bw, lb, ub, x, &minf, minf_max, ftol_rel, ftol_abs, xtol_rel, xtabs, maxeval, maxtime); 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.\n", minf, testfuncs_counter); 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 (val != minf) { 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; }
void minim_nlopt(density_t *ndft){ nlopt_opt opt; double minf; int i, status; double *x; nlopt_function_data function_data; nlopt_par par; x = (double *)malloc(ipf.npar*sizeof(double)); for(i = 0; i < ipf.npar; i++) x[i] = gsl_vector_get(ipf.gamma, i); /* Here we choose the minimization method from NLOPT (check the avaible algorithms at http://ab-initio.mit.edu/wiki/index.php/NLopt_Algorithms) and specify the dimension of the problem */ par.algorithm = 1; parse_int("nlopt_algorithm", &par.algorithm); switch(par.algorithm){ case 1 : opt = nlopt_create(NLOPT_LN_BOBYQA, ipf.npar); if(myid == 0) printf("\n\n%s", nlopt_algorithm_name(NLOPT_LN_BOBYQA)); break; case 2 : opt = nlopt_create(NLOPT_GN_DIRECT, ipf.npar); if(myid == 0) printf("\n\n%s", nlopt_algorithm_name(NLOPT_GN_DIRECT)); break; case 3 : opt = nlopt_create(NLOPT_GD_STOGO, ipf.npar); if(myid == 0) printf("\n\n%s", nlopt_algorithm_name(NLOPT_GD_STOGO)); break; case 4: opt = nlopt_create(NLOPT_GN_ESCH, ipf.npar); if(myid == 0) printf("\n\n%s", nlopt_algorithm_name(NLOPT_GN_ESCH)); break; default : if(myid == 0) printf("\n\nWARNING: wrong choice for the NLOPT algorithm\nTHe optimization will start with the default algorithm:"); opt = nlopt_create(NLOPT_GN_DIRECT_L, ipf.npar); if(myid == 0) printf("\n%s", nlopt_algorithm_name(NLOPT_GN_DIRECT_L)); break; } nlopt_set_min_objective(opt, nlopt_gfunction, &function_data); par.rel_tol = 1e-4; parse_double("nlopt_rel_tol", &par.rel_tol); nlopt_set_xtol_rel(opt, par.rel_tol); /* Set the lower and upper bounds of the optimization to a single constant lb or ub respectively */ par.lb = -2.0; parse_double("nlopt_lb", &par.lb); par.ub = 2.0; parse_double("nlopt_ub", &par.ub); nlopt_set_lower_bounds1(opt, par.lb); nlopt_set_upper_bounds1(opt, par.ub); function_data.counter = 0; function_data.ndft = density_get_val(ndft); messages_basic("\n\n\nStarting the optimization.\n\n\n"); if ((status = nlopt_optimize(opt, x, &minf)) < 0){ if (myid == 0) printf("nlopt failed! status = %d\n", status); parallel_end(EXIT_FAILURE); } if(myid == 0) printf("Success. status = %d, iterations = %d, minf = %.12lg\n", status, function_data.counter, minf); if(myid == 0) {for(i = 0; i < ipf.npar; i++) printf("%.5f ", x[i]);} nlopt_destroy(opt); for(i = 0; i < ipf.npar; i++) gsl_vector_set(ipf.gamma, i, x[i]); ipf_write(ipf, ipf_ref, "pot"); parallel_end(EXIT_SUCCESS); }