Пример #1
0
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));
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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);
}