示例#1
0
// Cleanup allocations done during evolve.
void gsl_gradient::cleanup(gsl_vector *x, gsl_multimin_fdfminimizer *s)
{
	if (x) {
		gsl_vector_free(x);
	}
	if (s) {
		gsl_multimin_fdfminimizer_free(s);
	}
}
示例#2
0
GSLFDFSolver::~GSLFDFSolver()
{
  if(gslSolver_ != NULL)
  {
    free(gslSolver_->x->block);
    free(gslSolver_->gradient->block);
    gsl_multimin_fdfminimizer_free(gslSolver_);
  }
}
示例#3
0
void GSLFDFSolver::doSetup_(const Function &objFunc,
                            const vector< double > &x0,
                            const Solver::Setup &solverSetup,
                            const Constraints &C)
{
  const int n = objFunc.getN();
  double stepSize, tol;
  
  NativeGradientSolver::doSetup_(objFunc, x0, solverSetup, C);
  
  if(typeid(solverSetup) == typeid(Solver::DefaultSetup))
  {
    stepSize = 1.0;
    tol = 0.1;
  }
  else
  {
    stepSize = dynamic_cast< const GSLFDFSolver::Setup & >(solverSetup).stepSize;
    tol = dynamic_cast< const GSLFDFSolver::Setup & >(solverSetup).tol;
  }
  
  if(gslSolver_ != NULL)
  {
    free(gslSolver_->x->block);
    free(gslSolver_->gradient->block);
    gsl_multimin_fdfminimizer_free(gslSolver_);
  }
  gslSolver_ = gsl_multimin_fdfminimizer_alloc(type_, n);
  
  // THIS IS A HACK!
  free(gslSolver_->x->block->data);
  gslSolver_->x->data = gslSolver_->x->block->data = &state_.x[0];
  gslSolver_->x->owner = 0;
  gslSolver_->x->size = n;
  gslSolver_->x->stride = 1;
  free(gslSolver_->gradient->block->data);
  gslSolver_->gradient->data = gslSolver_->gradient->block->data = &state_.g[0];
  gslSolver_->gradient->owner = 0;
  gslSolver_->gradient->size = n;
  gslSolver_->gradient->stride = 1;
  // !!!!!!!!!!!!!!!
  
  gslFunction_.n      = n;
  gslFunction_.params = NULL;
  gslFunction_.f      = &gslutils::f;
  // by using a pointer-to-member it would be something like this:
  // (double (*)(const gsl_vector *, void *))(gslWrapper_.*(&GSLWrapper::f));
  gslFunction_.df     = &gslutils::df;
  gslFunction_.fdf    = &gslutils::fdf;
  
  gslutils::setFunction(setup_->f);
  gsl_vector *x0_ = gsl_vector_alloc(n);
  gslutils::BoostToGSLVector(x0, x0_);
  gsl_multimin_fdfminimizer_set(gslSolver_, &gslFunction_, x0_, stepSize, tol);
  gsl_vector_free(x0_);
}
示例#4
0
int
test_fdf(const char * desc, 
         gsl_multimin_function_fdf *f,
         initpt_function initpt,
         const gsl_multimin_fdfminimizer_type *T)
{
  int status;
  size_t iter = 0;
  double step_size;
  
  gsl_vector *x = gsl_vector_alloc (f->n);

  gsl_multimin_fdfminimizer *s;
  fcount = 0; gcount = 0;

  (*initpt) (x);

  step_size = 0.1 * gsl_blas_dnrm2 (x);

  s = gsl_multimin_fdfminimizer_alloc(T, f->n);

  gsl_multimin_fdfminimizer_set (s, f, x, step_size, 0.1);

#ifdef DEBUG
  printf("x "); gsl_vector_fprintf (stdout, s->x, "%g"); 
  printf("g "); gsl_vector_fprintf (stdout, s->gradient, "%g"); 
#endif

  do 
    {
      iter++;
      status = gsl_multimin_fdfminimizer_iterate(s);

#ifdef DEBUG
      printf("%i: \n",iter);
      printf("x "); gsl_vector_fprintf (stdout, s->x, "%g"); 
      printf("g "); gsl_vector_fprintf (stdout, s->gradient, "%g"); 
      printf("f(x) %g\n",s->f);
      printf("dx %g\n",gsl_blas_dnrm2(s->dx));
      printf("\n");
#endif

      status = gsl_multimin_test_gradient(s->gradient,1e-3);
    }
  while (iter < 5000 && status == GSL_CONTINUE);

  status |= (fabs(s->f) > 1e-5);

  gsl_test(status, "%s, on %s: %i iters (fn+g=%d+%d), f(x)=%g",
           gsl_multimin_fdfminimizer_name(s),desc, iter, fcount, gcount, s->f);

  gsl_multimin_fdfminimizer_free(s);
  gsl_vector_free(x);

  return status;
}
示例#5
0
文件: demo.c 项目: BrianGladman/gsl
int
main (void)
{
  size_t iter = 0;
  int status;

  const gsl_multimin_fdfminimizer_type *T;
  gsl_multimin_fdfminimizer *s;

  /* Position of the minimum (1,2). */
  double par[2] = { 1.0, 2.0 };

  gsl_vector *x;
  gsl_multimin_function_fdf my_func;

  my_func.f = &my_f;
  my_func.df = &my_df;
  my_func.fdf = &my_fdf;
  my_func.n = 2;
  my_func.params = &par;

  /* Starting point, x = (5,7) */

  x = gsl_vector_alloc (2);
  gsl_vector_set (x, 0, 5.0);
  gsl_vector_set (x, 1, 7.0);

  T = gsl_multimin_fdfminimizer_conjugate_fr;
  s = gsl_multimin_fdfminimizer_alloc (T, 2);

  gsl_multimin_fdfminimizer_set (s, &my_func, x, 0.01, 1e-4);

  do
    {
      iter++;
      status = gsl_multimin_fdfminimizer_iterate (s);

      if (status)
        break;

      status = gsl_multimin_test_gradient (s->gradient, 1e-3);

      if (status == GSL_SUCCESS)
        printf ("Minimum found at:\n");

      printf ("%5d %.5f %.5f %10.5f\n", iter,
              gsl_vector_get (s->x, 0), gsl_vector_get (s->x, 1), s->f);

    }
  while (status == GSL_CONTINUE && iter < 100);

  gsl_multimin_fdfminimizer_free (s);
  gsl_vector_free (x);

  return 0;
}
示例#6
0
void MStep (Dataset *data)
{
    double lastF;
    int iter, status;
    int numParams = data->num_labelers + data->num_beta;

    gsl_vector *x;
    gsl_multimin_fdfminimizer *s;
    const gsl_multimin_fdfminimizer_type *T;
    gsl_multimin_function_fdf obj_func;

    gsl_set_error_handler_off();

    // Pack parameters into a gsl_vector
    x = gsl_vector_alloc(numParams);
    packX(x, data);

    std::cerr << "Packed" << std::endl;

    // Initialize objective function
    obj_func.n = numParams;
    obj_func.f = &objective_function;
    obj_func.df = &get_gradients;
    obj_func.fdf = &set_functions;
    obj_func.params = data;
    // Initialize a minimizer
    T = gsl_multimin_fdfminimizer_conjugate_pr;
    s = gsl_multimin_fdfminimizer_alloc(T, numParams);

    gsl_multimin_fdfminimizer_set(s, &obj_func, x, 0.01, 0.01);
    iter = 0;

    std::cerr << "Start optimization" << std::endl;
    do {
        lastF = s->f;
        iter++;
        printf("[MStep:%d] f=%f\n", iter, s->f);

        status = gsl_multimin_fdfminimizer_iterate(s);
        if (status) {
            printf("Error occurred [MStep]\n");
            break;
        }
        status = gsl_multimin_test_gradient(s->gradient, 1e-2);
        if (status == GSL_SUCCESS) {
            printf ("Minimum found");
        }
    } while (lastF - s->f > 1e-5 && status == GSL_CONTINUE && iter < 25);

    /* Unpack alpha and beta from gsl_vector */
    unpackX(s->x, data);
  
    gsl_multimin_fdfminimizer_free(s);
    gsl_vector_free(x);
}
示例#7
0
double Fitting(FittinfPar *Par)
{
	size_t iter = 0;
	int status;
	const gsl_multimin_fdfminimizer_type *T;
	gsl_multimin_fdfminimizer *s;
	/* Starting point */
	//adding on 2011.8.27
	Par->Initial();
	//////////////////
	double a0=Error_std(Par)*0.6;
	double b0=a0*0.4;
	gsl_vector *v;
	v=gsl_vector_alloc(2);
	gsl_vector_set(v,0,a0);
	gsl_vector_set(v,1,b0);
	Par->a=a0;
	Par->b=b0;	

	gsl_multimin_function_fdf my_func;
	my_func.f = &IntR_Res_f;
	my_func.df = &IntR_Res_df;
	my_func.fdf = &IntR_Res_fdf;
	my_func.n = 2;
	my_func.params =(void *)Par;

	T = gsl_multimin_fdfminimizer_vector_bfgs;
	s = gsl_multimin_fdfminimizer_alloc(T,2);//3 是未知数个数
	gsl_multimin_fdfminimizer_set(s,&my_func,v,0.01,1e-5);
	do
	{
		iter++;
		status = gsl_multimin_fdfminimizer_iterate(s);
		if(status==GSL_ENOPROG)
		{	
			Par->a=gsl_vector_get(s->x,0);
			Par->b=gsl_vector_get(s->x,1);						
			break;
		}
		status = gsl_multimin_test_gradient(s->gradient,1e-6);
		if(status == GSL_SUCCESS)
		{
			Par->a=gsl_vector_get(s->x,0);
			Par->b=gsl_vector_get(s->x,1);							
		}
	}while(status==GSL_CONTINUE&&iter<100);
	//printf("Iter=%d\n",iter);
	double breturn=IntR_Res_f(s->x,(void *)Par);
	gsl_multimin_fdfminimizer_free(s);	
	gsl_vector_free(v);
	//cal the goodness of fitting
	return -breturn;	
}
示例#8
0
double GSLOptimizer::optimize(unsigned int iter,
                              const gsl_multimin_fdfminimizer_type*t,
                              double step, double param,
                              double min_gradient) {
  fis_= get_optimized_attributes();
  best_score_=std::numeric_limits<double>::max();
  unsigned int n= get_dimension();
  if (n ==0) {
    IMP_LOG(TERSE, "Nothing to optimize" << std::endl);
    return get_scoring_function()->evaluate(false);
  }
  gsl_multimin_fdfminimizer *s=gsl_multimin_fdfminimizer_alloc (t, n);

  gsl_vector *x= gsl_vector_alloc(get_dimension());

  gsl_multimin_function_fdf f= internal::create_function_data(this);

  update_state(x);
  gsl_multimin_fdfminimizer_set (s, &f, x, step, param);

  try {
    int status;
    do {
      --iter;
      //update_state(x);
      status = gsl_multimin_fdfminimizer_iterate(s);
      update_states();
      if (status) {
        IMP_LOG(TERSE, "Ending optimization because of status "
                << status << std::endl);
        break;
      }
      status = gsl_multimin_test_gradient (s->gradient, min_gradient);
      if (status == GSL_SUCCESS) {
        IMP_LOG(TERSE, "Ending optimization because of small gradient "
                << s->gradient << std::endl);
        break;
      }
    } while (status == GSL_CONTINUE && iter >0);
  } catch (AllDone){
  }
  gsl_vector *ret=gsl_multimin_fdfminimizer_x (s);
  write_state(ret);
  gsl_multimin_fdfminimizer_free (s);
  gsl_vector_free (x);
  return best_score_;
}
示例#9
0
文件: opt.c 项目: hsoleimani/MCCTM
void optimize_alpha(gsl_vector * x, void * data, int n, gsl_vector * x2){

	size_t iter = 0;
	int status, j;

	const gsl_multimin_fdfminimizer_type *T;
	gsl_multimin_fdfminimizer *s;

	gsl_multimin_function_fdf my_func;

	my_func.n = n;
	my_func.f = my_f;
	my_func.df = my_df;
	my_func.fdf = my_fdf;
	my_func.params = data;

	T = gsl_multimin_fdfminimizer_conjugate_fr;
	s = gsl_multimin_fdfminimizer_alloc (T, n);
	gsl_multimin_fdfminimizer_set (s, &my_func, x, 0.01, 1e-3);

	do{
		iter++;
		status = gsl_multimin_fdfminimizer_iterate (s);
		//printf ("status = %s\n", gsl_strerror (status));
		if (status){
			if (iter == 1){
				for (j = 0; j < n; j++){
					gsl_vector_set(x2, j, gsl_vector_get(x, j));
				}
			}
			break;
		}

		status = gsl_multimin_test_gradient (s->gradient, 1e-3);

		if ((isnan(s->f)) || (isinf(s->f)))
			break;
		for (j = 0; j < n; j++){
			gsl_vector_set(x2, j, gsl_vector_get(s->x, j));
		}

	}while (status == GSL_CONTINUE && iter < 100);

	gsl_multimin_fdfminimizer_free (s);

}
static void optimise_lambda_k(double *adLambdaK, struct data_t *data,
                              double *adZ)
{
    const int S = data->S;

    int i, status;
    size_t iter = 0;

    const gsl_multimin_fdfminimizer_type *T;
    gsl_multimin_fdfminimizer *s;
    gsl_multimin_function_fdf fdf;
    gsl_vector *ptLambda;

    /*initialise vector*/
    ptLambda = gsl_vector_alloc(S);
    for (i = 0; i < S; i++)
        gsl_vector_set(ptLambda, i, adLambdaK[i]);

    /*initialise function to be solved*/
    data->adPi = adZ;
    fdf.n = S;
    fdf.f = neg_log_evidence_lambda_pi;
    fdf.df = neg_log_derive_evidence_lambda_pi;
    fdf.fdf = neg_log_FDF_lamba_pi;
    fdf.params = data;

    T = gsl_multimin_fdfminimizer_vector_bfgs2;
    s = gsl_multimin_fdfminimizer_alloc(T, S);

    gsl_multimin_fdfminimizer_set(s, &fdf, ptLambda, 1.0e-6, 0.1);

    do {
        iter++;
        status = gsl_multimin_fdfminimizer_iterate(s);
        if (status)
            break;
        status = gsl_multimin_test_gradient(s->gradient, 1e-3);
   } while (status == GSL_CONTINUE && iter < MAX_GRAD_ITER);

    for (i = 0; i < S; i++)
        adLambdaK[i] = gsl_vector_get(s->x, i);

    gsl_vector_free(ptLambda);
    gsl_multimin_fdfminimizer_free(s);
}
void optimize_fdf(int dim,
                  gsl_vector* x,
                  void* params,
                  void (*fdf)(const gsl_vector*, void*, double*, gsl_vector*),
                  void (*df)(const gsl_vector*, void*, gsl_vector*),
                  double (*f)(const gsl_vector*, void*),
                  double* f_val,
                  double* conv_val,
                  int* niter) { 
	gsl_multimin_function_fdf obj;
	obj.f = f;
	obj.df = df;
	obj.fdf = fdf;
	obj.n = dim;
	obj.params = params;
	
//    const gsl_multimin_fdfminimizer_type * method =
//        gsl_multimin_fdfminimizer_vector_bfgs;
	const gsl_multimin_fdfminimizer_type * method =
		gsl_multimin_fdfminimizer_conjugate_fr;
	
	gsl_multimin_fdfminimizer * opt =
		gsl_multimin_fdfminimizer_alloc(method, dim);
	
	gsl_multimin_fdfminimizer_set(opt, &obj, x, 0.01, 1e-3);
	
	int iter = 0, status;
	double converged, f_old = 0;
	do {
		iter++;
		status = gsl_multimin_fdfminimizer_iterate(opt);
		// assert(status==0);
		converged = fabs((f_old - opt->f) / (dim * f_old));
		// status = gsl_multimin_test_gradient(opt->gradient, 1e-3);
		// printf("f = %1.15e; conv = %5.3e; norm = %5.3e; niter = %03d\n",
		// opt->f, converged, norm(opt->gradient), iter);
		f_old = opt->f;
	} while (converged > 1e-8 && iter < MAX_ITER);
	// while (status == GSL_CONTINUE);
	*f_val = opt->f;
	*conv_val = converged;
	*niter = iter;
	gsl_multimin_fdfminimizer_free(opt);
}
void multidim_minimization_steepest_descent()
{
	// Position of the minimum (1,2)
	double par[2] = { 1.0, 2.0 };

	gsl_multimin_function_fdf my_func;
	my_func.f = &local::my_f;
	my_func.df = &local::my_df;
	my_func.fdf = &local::my_fdf;
	my_func.n = 2;  // the dimension of the system, i.e. the number of components of the vectors x
	my_func.params = (void*)&par;

	// Starting point, x = (5,7)
	gsl_vector *x = gsl_vector_alloc(2);
	gsl_vector_set(x, 0, 5.0);
	gsl_vector_set(x, 1, 7.0);

	const gsl_multimin_fdfminimizer_type *T = gsl_multimin_fdfminimizer_steepest_descent;
	gsl_multimin_fdfminimizer *s = gsl_multimin_fdfminimizer_alloc(T, 2);
	gsl_multimin_fdfminimizer_set(s, &my_func, x, 0.01, 1e-4);

	size_t iter = 0;
	int status;
	do
	{
		++iter;
		status = gsl_multimin_fdfminimizer_iterate(s);
		if (status)
			break;
		status = gsl_multimin_test_gradient(s->gradient, 1e-7);
		if (status == GSL_SUCCESS)
			printf("Minimum found at:\n");
		printf("%5d %.5f %.5f %10.5f\n", iter,
			gsl_vector_get(s->x, 0),
			gsl_vector_get(s->x, 1),
			s->f);
	} while (status == GSL_CONTINUE && iter < 1000);

	//
	gsl_multimin_fdfminimizer_free(s);
	gsl_vector_free(x);
}
示例#13
0
/*
  internal function used by get_theta_matrix(). Minimizes
  the function func(): 
  e0*cos(th0) + e1*cos(th1) + e2*cos(th0+th1+phi) for th0, th1
*/
void
minimize_for_thetas(gsl_vector *th, struct func_params *f_params)
{
  const int niter = 10000;
  const double eps = 1.e-5;
  const gsl_multimin_fdfminimizer_type *minimizer_type;
  gsl_multimin_fdfminimizer *minimizer;
  int status;
  size_t iter = 0;
  const size_t n = 2;
  gsl_multimin_function_fdf fdf = 
    {
      &func,
      &dfunc,
      &funcdfunc,
      n,
      (void *)f_params
    };
  minimizer_type = gsl_multimin_fdfminimizer_conjugate_fr;
  minimizer = gsl_multimin_fdfminimizer_alloc (minimizer_type, 2);
  gsl_multimin_fdfminimizer_set (minimizer, &fdf, th, 0.1, eps);
  do{
    iter++;
    status = gsl_multimin_fdfminimizer_iterate (minimizer);
    if(status)
      break;
    status = gsl_multimin_test_gradient (minimizer->gradient, eps);
  }while(status == GSL_CONTINUE && iter < niter);

  if(status == GSL_CONTINUE){
    fprintf(stderr," failed to find minimum in %s(), quitting\n", __func__);
    exit(-3);
  }

  gsl_vector_set (th, 0, gsl_vector_get (minimizer->x, 0));
  gsl_vector_set (th, 1, gsl_vector_get (minimizer->x, 1));

  gsl_multimin_fdfminimizer_free (minimizer);
  return;
}
示例#14
0
    ~RatesEM()
    {
	//gsl_root_fdfsolver_free(sol_gene_rate);
	gsl_root_fsolver_free(sol_gene_rate);
        gsl_multimin_fdfminimizer_free(sol_sp_rate);
    }
示例#15
0
文件: example.c 项目: nquesada/gupta
int
main (int argc, char *argv[])
{
  int i;
  int outp;
  int n = atoi (argv[1]);
  double x, y, z;
  gsl_vector *r = gsl_vector_alloc (3 * n);
  gsl_vector *dr = gsl_vector_alloc (3 * n);
  double uu = 0;
  double est;
  double tmp1, tmp2;
  FILE *in, *out;

  //Reading input
  in = fopen (argv[2], "r");
  if (in != NULL)
    {
      out = fopen (argv[3], "w");
      for (i = 0; i < n; i++)
	{
	  outp = fscanf (in, "%lf %lf %lf", &x, &y, &z);
	  gsl_vector_set (r, 3 * i, x);
	  gsl_vector_set (r, 3 * i + 1, y);
	  gsl_vector_set (r, 3 * i + 2, z);
	}
      fclose (in);

      //Initial energies and forces before optimization
      gupta_fdf (r, &n, &uu, dr);
      tmp1 = tmp2 = 0.0;
      for (i = 0; i < 3 * n; i++)
	{
	  tmp1 = gsl_vector_get (dr, i);
	  tmp2 += tmp1 * tmp1;
	}
      tmp2 = sqrt (tmp2);
      fprintf (stdout,
	       "\n \nInitial Energy in file %s was E=%lf and the value of the norm of the gradient was |df|=%lf\n ",
	       argv[2], uu, tmp2);



      //Setting the optimizer
      size_t iter = 0;
      int status;
      const gsl_multimin_fdfminimizer_type *T;
      gsl_multimin_fdfminimizer *s;
      gsl_multimin_function_fdf my_func;

      my_func.n = 3 * n;
      my_func.f = gupta_f;
      my_func.df = gupta_df;
      my_func.fdf = gupta_fdf;
      my_func.params = &n;

      T = gsl_multimin_fdfminimizer_vector_bfgs2;
      s = gsl_multimin_fdfminimizer_alloc (T, 3 * n);
      gsl_multimin_fdfminimizer_set (s, &my_func, r, 0.01, 1e-4);

      //The actual optimization
      do
	{
	  iter++;
	  status = gsl_multimin_fdfminimizer_iterate (s);
	  if (status)
	    break;
	  status = gsl_multimin_test_gradient (s->gradient, 1e-6);
	}
      while (status == GSL_CONTINUE && iter < 10000);


      est = gsl_multimin_fdfminimizer_minimum (s);
      gsl_vector_memcpy (r, gsl_multimin_fdfminimizer_x (s));

      //The values of the energies and forces after the optimization

      gupta_fdf (r, &n, &uu, dr);
      tmp1 = tmp2 = 0.0;
      for (i = 0; i < 3 * n; i++)
	{
	  tmp1 = gsl_vector_get (dr, i);
	  tmp2 += tmp1 * tmp1;
	}
      tmp2 = sqrt (tmp2);


      fprintf (stdout,
	       "\n \nFinal Energy in file %s was E=%lf and the value of the norm of the gradient was |df|=%lf\n ",
	       argv[3], uu, tmp2);


      for (i = 0; i < n; i++)
	{
	  fprintf (out, "%.16e %.16e %.16e\n", gsl_vector_get (r, 3 * i),
		   gsl_vector_get (r, 3 * i + 1), gsl_vector_get (r,
								  3 * i + 2));
	}
      gsl_multimin_fdfminimizer_free (s);
      gsl_vector_free (r);
    }
  else
    {
      fprintf (stdout, "The file %s was not found\n", argv[2]);
    }
  return 0;
}
示例#16
0
文件: RNApbfold.c 项目: wash/probing
int main(int argc, char *argv[]) {

    struct        RNAfold_args_info args_info;
    char          *string, *input_string, *structure=NULL, *cstruc=NULL;
    char          fname[80], ffname[80], gfname[80], *ParamFile=NULL;
    char          *ns_bases=NULL, *c;
    int           i, j, ii, jj, mu, length, l, sym, r, pf=0, noconv=0;
    unsigned int  input_type;
    double        energy, min_en, kT, sfact=1.07;
    int           doMEA=0, circular = 0, N;
    char *pf_struc;
    double dist;
    plist *pl;

    FILE * filehandle;
    FILE * statsfile;
    char* line;

    double tau   = 0.01; /* Variance of energy parameters */
    double sigma = 0.01; /* Variance of experimental constraints */
    double *gradient;           /* Gradient for steepest descent search
                                 epsilon[i+1]= epsilon[i] - gradient *
                                 step_size */
    double initial_step_size = 0.5;  /* Initial step size for steepest
                                      descent search */
    double step_size;
    double D;                  /* Discrepancy (i.e. value of objective
                                function) for the current
                                prediction */
    int iteration, max_iteration = 2000; /* Current and maximum number of
                                         iterations after which
                                         algorithm stops */

    double precision = 0.1; /* cutoff used for stop conditions */
    double tolerance = 0.1;   /* Parameter used by various GSL minimizers */
    int method_id = 1;        /* Method to use for minimization, 0 and 1
                               are custom steepest descent, the rest
                               are GSL implementations (see below)*/

    int initial_guess_method = 0;

    int sample_N = 1000;

    double *prev_epsilon;
    double *prev_gradient;
    double DD, prev_D, sum, norm;
    int status;
    double* gradient_numeric;
    double* gradient_numeric_gsl;

    /* Minimizer vars */
    const gsl_multimin_fdfminimizer_type *T;
    gsl_multimin_fdfminimizer *minimizer;
    gsl_vector *minimizer_x;
    gsl_vector *minimizer_g;
    gsl_multimin_function_fdf minimizer_func;
    minimizer_pars_struct minimizer_pars;

    char *constraints;
    char outfile[256];
    char constraints_file[256];
    char epsilon_file[256];
    FILE* fh;

    double last_non_nan_lnQ;

    pf_overflow = 0;
    pf_underflow = 0;

    dangles=2;

    do_backtrack  = 1;
    string        = NULL;

    noPS = 0;
    outfile[0]='\0';
    epsilon_file[0]='\0';
    strcpy(psDir, "dotplots");

    if(RNAfold_cmdline_parser (argc, argv, &args_info) != 0) exit(1);

    /* RNAbpfold specific options */

    if (args_info.tau_given) tau = args_info.tau_arg;
    if (args_info.sigma_given) sigma = args_info.sigma_arg;
    if (args_info.precision_given) precision = args_info.precision_arg;
    if (args_info.step_given) initial_step_size = args_info.step_arg;
    if (args_info.maxN_given) max_iteration = args_info.maxN_arg;
    if (args_info.minimization_given) method_id = args_info.minimization_arg;
    if (args_info.init_given) initial_guess_method = args_info.init_arg;
    if (args_info.tolerance_given) tolerance = args_info.tolerance_arg;
    if (args_info.outfile_given) strcpy(outfile, args_info.outfile_arg);
    if (args_info.constraints_given) strcpy(constraints_file, args_info.constraints_arg);
    if (args_info.epsilon_given) strcpy(epsilon_file, args_info.epsilon_arg);
    if (args_info.sampleGradient_given) sample_conditionals=1;
    if (args_info.hybridGradient_given) {
        sample_conditionals=1;
        hybrid_conditionals=1;
    }
    if (args_info.numericalGradient_given) numerical=1;
    if (args_info.sampleStructure_given) sample_structure=1;
    if (args_info.psDir_given) strcpy(psDir, args_info.psDir_arg);
    if (args_info.sparsePS_given) sparsePS=args_info.sparsePS_arg;
    if (args_info.gridSearch_given) grid_search = 1;


    /* Generic RNAfold options */

    if (args_info.temp_given)        temperature = args_info.temp_arg;
    if (args_info.reference_given)  fold_constrained=1;
    if (args_info.noTetra_given)     tetra_loop=0;
    if (args_info.dangles_given)     dangles = args_info.dangles_arg;
    if (args_info.noLP_given)        noLonelyPairs = 1;
    if (args_info.noGU_given)        noGU = 1;
    if (args_info.noClosingGU_given) no_closingGU = 1;
    if (args_info.noconv_given)      noconv = 1;
    if (args_info.energyModel_given) energy_set = args_info.energyModel_arg;
    if (args_info.paramFile_given)   ParamFile = strdup(args_info.paramFile_arg);
    if (args_info.nsp_given)         ns_bases = strdup(args_info.nsp_arg);
    if (args_info.pfScale_given)     sfact = args_info.pfScale_arg;
    if (args_info.noPS_given)        noPS=1;



    /* Create postscript directory */
    if (!noPS) {
        struct stat stat_p;
        if (stat (psDir, &stat_p) != 0) {
            if (mkdir(psDir, S_IRWXU|S_IROTH|S_IRGRP ) !=0) {
                fprintf(stderr, "WARNING: Could not create directory: %s", psDir);
            }
        }
    }

    if (ParamFile != NULL) {
        read_parameter_file(ParamFile);
    }

    if (ns_bases != NULL) {
        nonstandards = space(33);
        c=ns_bases;
        i=sym=0;
        if (*c=='-') {
            sym=1;
            c++;
        }
        while (*c!='\0') {
            if (*c!=',') {
                nonstandards[i++]=*c++;
                nonstandards[i++]=*c;
                if ((sym)&&(*c!=*(c-1))) {
                    nonstandards[i++]=*c;
                    nonstandards[i++]=*(c-1);
                }
            }
            c++;
        }
    }

    /*Read sequence*/
    fname[0] = '\0';
    while((input_type = get_input_line(&input_string, 0)) & VRNA_INPUT_FASTA_HEADER) {
        (void) sscanf(input_string, "%42s", fname);
        free(input_string);
    }

    length = (int)    strlen(input_string);
    string = strdup(input_string);
    free(input_string);
    structure = (char *) space((unsigned) length+1);

    /* For testing purpose pass dot bracket structure of reference structure via -C */
    if (fold_constrained) {
        input_type = get_input_line(&input_string, VRNA_INPUT_NOSKIP_COMMENTS);
        if(input_type & VRNA_INPUT_QUIT) {
            exit(1);
        }
        else if((input_type & VRNA_INPUT_MISC) && (strlen(input_string) > 0)) {
            cstruc = strdup(input_string);
            free(input_string);
        }
        else warn_user("-C was given but reference structure is missing");
    }

    if(noconv) {
        str_RNA2RNA(string);
    } else {
        str_DNA2RNA(string);
    }

    /* Allocating space */

    epsilon =     (double *) space(sizeof(double)*(length+1));

    exp_pert =  (double **)space(sizeof(double *)*(length+1));
    perturbations =  (double **)space(sizeof(double *)*(length+1));
    prev_epsilon = (double *) space(sizeof(double)*(length+1));
    gradient =    (double *) space(sizeof(double)*(length+1));
    gradient_numeric =    (double *) space(sizeof(double)*(length+1));
    gradient_numeric_gsl =    (double *) space(sizeof(double)*(length+1));
    prev_gradient = (double *) space(sizeof(double)*(length+1));

    q_unpaired = (double *) space(sizeof(double)*(length+1));
    p_unpaired_cond = (double **)space(sizeof(double *)*(length+1));
    p_unpaired_cond_sampled = (double **)space(sizeof(double *)*(length+1));
    p_pp =  (double **)space(sizeof(double *)*(length+1));
    p_unpaired =  (double *) space(sizeof(double)*(length+1));
    p_unpaired_tmp = (double *) space(sizeof(double)*(length+1));

    for (i=0; i <= length; i++) {
        epsilon[i] = gradient[i] = q_unpaired[i] = 0.0;
        p_unpaired_cond[i] = (double *) space(sizeof(double)*(length+1));
        p_unpaired_cond_sampled[i] = (double *) space(sizeof(double)*(length+1));
        p_pp[i] = (double *) space(sizeof(double)*(length+1));
        exp_pert[i] = (double *) space(sizeof(double)*(length+1));
        perturbations[i] = (double *) space(sizeof(double)*(length+1));
        for (j=0; j <= length; j++) {
            p_pp[i][j]=p_unpaired_cond[i][j] = 0.0;
            p_unpaired_cond_sampled[i][j] = 0.0;
        }
    }


    /*** If file with perturbation vector epsilon is given we fold using
         this epsilon and are done ***/

    if (args_info.epsilon_given) {
        plist *pl, *pl1,*pl2;

        filehandle = fopen (epsilon_file,"r");

        if (filehandle == NULL) {
            nrerror("Could not open file with perturbation vector.");
        }

        i=1;
        while (1) {
            double t;
            line = get_line(filehandle);
            if (line == NULL) break;
            if (i>length) nrerror("Too many values in perturbation vector file.");
            if (sscanf(line, "%lf", &epsilon[i]) !=1) {
                nrerror("Error while reading perturbation vector file.");
            }
            i++;
        }

        if (i-1 != length) {
            nrerror("Too few values in perturbation vector file.");
        }

        init_pf_fold(length);
        pf_fold_pb(string, NULL);

        sprintf(fname,"%s/dot.ps", psDir);
        pl1 = make_plist(length, 1e-5);

        (void) PS_dot_plot_list_epsilon(string, fname, NULL, pl1, epsilon, "");

        exit(0);
    }



    /*** Get constraints from reference structure or from external file ***/

    /* Structure was given by -C */
    if (fold_constrained) {
        for (i=0; i<length; i++) {
            if (cstruc[i] == '(' || cstruc[i] == ')') {
                q_unpaired[i+1] = 0.0;
            } else {
                q_unpaired[i+1] = 1.0;
            }
        }

        /*Read constraints from file*/
    } else {

        filehandle = fopen (constraints_file,"r");

        if (filehandle == NULL) {
            nrerror("No constraints given as dot bracket or wrong file name");
        }

        i=1;
        while (1) {
            double t;
            line = get_line(filehandle);
            if (line == NULL) break;
            if (i>length) nrerror("Too many values in constraints.dat");
            if (sscanf(line, "%lf", &q_unpaired[i]) !=1) {
                nrerror("Error while reading constraints.dat");
            }
            i++;
        }

        if (i-1 != length) {
            nrerror("Too few values in constraints.dat");
        }
    }

    /* Create file handle */
    if (outfile[0] !='\0') {
        statsfile = fopen (outfile,"w");
    } else {
        statsfile = fopen ("stats.dat","w");
    }

    setvbuf(statsfile, NULL, _IONBF, 0);

    if (!grid_search) {
        fprintf(statsfile, "Iteration\tDiscrepancy\tNorm\tdfCount\tMEA\tSampled_structure\tSampled_energy\tSampled_distance\tEpsilon\ttimestamp\n");
    } else {
        /* If we do a grid search we have a different output. */
        fprintf(statsfile, "Dummy\tm\tb\tdummy\tMEA\tepsilon\n");
    }

    if (statsfile == NULL) {
        nrerror("Could not open stats.dat for writing.");
    }

    fprintf(stderr, "tau^2 = %.4f; sigma^2 = %.4f; precision = %.4f; tolerance = %.4f; step-size: %.4f\n\n",
            tau, sigma, precision, tolerance, initial_step_size);

    st_back=1;
    min_en = fold(string, structure);

    (void) fflush(stdout);

    if (length>2000) free_arrays();

    pf_struc = (char *) space((unsigned) length+1);

    kT = (temperature+273.15)*1.98717/1000.; /* in Kcal */
    pf_scale = exp(-(sfact*min_en)/kT/length);

    /* Set up minimizer */

    minimizer_x = gsl_vector_alloc (length+1);
    minimizer_g = gsl_vector_alloc (length+1);

    for (i=0; i <= length; i++) {
        epsilon[i] = 0.0;
        gsl_vector_set (minimizer_g, i, 0.0);
        gsl_vector_set (minimizer_x, i, epsilon[i]);
    }

    minimizer_pars.length=length;
    minimizer_pars.seq = string;
    minimizer_pars.tau=tau;
    minimizer_pars.sigma=sigma;
    minimizer_pars.kT=kT;

    minimizer_func.n = length+1;
    minimizer_func.f = calculate_f;
    minimizer_func.df = numerical ? calculate_df_numerically: calculate_df;
    minimizer_func.fdf = calculate_fdf;
    minimizer_func.params = &minimizer_pars;


    //min_en = fold_pb(string, structure);
    //fprintf(stderr, "%f", min_en);
    //exit(0);

    /* Calling test functions for debugging */
    for (i=1; i <= length; i++) {
        if (i%2==0) {
            epsilon[i] = +0.2*i;
        } else {
            epsilon[i] = -0.2*i;
        }
    }

    //test_folding(string, length);
    /* //test_stochastic_backtracking(string, length); */
    /* //test_gradient(minimizer_func, minimizer_pars); */
    /* //test_gradient_sampling(minimizer_func, minimizer_pars); */
    //exit(1);


    count_df_evaluations=0;

    /* Initial guess for epsilon */

    if (initial_guess_method !=0 && initial_guess_method !=3) {

        /* Vars for inital guess methods */
        double m,b;
        double* curr_epsilon;
        double* best_epsilon;
        double best_m, best_b, best_scale;
        double curr_D;
        double min_D = 999999999.0;
        double inc = +0.25;
        double cut;

        if (initial_guess_method == 1) fprintf(stderr, "Mathew's constant perturbations\n");
        if (initial_guess_method == 2) fprintf(stderr, "Perturbations proportional to q-p\n");

        curr_epsilon = (double *) space(sizeof(double)*(length+1));
        best_epsilon = (double *) space(sizeof(double)*(length+1));

        last_non_nan_lnQ = min_en;

        // Calculate p_unpaired for unperturbed state which we need later
        // for the proportinal method
        if (initial_guess_method == 2) {

            init_pf_fold(length);

            for (i=0; i <= length; i++) {
                epsilon[i] = 0.0;
            }

            pf_fold_pb(string, NULL);
            for (i = 1; i < length; i++) {
                for (j = i+1; j<= length; j++) {
                    p_pp[i][j]=p_pp[j][i]=pr[iindx[i]-j];
                }
            }
            get_pair_prob_vector(p_pp, p_unpaired_tmp, length, 1);
            free_pf_arrays();
        }

        /* We do the same grid search as in the Mathews paper Fig. 4*/
        for (m=0.25; m <=7.0; m+=0.25) {

            // Weird way of writing this inner loop for the grid search. We
            // traverse the grid without big jumps in the parameters to make
            // sure that the updated scaling factor is accurate all the time.
            inc*=-1;

            for (b = inc < 0.0 ? 0.0 : -3.0; inc < 0.0 ? b >= -3.0 : b<= 0.0 ; b+=inc) {

                // calculate cut point with x-axis and skip parameter pairs
                // which give a cut point outside the range of
                // q_unpaired (0 to 1). They gave frequently overflows and the
                // idea is that we both want positive and negative perturbations
                cut = exp( (-1) * b / m ) - 1;

                fprintf(stderr, "\nm = %.2f, b = %.2f, cut=%.2f\n", m, b, cut);

                if (cut > 1.0 || cut < 0.01) {
                    fprintf(stderr, "\nSkipping m = %.2f, b = %.2f\n", m, b);
                    continue;
                }

                /* Mathew's constant perturbations */
                if (initial_guess_method == 1) {
                    for (i=0; i <= length; i++) {

                        /* We add epsilon to unpaired regions (as opposed to
                           paired regions as in the Mathews paper) so we multiply
                           by -1; if missing data we set it to 0.0 */

                        if (q_unpaired[i] < -0.5) {
                            curr_epsilon[i] = 0.0;
                        } else {
                            curr_epsilon[i] = (m *(log(q_unpaired[i]+1))+b) *(-1);
                        }

                        gsl_vector_set (minimizer_x, i, curr_epsilon[i]);
                    }
                    /* Perturbations proportional to q-p */
                } else {

                    for (i=0; i <= length; i++) {
                        curr_epsilon[i] = (m *(log(q_unpaired[i]+1)-log(p_unpaired_tmp[i]+1))+ b ) * (-1);
                        gsl_vector_set (minimizer_x, i, curr_epsilon[i]);
                    }
                }

                // Repeat and adjust scaling factor until we get result without over-/underflows
                do {

                    // First we use default scaling factor
                    if (pf_underflow == 0 && pf_overflow == 0) {
                        sfact = 1.070;
                    }

                    if (pf_underflow) {
                        sfact *= 0.8;
                        fprintf(stderr,"Underflow, adjusting sfact to %.4f\n", sfact );
                    }

                    if (pf_overflow) {
                        sfact *= 1.2;
                        fprintf(stderr,"Overflow, adjusting sfact to %.4f\n", sfact );
                    }

                    pf_scale = exp(-(sfact*last_non_nan_lnQ)/kT/length);

                    //fprintf(stderr,"Scaling factor is now: %.4e\n", pf_scale);

                    curr_D = calculate_f(minimizer_x, (void*)&minimizer_pars);

                    if (!isnan(last_lnQ)) last_non_nan_lnQ = last_lnQ;

                    // Give up when even extreme scaling does not give results
                    // (for some reason I could not get rid of overflows even with high scaling factors)
                    if (sfact < 0.1 || sfact > 2.0) break;

                } while (pf_underflow == 1 || pf_overflow == 1);

                // We have not given up so everything is ok now
                if (!(sfact < 0.1 || sfact > 2.0)) {

                    if (curr_D < min_D) {
                        min_D = curr_D;
                        for (i=0; i <= length; i++) {
                            best_epsilon[i] = curr_epsilon[i];
                        }
                        best_m = m;
                        best_b = b;
                        best_scale = pf_scale;
                    }

                    /*If we are interested in the grid search we misuse the
                      print_stats function and report m and b together with MEA*/
                    if (grid_search) {
                        for (i=0; i <= length; i++) {
                            epsilon[i] = curr_epsilon[i];
                        }
                        print_stats(statsfile, string, cstruc, length, 0, 0, m, 0.0, b, 0);
                    }

                    fprintf(stderr, "curr D: %.2f, minimum D: %.2f\n", curr_D, min_D);

                    // Adjust pf_scale with default scaling factor but lnQ from
                    // previous step
                    sfact = 1.070;
                    pf_scale = exp(-(sfact*last_lnQ)/kT/length);

                } else {
                    sfact = 1.070;
                    fprintf(stderr, "Skipping m = %.2f, b = %.2f; did not get stable result.\n", m, b);
                }
            } // for b
        } // for m

        fprintf(stderr, "Minimum found: m=%.2f, b=%.2f: %.2f\n", best_m, best_b, min_D);

        for (i=0; i <= length; i++) {
            epsilon[i] = best_epsilon[i];
            gsl_vector_set (minimizer_x, i, best_epsilon[i]);
        }
        pf_scale = best_scale;
    }

    if (initial_guess_method == 3) {
        srand((unsigned)time(0));
        for (i=0; i <= length; i++) {
            double r = (double)rand()/(double)RAND_MAX * 4 - 2;
            epsilon[i] = r;
            gsl_vector_set (minimizer_x, i, epsilon[i]);
        }
    }

    /* If we just wanted a grid search we are done now. */
    if (grid_search) {
        exit(0);
    }

    prev_D = calculate_f(minimizer_x, (void*)&minimizer_pars);

    print_stats(statsfile, string, cstruc, length, 0 , count_df_evaluations , prev_D, -1.0, 0.0,1);

    /* GSL minimization */

    if (method_id !=0) {

        if (method_id > 2) {
            char name[100];
            // Available algorithms
            //  3  gsl_multimin_fdfminimizer_conjugate_fr
            //  4  gsl_multimin_fdfminimizer_conjugate_pr
            //  5  gsl_multimin_fdfminimizer_vector_bfgs
            //  6  gsl_multimin_fdfminimizer_vector_bfgs2
            //  7  gsl_multimin_fdfminimizer_steepest_descent

            //   http://www.gnu.org/software/gsl/manual/html_node/Multimin-Algorithms-with-Derivatives.html

            switch (method_id) {
            case 2:
                minimizer = gsl_multimin_fdfminimizer_alloc (gsl_multimin_fdfminimizer_conjugate_fr, length+1);
                strcpy(name, "Fletcher-Reeves conjugate gradient");
                break;
            case 3:
                minimizer = gsl_multimin_fdfminimizer_alloc (gsl_multimin_fdfminimizer_conjugate_pr, length+1);
                strcpy(name, "Polak-Ribiere conjugate gradient");
                break;
            case 4:
                minimizer = gsl_multimin_fdfminimizer_alloc ( gsl_multimin_fdfminimizer_vector_bfgs, length+1);
                strcpy(name, "Broyden-Fletcher-Goldfarb-Shanno");
                break;
            case 5:
                minimizer = gsl_multimin_fdfminimizer_alloc ( gsl_multimin_fdfminimizer_vector_bfgs2, length+1);
                strcpy(name, "Broyden-Fletcher-Goldfarb-Shanno (improved version)");
                break;
            case 6:
                minimizer = gsl_multimin_fdfminimizer_alloc (gsl_multimin_fdfminimizer_steepest_descent, length+1);
                strcpy(name, "Gradient descent (GSL implmementation)");
                break;
            }

            fprintf(stderr, "Starting minimization via GSL implementation of %s...\n\n", name);

            // The last two parmeters are step size and tolerance (with
            // different meaning for different algorithms

            gsl_multimin_fdfminimizer_set (minimizer, &minimizer_func, minimizer_x, initial_step_size, tolerance);

            iteration = 1;

            do {

                status = gsl_multimin_fdfminimizer_iterate (minimizer);
                D = minimizer->f;
                norm = gsl_blas_dnrm2(minimizer->gradient);

                print_stats(statsfile, string, cstruc, length,iteration, count_df_evaluations, D, prev_D, norm, iteration%sparsePS == 0);

                prev_D = D;

                if (status) {
                    fprintf(stderr, "An unexpected error has occured in the iteration (status:%i)\n", status);
                    break;
                }

                status = gsl_multimin_test_gradient (minimizer->gradient, precision);
                if (status == GSL_SUCCESS) fprintf(stderr, "Minimum found stopping.\n");

                iteration++;

            } while (status == GSL_CONTINUE && iteration < max_iteration);

            gsl_multimin_fdfminimizer_free (minimizer);
            gsl_vector_free (minimizer_x);

            /* Custom implementation of steepest descent */
        } else {

            if (method_id == 1) {
                fprintf(stderr, "Starting custom implemented steepest descent search...\n\n");
            } else {
                fprintf(stderr, "Starting custom implemented steepest descent search with Barzilai Borwein step size...\n\n");
            }

            iteration = 0;
            D = 0.0;

            while (iteration++ < max_iteration) {

                for (i=1; i <= length; i++) {
                    gsl_vector_set (minimizer_x, i, epsilon[i]);
                }

                D = calculate_f(minimizer_x, (void*)&minimizer_pars);

                if (numerical) {
                    calculate_df_numerically(minimizer_x, (void*)&minimizer_pars, minimizer_g);
                } else {
                    calculate_df(minimizer_x, (void*)&minimizer_pars, minimizer_g);
                }

                for (i=1; i <= length; i++) {
                    gradient[i] = gsl_vector_get (minimizer_g, i);
                }

                // Do line search

                fprintf(stderr, "\nLine search:\n");

                // After the first iteration, use Barzilai-Borwain (1988) step size (currently turned off)
                if (iteration>1 && method_id==2) {

                    double denominator=0.0;
                    double numerator=0.0;

                    for (i=1; i <= length; i++) {
                        numerator += (epsilon[i]-prev_epsilon[i]) * (gradient[i]-prev_gradient[i]);
                        denominator+=(gradient[i]-prev_gradient[i]) * (gradient[i]-prev_gradient[i]);
                    }

                    step_size = numerator / denominator;

                    norm =1.0;
                } else {
                    // Use step sized given by the user (normalize it first)
                    step_size = initial_step_size / calculate_norm(gradient, length);
                }

                for (i=1; i <= length; i++) {
                    prev_epsilon[i] = epsilon[i];
                    prev_gradient[i] = gradient[i];
                }

                do {

                    for (mu=1; mu <= length; mu++) {
                        epsilon[mu] = prev_epsilon[mu] - step_size * gradient[mu];
                    }

                    for (i=1; i <= length; i++) {
                        gsl_vector_set (minimizer_x, i, epsilon[i]);
                    }

                    DD = calculate_f(minimizer_x, (void*)&minimizer_pars);

                    if (step_size > 0.0001) {
                        fprintf(stderr, "Old D: %.4f; New D: %.4f; Step size: %.4f\n", D, DD, step_size);
                    } else {
                        fprintf(stderr, "Old D: %.4f; New D: %.4f; Step size: %.4e\n", D, DD, step_size);
                    }

                    step_size /= 2;
                } while (step_size > 1e-12 && DD > D);

                norm = calculate_norm(gradient,length);

                if (DD > D) {
                    fprintf(stderr, "Line search did not improve D in iteration %i. Stop.\n", iteration);

                    if (hybrid_conditionals) {
                        sample_conditionals=0;
                    } else {
                        break;
                    }
                }

                print_stats(statsfile, string, cstruc, length,iteration, count_df_evaluations, DD, prev_D, norm, iteration%sparsePS == 0);

                if (norm<precision && iteration>1) {
                    fprintf(stderr, "Minimum found stopping.\n");
                    break;
                }

                prev_D = DD;

            }
        }

        /* Force last dotplot to be printed */
        print_stats(statsfile, string, cstruc, length,iteration, count_df_evaluations, DD, prev_D, norm, 1);
    }

    free(pf_struc);
    if (cstruc!=NULL) free(cstruc);
    (void) fflush(stdout);
    free(string);
    free(structure);
    RNAfold_cmdline_parser_free (&args_info);


    return 0;
}
示例#17
0
void
multimin(size_t n,double *x,double *fun,
	 const unsigned *type, const double *xmin,const double *xmax,
	 void (*f) (const size_t,const double *,void *,double *),
	 void (* df) (const size_t,const double *, void *,double *),
	 void (* fdf) (const size_t,const double *, void *,double *,double *),
	 void *fparams,
	 const struct multimin_params oparams)
{
  unsigned iter=0;
  int status;

  size_t i;
  double dtmp1;

  const gsl_multimin_fdfminimizer_type *Tfdf;
  const gsl_multimin_fminimizer_type *Tf;
  const char *Tname;
  
  gsl_vector * y  = gsl_vector_alloc (n);

  /* set the algorithm */
  switch(oparams.method){
  case 0:/* Fletcher-Reeves conjugate gradient */
    Tfdf = gsl_multimin_fdfminimizer_conjugate_fr;
    Tname = Tfdf->name;
    break;
  case 1:/* Polak-Ribiere conjugate gradient */
    Tfdf = gsl_multimin_fdfminimizer_conjugate_pr;
    Tname = Tfdf->name;
    break;
  case 2:/* Vector Broyden-Fletcher-Goldfarb-Shanno method */
    Tfdf = gsl_multimin_fdfminimizer_vector_bfgs;
    Tname = Tfdf->name;
    break;
  case 3:/* Steepest descent algorithm */
    Tfdf =gsl_multimin_fdfminimizer_steepest_descent;
    Tname = Tfdf->name;
    break;
  case 4:/* Simplex */
    Tf = gsl_multimin_fminimizer_nmsimplex2;
    Tname = Tf->name;
    break;
  case 5:/*  Vector Broyden-Fletcher-Goldfarb-Shanno2 method */
    Tfdf = gsl_multimin_fdfminimizer_vector_bfgs2;
    Tname = Tfdf->name;
   break;

  default:
    fprintf(stderr,"Optimization method not recognized. Try -h\n");
    exit(EXIT_FAILURE);
  }

  /* --- OUPUT ---------------------------------- */
  if(oparams.verbosity>0){
    fprintf(stderr,"#--- MULTIMIN START\n");
    fprintf(stderr,"#    method                         %s\n",Tname);
    if(oparams.method<4 || oparams.method==5){
    fprintf(stderr,"#    initial step size              %g\n", oparams.step_size);
    fprintf(stderr,"#    line minimization tolerance    %g\n",oparams.tol);
    fprintf(stderr,"#    maximum number of iterations   %u\n",oparams.maxiter);
    fprintf(stderr,"#    precision                      %g\n",oparams.epsabs);
    }
    else{
      fprintf(stderr,"#    maximum number of iterations   %u\n",oparams.maxiter);
      fprintf(stderr,"#    maximum simplex size           %g\n",oparams.maxsize);
    }
  }
  /* -------------------------------------------- */



  /* compute values of y for initial condition */
  for(i=0;i<n;i++){
    if(type==NULL)
      SET(y,i,x[i]);
    else
      switch(type[i]){
      case 0:/* (-inf,+inf) */
	SET(y,i,x[i]);
	break;
      case 1:/* [a,+inf) */
	SET(y,i,sqrt( x[i]-xmin[i] ));
	break;
      case 2:/* (-inf,a] */
	SET(y,i,sqrt( xmax[i]-x[i] ));
	break;
      case 3:/* [a,b] */
	dtmp1 = (xmax[i]>xmin[i]?
		 (2.*x[i]-xmax[i]-xmin[i])/(xmax[i]-xmin[i]) : 0);
	/*       dtmp1 = (2.*x[i]-xmax[i]-xmin[i])/(xmax[i]-xmin[i]); */
	SET(y,i,asin( dtmp1 ));
	break;
      case 4:/* (a,+inf) */
	SET(y,i,log( x[i]-xmin[i] ));
	break;
      case 5:/* (-inf,a) */
	SET(y,i,log( xmax[i]-x[i] ));
	break;
      case 6:/* (a,b) */
	dtmp1 = (2.*x[i]-xmax[i]-xmin[i])/(xmax[i]-xmin[i]);
	SET(y,i,gsl_atanh ( dtmp1 ));
	break;
      case 7:/* (a,b) second approach */
	dtmp1 = (2.*x[i]-xmax[i]-xmin[i])/(xmax[i]-xmin[i]);
	SET(y,i, dtmp1/sqrt(1-dtmp1*dtmp1));
	break;
      case 8:/* (a,+inf) second approach */
	dtmp1 = x[i]-xmin[i];
	SET(y,i, dtmp1-1./(4.*dtmp1));
	break;
      }
  }

  /* --- OUPUT ---------------------------------- */
  if(oparams.verbosity>1){
    fprintf(stderr,"#    - variables initial value and boundaries\n");
    for(i=0;i<n;i++){
      if(type==NULL)
	fprintf(stderr,"#    x[%d]=%e (-inf,+inf) -> %e\n",(int) i,x[i],GET(y,i));
      else
	switch(type[i]){
	case 0:/* (-inf,+inf) */
	  fprintf(stderr,"#    x[%d]=%e (-inf,+inf) -> %e\n",(int) i,x[i],GET(y,i));
	  break;
	case 1:/* [a,+inf) */
	  fprintf(stderr,"#    x[%d]=%e [%g,+inf) -> %e\n",(int) i,x[i],xmin[i],GET(y,i));
	  break;
	case 2:/* (-inf,a] */
	  fprintf(stderr,"#    x[%d]=%e (-inf,%g] -> %e\n",(int) i,x[i],xmax[i],GET(y,i));
	  break;
	case 3:/* [a,b] */
	  fprintf(stderr,"#    x[%d]=%e [%g,%g] -> %e\n",(int) i,x[i],xmin[i],xmax[i],GET(y,i));
	  break;
	case 4:/* (a,+inf) */
	  fprintf(stderr,"#    x[%d]=%e (%g,+inf) -> %e\n",(int) i,x[i],xmin[i],GET(y,i));
	  break;
	case 5:/* (-inf,a) */
	  fprintf(stderr,"#    x[%d]=%e (-inf,%g) -> %e\n",(int) i,x[i],xmax[i],GET(y,i));
	  break;
	case 6:/* (a,b) */
	case 7:
	  fprintf(stderr,"#    x[%d]=%e (%g,%g) -> %e\n",(int) i,x[i],xmin[i],xmax[i],GET(y,i));
	  break;
	case 8:/* [a,+inf) */
	  fprintf(stderr,"#    x[%d]=%e (%g,+inf) -> %e\n",(int) i,x[i],xmin[i],GET(y,i));
	  break;
	}
    }
    {
      double res;
      fprintf(stderr,"#    - function initial value\n");
      f(n,x,fparams,&res);
      fprintf(stderr,"#    f=%e\n",res);
    }
  }
  /* -------------------------------------------- */


  if(oparams.method<4 || oparams.method==5){/* methods with derivatives */

    struct g_params gparams;
    gsl_multimin_function_fdf GdG;
    gsl_multimin_fdfminimizer *s = gsl_multimin_fdfminimizer_alloc (Tfdf,n);

    /* set the parameters of the new function */
    gparams.n       = n;
    gparams.type    = type;
    gparams.xmin    = xmin;
    gparams.xmax    = xmax;
    gparams.f       = f;
    gparams.df      = df;
    gparams.fdf     = fdf;
    gparams.fparams = fparams;
    
    /* set the function to solve */
    GdG.f=g;
    GdG.df=dg;
    GdG.fdf=gdg;
    GdG.n=n;
    GdG.params=(void *) &gparams;

  
    /* initialize minimizer */
    status=gsl_multimin_fdfminimizer_set(s,&GdG,y,oparams.step_size,oparams.tol);  

    if(status)
      {
	fprintf(stderr,"#ERROR: %s\n",gsl_strerror (status));
	exit(EXIT_FAILURE);
      }

    /* +++++++++++++++++++++++++++++++++++++++++++++++ */
    if(oparams.verbosity>2)
      fprintf(stderr,"#    - start minimization \n");
    /* +++++++++++++++++++++++++++++++++++++++++++++++ */
   
    do
      {

	iter++;
	
	status = gsl_multimin_fdfminimizer_iterate (s);

	/* +++++++++++++++++++++++++++++++++++++++++++++++ */
	if(oparams.verbosity>2){
	  fprintf(stderr,"#     [%d]",iter);
	  fprintf(stderr," g=%+12.6e  y=( ",s->f);
	  for(i=0;i<n;i++)
	  fprintf(stderr,"%+12.6e ",GET(s->x,i));
	  fprintf(stderr,") dg=( ");
	  for(i=0;i<n;i++)
	    fprintf(stderr,"%+12.6e  ",GET(s->gradient,i));
          fprintf(stderr,") |dg|=%12.6e ",gsl_blas_dnrm2 (s->gradient));
          fprintf(stderr,"|dx|=%12.6e\n",gsl_blas_dnrm2 (s->dx));
	}
	/* +++++++++++++++++++++++++++++++++++++++++++++++ */


	if(status == GSL_ENOPROG){
	  fprintf(stderr,"#    status: %s\n",gsl_strerror (status));
	  break;
	}
	
	if(status){
	  fprintf(stderr,"#WARNING: %s\n", gsl_strerror (status));
	  break;
	}

/*         { */
/* 	  const double eps = oparams.epsabs; */
/* 	  const double norm_x  = gsl_blas_dnrm2 (s->x); */
/* 	  const double norm_dx = gsl_blas_dnrm2 (s->dx); */
/* 	  const double norm_g  = gsl_blas_dnrm2 (s->gradient); */

/* 	  if( norm_dx < eps && norm_dx < norm_x*eps && norm_g < eps ) */
/* 	    status = GSL_SUCCESS; */
/* 	  else */
/* 	    status = GSL_CONTINUE; */

/*           fprintf(stderr,"|x|=%f |dx|=%f |dg|=%f\n",norm_x,norm_dx,norm_g); */
	  
/* 	} */
            
	status = gsl_multimin_test_gradient (s->gradient,oparams.epsabs); 

      }
    while (status == GSL_CONTINUE && iter < oparams.maxiter);

    gsl_vector_memcpy (y,s->x);
    *fun=s->f;
    gsl_multimin_fdfminimizer_free (s);

  }
  else{ /* methods without derivatives */

    gsl_vector *ss = gsl_vector_alloc (n);
    struct g_params gparams;
    gsl_multimin_function G;
    gsl_multimin_fminimizer *s=gsl_multimin_fminimizer_alloc (Tf,n);

    /* set the parameters of the new function */
    gparams.n       = n;
    gparams.type    = type;
    gparams.xmin    = xmin;
    gparams.xmax    = xmax;
    gparams.f       = f;
    gparams.fparams = fparams;

    /* set the function to solve */
    G.f=g;
    G.n=n;
    G.params=(void *) &gparams;

    /* Initial vertex size vector */
    {
      /* size_t i; */

/*       dg(y,&gparams,ss); */
/*       gsl_vector_set_all (ss,1); */

/*       for(i=0;i<n;i++) */
/* 	SET(ss,i,fabs(GET(ss,i))); */
/*       gsl_vector_add_constant (ss,oparams.maxsize); */


      gsl_vector_set_all (ss,oparams.step_size+oparams.maxsize);

    }

    /* --- OUPUT ---------------------------------- */
    if(oparams.verbosity>0){
      size_t i;
      fprintf(stderr,"#    initial simplex sizes\n");
      fprintf(stderr,"#    ");
      for(i=0;i<n;i++)
	fprintf(stderr," %g", GET(ss,i));
      fprintf(stderr,"\n");
    }
    /* -------------------------------------------- */

    /* Initialize minimizer */ 
    status=gsl_multimin_fminimizer_set(s,&G,y,ss);

    do
      {

	status = gsl_multimin_fminimizer_iterate(s);
	const double size = gsl_multimin_fminimizer_size (s);
	iter++;

	/* +++++++++++++++++++++++++++++++++++++++++++++++ */
	if(oparams.verbosity>2){
	  fprintf(stderr,"#    g=%g y=( ",s->fval);
	  for(i=0;i<n;i++)
	    fprintf(stderr,"%g ",GET(s->x,i));
	  fprintf(stderr,") ");
	  fprintf(stderr," simplex size=%g ",size);
	  fprintf(stderr,"\n");
	}
	/* +++++++++++++++++++++++++++++++++++++++++++++++ */

	status=gsl_multimin_test_size (size,oparams.maxsize);
      }
    while (status == GSL_CONTINUE && iter < oparams.maxiter);

    gsl_vector_memcpy (y, s->x);
    *fun=s->fval;
    gsl_multimin_fminimizer_free (s);
  gsl_vector_free(ss);

  }

  /* compute values of x */
  for(i=0;i<n;i++){
    if(type==NULL) /* (-inf,+inf) */
      x[i]=GET(y,i);
    else 
      switch(type[i]){
      case 0:/* (-inf,+inf) */
	x[i]=GET(y,i);
	break;
      case 1:/* [a,+inf) */
	x[i]=xmin[i]+GET(y,i)*GET(y,i);
	break;
      case 2:/* (-inf,a] */
	x[i]=xmax[i]-GET(y,i)*GET(y,i);
	break;
      case 3:/* [a,b] */
	dtmp1 = sin( GET(y,i) );
	x[i]=.5*(xmin[i]*(1-dtmp1) +xmax[i]*(1+dtmp1));
	break;
      case 4:/* (a,+inf) */
	dtmp1 = exp( GET(y,i) );
	x[i]=xmin[i]+dtmp1;
	break;
      case 5:/* (-inf,a) */
	dtmp1 = -exp( GET(y,i) );
	x[i]=xmax[i]+dtmp1;
	break;
      case 6:/* (a,b) */
	dtmp1 = tanh( GET(y,i) );
	x[i]=.5*(xmin[i]*(1-dtmp1) +xmax[i]*(1+dtmp1));
	break;
      case 7:/* (a,b) second approach */
	dtmp1 = GET(y,i) ;
	dtmp1 = dtmp1/sqrt(1.+dtmp1*dtmp1);
	x[i]=.5*(xmin[i]*(1-dtmp1) +xmax[i]*(1+dtmp1));
	break;
      case 8:/* (a,+inf) second approach */
	dtmp1 = sqrt(1.+GET(y,i)*GET(y,i));
	x[i]= xmin[i] + .5*(dtmp1+GET(y,i));
	break;
      }

  }

  /* --- OUPUT ---------------------------------- */
  if(oparams.verbosity>0){
    fprintf(stderr,"#    - end minimization\n");
    fprintf(stderr,"#    iterations %u\n",iter);

    for(i=0;i<n;i++)
      fprintf(stderr,"#    %e -> x[%zd]=%e\n",GET(y,i),i,x[i]);

    fprintf(stderr,"#--- MULTIMIN END --- \n");
  }
  /* -------------------------------------------- */

  gsl_vector_free (y);

}
	GslMinimizerHolder::Instance::~Instance () {
		gsl_multimin_fdfminimizer* &gslMinimizer( *this );
		gsl_multimin_fdfminimizer_free( gslMinimizer );
		gslMinimizer = NULL;
	}
示例#19
0
arma::vec DIIS::get_w_adiis() const {
  // Number of parameters
  size_t N=PiF.n_elem;

  if(N==1) {
    // Trivial case.
    arma::vec ret(1);
    ret.ones();
    return ret;
  }

  const gsl_multimin_fdfminimizer_type *T;
  gsl_multimin_fdfminimizer *s;

  gsl_vector *x;
  gsl_multimin_function_fdf minfunc;
  minfunc.f = adiis::min_f;
  minfunc.df = adiis::min_df;
  minfunc.fdf = adiis::min_fdf;
  minfunc.n = N;
  minfunc.params = (void *) this;

  T=gsl_multimin_fdfminimizer_vector_bfgs2;
  s=gsl_multimin_fdfminimizer_alloc(T,N);

  // Starting point: equal weights on all matrices
  x=gsl_vector_alloc(N);
  gsl_vector_set_all(x,1.0/N);

  // Initial energy estimate
  // double E_initial=get_E(x);

  // Initialize the optimizer. Use initial step size 0.02, and an
  // orthogonality tolerance of 0.1 in the line searches (recommended
  // by GSL manual for bfgs).
  gsl_multimin_fdfminimizer_set(s, &minfunc, x, 0.02, 0.1);

  size_t iter=0;
  int status;
  do {
    iter++;
    //    printf("iteration %lu\n",iter);
    status = gsl_multimin_fdfminimizer_iterate (s);

    if (status) {
      //      printf("Error %i in minimization\n",status);
      break;
    }

    status = gsl_multimin_test_gradient (s->gradient, 1e-7);

    /*
    if (status == GSL_SUCCESS)
      printf ("Minimum found at:\n");

    printf("%5lu ", iter);
    for(size_t i=0;i<N;i++)
      printf("%.5g ",gsl_vector_get(s->x,i));
    printf("%10.5g\n",s->f);
    */
  }
  while (status == GSL_CONTINUE && iter < 1000);

  // Final estimate
  // double E_final=get_E(s->x);

  // Form minimum
  arma::vec c=adiis::compute_c(s->x);

  gsl_multimin_fdfminimizer_free (s);
  gsl_vector_free (x);

  //  printf("Minimized estimate of %lu matrices by %e from %e to %e in %lu iterations.\n",D.size(),E_final-E_initial,E_initial,E_final,iter);

  return c;
}
示例#20
0
void GslOptimizer::minimize_with_gradient( unsigned int dim, OptimizerMonitor* monitor )
{
  // Set initial point
  gsl_vector * x = gsl_vector_alloc(dim);
  for (unsigned int i = 0; i < dim; i++) {
    gsl_vector_set(x, i, (*m_initialPoint)[i]);
  }

  // Tell GSL which solver we're using
  const gsl_multimin_fdfminimizer_type* type = NULL;

  // We use m_solver_type here because we need the enum
  switch(m_solver_type)
    {
    case(FLETCHER_REEVES_CG):
      type = gsl_multimin_fdfminimizer_conjugate_fr;
      break;
    case(POLAK_RIBIERE_CG):
      type = gsl_multimin_fdfminimizer_conjugate_pr;
      break;
    case(BFGS):
      type = gsl_multimin_fdfminimizer_vector_bfgs;
      break;
    case(BFGS2):
      type = gsl_multimin_fdfminimizer_vector_bfgs2;
      break;
    case(STEEPEST_DESCENT):
      type = gsl_multimin_fdfminimizer_steepest_descent;
      break;
    case(NELDER_MEAD):
    case(NELDER_MEAD2):
    case(NELDER_MEAD2_RAND):
    default:
      // Wat?!
      queso_error();
    }

  // Init solver
  gsl_multimin_fdfminimizer * solver =
    gsl_multimin_fdfminimizer_alloc(type, dim);

  // Point GSL to the right functions
  gsl_multimin_function_fdf minusLogPosterior;
  minusLogPosterior.n = dim;
  minusLogPosterior.f = &c_evaluate;
  minusLogPosterior.df = &c_evaluate_derivative;
  minusLogPosterior.fdf = &c_evaluate_with_derivative;
  minusLogPosterior.params = (void *)(this);

  gsl_multimin_fdfminimizer_set(solver, &minusLogPosterior, x, getFdfstepSize(), getLineTolerance());

  int status;
  size_t iter = 0;

  do {
    iter++;
    status = gsl_multimin_fdfminimizer_iterate(solver);

    if (status) {
      if( m_objectiveFunction.domainSet().env().fullRank() == 0 )
        {
          std::cerr << "Error while GSL does optimisation. "
                    << "See below for GSL error type." << std::endl;
          std::cerr << "Gsl error: " << gsl_strerror(status) << std::endl;
        }
      break;
    }

    status = gsl_multimin_test_gradient(solver->gradient, this->getTolerance());

    if(monitor)
      {
        gsl_vector* x = gsl_multimin_fdfminimizer_x(solver);
        std::vector<double> x_min(dim);
        for( unsigned int i = 0; i < dim; i++)
          x_min[i] = gsl_vector_get(x,i);

        double f = gsl_multimin_fdfminimizer_minimum(solver);

        gsl_vector* grad = gsl_multimin_fdfminimizer_gradient(solver);
        double grad_norm = gsl_blas_dnrm2(grad);

        monitor->append( x_min, f, grad_norm );
      }

  } while ((status == GSL_CONTINUE) && (iter < this->getMaxIterations()));

  for (unsigned int i = 0; i < dim; i++) {
    (*m_minimizer)[i] = gsl_vector_get(solver->x, i);
  }

  // We're being good human beings and cleaning up the memory we allocated
  gsl_multimin_fdfminimizer_free(solver);
  gsl_vector_free(x);

  return;
}
示例#21
0
void minim(density_t * ndft){
  const gsl_multimin_fdfminimizer_type *T;
  gsl_multimin_fdfminimizer *s;
  gsl_multimin_function_fdf my_func;
  gsl_vector * grad_initial;
  size_t iter;

  ipf_t ipf_previous;

  int  status;
  double minimum, g_initial, norm_initial;
  char * output_string;
  int i;
  params_gsl_multimin_function_t params;

  output_string = (char *) malloc(25*sizeof(char));

  params.nDFT = density_get_val(ndft);
  my_func.n = ipf.npar;
  my_func.f = my_f;
  my_func.df = my_df;
  my_func.fdf = my_fdf;
  my_func.params = (void *) (&params);

  /* We use the BFGS algorithm from thee GNU Scientific Library (GSL)
     in its optimized version bfgs2 */
  T = gsl_multimin_fdfminimizer_vector_bfgs2;

  messages_basic("\n\nStarting the optimization.\n\n\n");


  grad_initial = gsl_vector_alloc(ipf.npar);
  my_fdf (ipf.gamma, &params, &g_initial, grad_initial);
  norm_initial = gsl_blas_dnrm2(grad_initial);
  if(g_initial < epsilon_gvalue){
    if(myid == 0) printf("The value of G for the starting gamma is %.12lg,\n", g_initial);
    if(myid == 0) printf("which is already below the requested threshold of %.12lg\n", epsilon_gvalue);
    parallel_end(EXIT_SUCCESS);
  }
  if(norm_initial < epsilon_grad){
    if(myid == 0) printf("The value of the normm of the gradient of G for the starting gamma is %.12lg,\n", norm_initial);
    if(myid == 0) printf("which is already below the requested threshold of %.12lg\n", epsilon_grad);
    parallel_end(EXIT_SUCCESS);
  }
  if(myid == 0) printf("  Starting from gamma =  ");
  if(myid == 0) {for(i = 0; i < ipf.npar; i++) printf ("%.5f ", gsl_vector_get (ipf.gamma, i));}
  if(myid == 0) printf("\n  G(gamma) = %.12lg\n", g_initial);
  if(myid == 0) printf("  ||Grad G(gamma)|| = %.12lg\n\n", norm_initial);


  /* Initialization of the minimizer s for the function
     my_func starting at the x point
     The step for the first try is 0.1
     and the convergence criteria is 0.1 */
  messages_basic("\n\nInitialization of the minimizer.\n\n\n");
  s = gsl_multimin_fdfminimizer_alloc (T, ipf.npar);
  gsl_multimin_fdfminimizer_set (s, &my_func, ipf.gamma, 0.1, 0.1);

  minimum = g_initial;
  iter = 0;
  do{
    iter++;

    ipf_copy(&ipf_previous, &ipf);

    if(myid == 0) printf("  Iter = %d\n", (int)iter);
    if(myid == 0) printf("    starting gamma =  ");
    if(myid == 0) {for(i = 0; i < ipf.npar; i++) printf ("%.5f ", gsl_vector_get (gsl_multimin_fdfminimizer_x(s), i));}
    if(myid == 0) printf("\n    starting G(gamma) = %15.10f\n", minimum);
    /* We make an iteration of the minimizer s */
    status = gsl_multimin_fdfminimizer_iterate (s);
    minimum = gsl_multimin_fdfminimizer_minimum(s);

    if (status){
      if(myid == 0) printf("  Breaking. Reason: %s\n", gsl_strerror(status));
      break;
    }

    if(myid == 0) printf("    ||Grad G(gamma)|| = %15.10f\n", gsl_blas_dnrm2(gsl_multimin_fdfminimizer_gradient(s)));
    if(myid == 0) printf("    G(gamma) = %15.10f\n", minimum);

    /* Checks convergence */
    if(minimum < epsilon_gvalue){
       status = GSL_SUCCESS;
    }else{
       status = gsl_multimin_test_gradient (gsl_multimin_fdfminimizer_gradient(s), epsilon_grad);
    }

    gsl_vector_memcpy(ipf.gamma, gsl_multimin_fdfminimizer_x(s));
    ipf_write(ipf, ipf_ref, "intermediate-pot");


    /* Print the diff between initial and reference IPFs */
    if(myid == 0) printf("    Diff[ IPF(previous), IPF(new) ] = %.12lg\n", ipf_diff(&ipf_previous, &ipf));
    ipf_end(&ipf_previous);

  }
  while (status == GSL_CONTINUE && iter < minim_maxiter);

  if(myid == 0) printf("\n\nFinished optimization. status = %d (%s)\n", status, gsl_strerror(status));
  if(myid == 0) printf("  Final gamma =  ");
  if(myid == 0) {for(i = 0; i < ipf.npar; i++) printf ("%.5f ", gsl_vector_get (gsl_multimin_fdfminimizer_x(s), i));}
  if(myid == 0) printf("\n  With value: G(gamma) = %.12lg\n\n", gsl_multimin_fdfminimizer_minimum(s));

  gsl_vector_memcpy(ipf.gamma, gsl_multimin_fdfminimizer_x(s));
  sprintf(output_string, "pot");
  ipf_write(ipf, ipf_ref, output_string);
  gsl_multimin_fdfminimizer_free (s);
  fflush(stdout);

}
示例#22
0
int main (int argc, char *argv[])
{



printf("Number of haplotypes: %d\n", atoi(argv[1]) );
int temp =0;
temp = atoi(argv[1]);
printf("Number of time intervals:  %d\n", atoi(argv[2]) );

printf("File name:  %s\n", argv[3] );

 int num_haps = atoi(argv[1]);
 int num_times = atoi(argv[2]);


//make_bins(num_haps);
//readfile(argv[3]);
read_binned_file(argv[3]);
//make_custom_bins(num_haps); // one bin per match length
// printf("num_loci = %d\n", num_loci);
// printf("marker %f\n", 1.7);
// printf("a;lskdjf %d\n", 3);


make_times(num_haps, num_times);
read_quant_file(argv[4]);
precompute(num_haps, num_times);




/*
 struct scenario the_scenario;
the_scenario.num_haps = argv[1];
the_scenario.num_times = argv[2];*/



  size_t iter = 0;
//  size_t i; // commented out to fix the problem labelled XYRQ below
		// there was a comparison between signed/unsiged int
  
int status;

  const gsl_multimin_fdfminimizer_type *T;
  gsl_multimin_fdfminimizer *s;

  /* Position of the minimum (1,2). */

int j=0;

double par[2];

par[0] = num_haps;
par[1] = num_times;

  gsl_vector *x;
  gsl_multimin_function_fdf my_func;

  my_func.f = &my_f;
  my_func.df = &my_df;
  my_func.fdf = &my_fdf;
  my_func.n = num_times;
  my_func.params = &par;


  /* Starting point, x = (5,7) */

  x = gsl_vector_alloc (num_times);

for (j=0; j<num_times; j++)
{
if(j<=50){gsl_vector_set (x, j, 30000  );}
else {gsl_vector_set (x, j, 20000   );}
}

 T = gsl_multimin_fdfminimizer_conjugate_fr;
//   T = gsl_multimin_fdfminimizer_vector_bfgs2;

  s = gsl_multimin_fdfminimizer_alloc (T, num_times);

// likelihood setting
  gsl_multimin_fdfminimizer_set (s, &my_func, x, 10000, .000001);

//  quantile setting
  //gsl_multimin_fdfminimizer_set (s, &my_func, x, 3000.0, .100);


  do
    {

      iter++;
      status = gsl_multimin_fdfminimizer_iterate (s);

	//printf("help %d\n", 3);

      if (status){
printf ("Iteration terminated at:\nSTART HERE\n");

	//printf ("%5zu ", iter);  // using %zu instead of %d b/c iter is type size_t not type int
			int k=0;
			for (k = 0; k < num_times; k++)  
			{
			printf ("%f\t%10.3f\n", time[k], gsl_vector_get (s->x, k));  // problem XYRQ
						// using k here renders size_t i above unused
			}
	printf ("f() = %7.3f \n", s->f);
//  q
        break;}

//printf("help %d\n", 4);


 //.likelihood setting
	status = gsl_multimin_test_gradient (s->gradient, 1e-10 );

// quantile setting
//	status = gsl_multimin_test_gradient (s->gradient, .010 );


      if (status == GSL_SUCCESS)
 { printf ("Minimum found at:\nSTART HERE\n");}
			int k=0;
 			for (k = 0; k < num_times; k++)  
 			{
 			printf ("%f\t%10.3f\n", time[k], gsl_vector_get (s->x, k)); // problem XYRQ
 						// using k here renders size_t i above unused
 			}
	//printf ("f() = %7.3f \n", s->f);
      
// 	  printf ("Minimum found at:\n");
// 
// 	printf ("%5zu ", iter);  // using %zu instead of %d b/c iter is type size_t not type int
// 			int k=0;
// 			for (k = 0; k < num_times; k++)  
// 			{
// 			printf ("%10.3e ", gsl_vector_get (s->x, k)); // problem XYRQ
// 						using k here renders size_t i above unused
// 			}
 	

	
//       printf ("%5d %.5f %.5f %10.5f\n", iter,
//               gsl_vector_get (s->x, 0),
//               gsl_vector_get (s->x, 1),
//               s->f);

    }

  while (status == GSL_CONTINUE && iter < 1000);

  gsl_multimin_fdfminimizer_free (s);
  gsl_vector_free (x);


  return 0;

}
示例#23
0
int FC_FUNC_(oct_minimize, OCT_MINIMIZE)
     (const int *method, const int *dim, double *point, const double *step, const double *line_tol, 
      const double *tolgrad, const double *toldr, const int *maxiter, func_d f, 
      const print_f_ptr write_info, double *minimum)
{
  int iter = 0;
  int status;
  double maxgrad, maxdr;
  int i;
  double * oldpoint;
  double * grad;

  const gsl_multimin_fdfminimizer_type *T = NULL;
  gsl_multimin_fdfminimizer *s;
  gsl_vector *x;
  gsl_vector *absgrad, *absdr;
  gsl_multimin_function_fdf my_func;

  param_fdf_t p;

  p.func = f;

  oldpoint = (double *) malloc(*dim * sizeof(double));
  grad     = (double *) malloc(*dim * sizeof(double));

  my_func.f = &my_f;
  my_func.df = &my_df;
  my_func.fdf = &my_fdf;
  my_func.n = *dim;
  my_func.params = (void *) &p;

  /* Starting point */
  x = gsl_vector_alloc (*dim);
  for(i=0; i<*dim; i++) gsl_vector_set (x, i, point[i]);

  /* Allocate space for the gradient */
  absgrad = gsl_vector_alloc (*dim);
  absdr = gsl_vector_alloc (*dim);

  //GSL recommends line_tol = 0.1;
  switch(*method){
  case 1: 
    T = gsl_multimin_fdfminimizer_steepest_descent;
    break;
  case 2: 
    T = gsl_multimin_fdfminimizer_conjugate_fr;
    break;
  case 3: 
    T = gsl_multimin_fdfminimizer_conjugate_pr;
    break;
  case 4: 
    T = gsl_multimin_fdfminimizer_vector_bfgs;
    break;
  case 5: 
    T = gsl_multimin_fdfminimizer_vector_bfgs2;
    break;
  }

  s = gsl_multimin_fdfminimizer_alloc (T, *dim);

  gsl_multimin_fdfminimizer_set (s, &my_func, x, *step, *line_tol);
  do
    {
      iter++;
      for(i=0; i<*dim; i++) oldpoint[i] = point[i];

      /* Iterate */
      status = gsl_multimin_fdfminimizer_iterate (s);

      /* Get current minimum, point and gradient */
      *minimum = gsl_multimin_fdfminimizer_minimum(s);
      for(i=0; i<*dim; i++) point[i] = gsl_vector_get(gsl_multimin_fdfminimizer_x(s), i);
      for(i=0; i<*dim; i++) grad[i] = gsl_vector_get(gsl_multimin_fdfminimizer_gradient(s), i);

      /* Compute convergence criteria */
      for(i=0; i<*dim; i++) gsl_vector_set(absdr, i, fabs(point[i]-oldpoint[i]));
      maxdr = gsl_vector_max(absdr);
      for(i=0; i<*dim; i++) gsl_vector_set(absgrad, i, fabs(grad[i]));
      maxgrad = gsl_vector_max(absgrad);

      /* Print information */
      write_info(&iter, dim, minimum, &maxdr, &maxgrad, point);
      
      /* Store infomation for next iteration */
      for(i=0; i<*dim; i++) oldpoint[i] = point[i];

      if (status)
        break;

      if ( (maxgrad <= *tolgrad) || (maxdr <= *toldr) ) status = GSL_SUCCESS;
      else status = GSL_CONTINUE;
    }
  while (status == GSL_CONTINUE && iter <= *maxiter);

  if(status == GSL_CONTINUE) status = 1025;

  gsl_multimin_fdfminimizer_free (s);
  gsl_vector_free (x); gsl_vector_free(absgrad); gsl_vector_free(absdr);

  free(oldpoint);
  free(grad);

  return status;
}
示例#24
0
std::vector<contr_t> slater_fit(double zeta, int am, int nf, bool verbose, int method) {
  sto_params_t par;
  par.zeta=zeta;
  par.l=am;
  par.Nf=nf;
  par.method=method;

  int maxiter=1000;

  // Degrees of freedom
  int dof;
  if(par.method==0 && nf>=2)
    dof=2;
  else
    // Full optimization
    par.method=2;

  if(par.method==1 && nf>=4)
    dof=4;
  else
    // Full optimization
    par.method=2;

  // Full optimization
  if(par.method==2)
    dof=par.Nf;

  gsl_multimin_function_fdf minfunc;
  minfunc.n=dof;
  minfunc.f=eval_difference;
  minfunc.df=eval_difference_df;
  minfunc.fdf=eval_difference_fdf;
  minfunc.params=(void *) &par;

  gsl_multimin_fdfminimizer *min;
  // Allocate minimizer
  //  min=gsl_multimin_fdfminimizer_alloc(gsl_multimin_fdfminimizer_vector_bfgs2,dof);
  min=gsl_multimin_fdfminimizer_alloc(gsl_multimin_fdfminimizer_conjugate_pr,dof);

  gsl_vector *x;
  x=gsl_vector_alloc(dof);

  // Initialize vector
  gsl_vector_set_all(x,0.0);

  // Set starting point
  switch(par.method) {
    
  case(2):
    // Legendre - same as for even tempered
  case(1):
    // Well tempered - same initialization as for even-tempered
  case(0):
    // Even tempered, set alpha=1.0 and beta=2.0
    gsl_vector_set(x,0,1.0);
    if(dof>1)
      gsl_vector_set(x,1,2.0);
    break;
  
    /*
  case(2):
    // Free minimization, set exponents to i
    for(int i=0;i<nf;i++)
      gsl_vector_set(x,i,i);
    break;
    */

  default:
    ERROR_INFO();
    throw std::runtime_error("Unknown Slater fitting method.\n");
  }
  
  // Set minimizer
  gsl_multimin_fdfminimizer_set(min, &minfunc, x, 0.01, 1e-4);

  // Iterate
  int iter=0;
  int iterdelta=0;
  int status;
  double cost=0;

  if(verbose) printf("Iteration\tDelta\n");
  do {
    iter++;
    iterdelta++;

    // Simplex
    status = gsl_multimin_fdfminimizer_iterate(min);
    if (status) {
      //      printf("Encountered GSL error \"%s\"\n",gsl_strerror(status));
      break;
    }

    // Are we converged?
    status = gsl_multimin_test_gradient (min->gradient, 1e-12);
    if (verbose && status == GSL_SUCCESS)
      {
        printf ("converged to minimum at\n");
      }

    if(min->f!=cost) {
      if(verbose) printf("%i\t%e\t%e\t%e\n",iter,min->f,min->f-cost,gsl_blas_dnrm2(min->gradient));
      cost=min->f;
      iterdelta=0;
    }

  } while (status == GSL_CONTINUE && iterdelta < maxiter);

  // Get best exponents and coefficients
  std::vector<double> optexp=get_exps(min->x,&par);
  arma::vec optc=solve_coefficients(optexp,par.zeta,par.l);

  // Free memory
  gsl_vector_free(x);
  gsl_multimin_fdfminimizer_free(min);

  // Return
  std::vector<contr_t> ret(nf);
  for(int i=0;i<nf;i++) {
    ret[i].z=optexp[i];
    ret[i].c=optc[i];
  }

  return ret;
}
示例#25
0
int lua_multimin_minimize(lua_State * L) {
    bool ssdel=false;
    double eps=0.00001;
    double tol=0.0001;
    double step_size=0.01;
    int maxiter=1000;
    bool print=false;
    array<double> * x=0;
    array<double> * ss=0;
    const gsl_multimin_fminimizer_type *Tf = 0;
    const gsl_multimin_fdfminimizer_type *Tdf = 0;


    multi_param mp;
    mp.L=L;
    mp.fdf_index=-1;

    lua_pushstring(L,"f");
    lua_gettable(L,-2);
    if(lua_isfunction(L,-1)) {
        mp.f_index=luaL_ref(L, LUA_REGISTRYINDEX);
    } else {
        luaL_error(L,"%s\n","missing function");
    }

    lua_pushstring(L,"df");
    lua_gettable(L,-2);
    if(lua_isfunction(L,-1)) {
        mp.df_index=luaL_ref(L, LUA_REGISTRYINDEX);
        Tdf= gsl_multimin_fdfminimizer_conjugate_fr;
    } else {
        lua_pop(L,1);
        Tf= gsl_multimin_fminimizer_nmsimplex2;
    }

    lua_pushstring(L,"fdf");
    lua_gettable(L,-2);
    if(lua_isfunction(L,-1)) {
        mp.fdf_index=luaL_ref(L, LUA_REGISTRYINDEX);
    } else {
        lua_pop(L,1);
        mp.fdf_index=-1;
    }

    lua_pushstring(L,"algorithm");
    lua_gettable(L,-2);
    if(lua_isstring(L,-1)) {
        if(Tf!=0) {
            if(!strcmp(lua_tostring(L,-1),"nmsimplex")) {
                Tf = gsl_multimin_fminimizer_nmsimplex;
            } else if(!strcmp(lua_tostring(L,-1),"nmsimplex2rand")) {
                Tf = gsl_multimin_fminimizer_nmsimplex2rand;
            } else if(!strcmp(lua_tostring(L,-1),"nmsimplex2")) {
                Tf = gsl_multimin_fminimizer_nmsimplex2;
            } else {
                luaL_error(L,"%s\n","invalid algorithm");
            }
        } else {
            if(!strcmp(lua_tostring(L,-1),"conjugate_pr")) {
                Tdf = gsl_multimin_fdfminimizer_conjugate_pr;
            } else if(!strcmp(lua_tostring(L,-1),"steepest_descent")) {
                Tdf = gsl_multimin_fdfminimizer_steepest_descent;
            } else if(!strcmp(lua_tostring(L,-1),"vector_bfgs")) {
                Tdf = gsl_multimin_fdfminimizer_vector_bfgs;
            } else if(!strcmp(lua_tostring(L,-1),"vector_bfgs2")) {
                Tdf = gsl_multimin_fdfminimizer_vector_bfgs2;
            } else if(!strcmp(lua_tostring(L,-1),"conjugate_fr")) {
                Tdf = gsl_multimin_fdfminimizer_conjugate_fr;
            } else {
                luaL_error(L,"%s\n","invalid algorithm");
            }
        }
    }
    lua_pop(L,1);

    lua_pushstring(L,"show_iterations");
    lua_gettable(L,-2);
    if(lua_isboolean(L,-1)) {
        print=(lua_toboolean(L,-1)==1);
    }
    lua_pop(L,1);

    lua_pushstring(L,"eps");
    lua_gettable(L,-2);
    if(lua_isnumber(L,-1)) {
        eps=lua_tonumber(L,-1);
    }
    lua_pop(L,1);

    lua_pushstring(L,"step_size");
    lua_gettable(L,-2);
    if(lua_isnumber(L,-1)) {
        step_size=lua_tonumber(L,-1);
    }
    lua_pop(L,1);

    lua_pushstring(L,"tol");
    lua_gettable(L,-2);
    if(lua_isnumber(L,-1)) {
        tol=lua_tonumber(L,-1);
    }
    lua_pop(L,1);

    lua_pushstring(L,"maxiter");
    lua_gettable(L,-2);
    if(lua_isnumber(L,-1)) {
        maxiter=(int)lua_tonumber(L,-1);
    }
    lua_pop(L,1);

    lua_pushstring(L,"starting_point");
    lua_gettable(L,-2);
    if(!lua_isuserdata(L,-1)) lua_error(L);
    if (!SWIG_IsOK(SWIG_ConvertPtr(L,-1,(void**)&x,SWIGTYPE_p_arrayT_double_t,0))){
        luaL_error(L,"%s\n","missing starting point");
    }
    lua_pop(L,1);

    if(Tf) {
        lua_pushstring(L,"step_sizes");
        lua_gettable(L,-2);
        if(lua_isuserdata(L,-1)) {
            if (!SWIG_IsOK(SWIG_ConvertPtr(L,-1,(void**)&ss,SWIGTYPE_p_arrayT_double_t,0))){
                lua_error(L);
            }
        } else {
            ssdel=true;
            ss=new array<double>(x->size());
            ss->set_all(1.0);
            if(lua_isnumber(L,-1)) {
                double v=lua_tonumber(L,-1);
                ss->set_all(v);
            }
        }
        lua_pop(L,1);
    }

    lua_pop(L,1);

    if(Tf) {
        gsl_multimin_fminimizer *s = NULL;
        gsl_vector SS, X;
        gsl_multimin_function minex_func;

        int iter = 0;
        int status;
        double size;
        int N=x->size();

        /* Starting point */
        X.size=x->size();
        X.stride=1;
        X.data=x->data();
        X.owner=0;

        /* Set initial step sizes */
        SS.size=ss->size();
        SS.stride=1;
        SS.data=ss->data();
        SS.owner=0;

        /* Initialize method and iterate */
        minex_func.n = N;
        minex_func.f = multimin_f_cb;
        minex_func.params = &mp;

        s = gsl_multimin_fminimizer_alloc (Tf, N);
        gsl_multimin_fminimizer_set (s, &minex_func, &X, &SS);
        if(print)  printf ("running algorithm '%s'\n",
                gsl_multimin_fminimizer_name (s));
        do
        {
            iter++;
            status = gsl_multimin_fminimizer_iterate(s);

            if (status)
                break;

            size = gsl_multimin_fminimizer_size (s);
            status = gsl_multimin_test_size (size, eps);

            if (status == GSL_SUCCESS)
            {
                if(print) printf ("converged to minimum at\n");
            }

            if(print) printf ("%5d f() = %12.3f size = %.9f\n",
                    iter,
                    s->fval, size);
        } while (status == GSL_CONTINUE && iter < maxiter);
        for(int i=0;i<N;++i) x->set(i,gsl_vector_get(s->x,i));
        luaL_unref(L, LUA_REGISTRYINDEX, mp.f_index);
        gsl_multimin_fminimizer_free (s);
    } else {
        gsl_multimin_fdfminimizer *s = NULL;
        gsl_vector X;
        gsl_multimin_function_fdf minex_func;

        int iter = 0;
        int status;
        double size;
        int N=x->size();

        /* Starting point */
        X.size=x->size();
        X.stride=1;
        X.data=x->data();
        X.owner=0;

        /* Initialize method and iterate */
        minex_func.n = N;
        minex_func.f = multimin_f_cb;
        minex_func.df = multimin_df_cb;
        minex_func.fdf = multimin_fdf_cb;
        minex_func.params = &mp;

        s = gsl_multimin_fdfminimizer_alloc (Tdf, N);
        gsl_multimin_fdfminimizer_set (s, &minex_func, &X, step_size, tol);
        if(print)  printf ("running algorithm '%s'\n",
                gsl_multimin_fdfminimizer_name (s));
        do
        {
            iter++;
            status = gsl_multimin_fdfminimizer_iterate(s);

            if (status)
                break;

            status = gsl_multimin_test_gradient (s->gradient, eps);

            if (status == GSL_SUCCESS)
            {
                if(print) printf ("converged to minimum at\n");
            }

            if(print) printf ("%5d f() = %12.3f\n",
                    iter,
                    s->f);
        } while (status == GSL_CONTINUE && iter < maxiter);
        for(int i=0;i<N;++i) x->set(i,gsl_vector_get(s->x,i));
        luaL_unref(L, LUA_REGISTRYINDEX, mp.f_index);
        luaL_unref(L, LUA_REGISTRYINDEX, mp.df_index);
        gsl_multimin_fdfminimizer_free (s);
    }
    if(mp.fdf_index>=0) {
        luaL_unref(L, LUA_REGISTRYINDEX, mp.fdf_index);
    }
    if(ssdel) {
        delete ss;
    }
    return 0;
}
示例#26
0
/**
 * Destructor.
 */
DerivMinimizer::~DerivMinimizer() {
  if (m_gslSolver != nullptr) {
    gsl_multimin_fdfminimizer_free(m_gslSolver);
    gsl_vector_free(m_x);
  }
}
int OptimizationOptions::gslOptimize( NLSFunction *F, gsl_vector* x_vec, 
        gsl_matrix *v, IterationLogger *itLog ) {
  const gsl_multifit_fdfsolver_type *Tlm[] =
    { gsl_multifit_fdfsolver_lmder, gsl_multifit_fdfsolver_lmsder };
  const gsl_multimin_fdfminimizer_type *Tqn[] = 
    { gsl_multimin_fdfminimizer_vector_bfgs,
      gsl_multimin_fdfminimizer_vector_bfgs2, 
      gsl_multimin_fdfminimizer_conjugate_fr,
      gsl_multimin_fdfminimizer_conjugate_pr };
  const gsl_multimin_fminimizer_type *Tnm[] = 
    { gsl_multimin_fminimizer_nmsimplex, gsl_multimin_fminimizer_nmsimplex2, 
      gsl_multimin_fminimizer_nmsimplex2rand };
  int gsl_submethod_max[] = { sizeof(Tlm) / sizeof(Tlm[0]),
			  sizeof(Tqn) / sizeof(Tqn[0]),
			  sizeof(Tnm) / sizeof(Tnm[0]) };  
			  
  int status, status_dx, status_grad, k;
  double g_norm, x_norm;

  /* vectorize x row-wise */
  size_t max_ind, min_ind;
  double max_val, min_val, abs_max_val = 0, abs_min_val;
  
  if (this->method < 0 || 
      this->method > sizeof(gsl_submethod_max)/sizeof(gsl_submethod_max[0]) || 
      this->submethod < 0 || 
      this->submethod > gsl_submethod_max[this->method]) {
    throw new Exception("Unknown optimization method.\n");   
  }
  
  if (this->maxiter < 0 || this->maxiter > 5000) {
    throw new Exception("opt.maxiter should be in [0;5000].\n");   
  }

  /* LM */
  gsl_multifit_fdfsolver* solverlm;
  gsl_multifit_function_fdf fdflm = { &(F->_f_ls),  &(F->_df_ls), &(F->_fdf_ls), 
                                       F->getNsq(), F->getNvar(), F };
  gsl_vector *g;

  /* QN */
  double stepqn = this->step; 
  gsl_multimin_fdfminimizer* solverqn;
  gsl_multimin_function_fdf fdfqn = { 
    &(F->_f), &(F->_df), &(F->_fdf), F->getNvar(), F };

  /* NM */
  double size;
  gsl_vector *stepnm;
  gsl_multimin_fminimizer* solvernm;
  gsl_multimin_function fnm = { &(F->_f), F->getNvar(), F };

  /* initialize the optimization method */
  switch (this->method) {
  case SLRA_OPT_METHOD_LM: /* LM */
    solverlm = gsl_multifit_fdfsolver_alloc(Tlm[this->submethod], 
                   F->getNsq(), F->getNvar());
    gsl_multifit_fdfsolver_set(solverlm, &fdflm, x_vec);
    g = gsl_vector_alloc(F->getNvar());
    break;
  case SLRA_OPT_METHOD_QN: /* QN */
    solverqn = gsl_multimin_fdfminimizer_alloc(Tqn[this->submethod], 
						F->getNvar() );
    gsl_multimin_fdfminimizer_set(solverqn, &fdfqn, x_vec, 
				  stepqn, this->tol); 
    status_dx = GSL_CONTINUE;  
    break;
  case SLRA_OPT_METHOD_NM: /* NM */
    solvernm = gsl_multimin_fminimizer_alloc(Tnm[this->submethod], F->getNvar());
    stepnm = gsl_vector_alloc(F->getNvar());
    gsl_vector_set_all(stepnm, this->step); 
    gsl_multimin_fminimizer_set( solvernm, &fnm, x_vec, stepnm );
    break;
  }

  /* optimization loop */
  Log::lprintf(Log::LOG_LEVEL_FINAL, "SLRA optimization:\n");
    
  status = GSL_SUCCESS;  
  status_dx = GSL_CONTINUE;
  status_grad = GSL_CONTINUE;  
  this->iter = 0;
  
  switch (this->method) {
  case SLRA_OPT_METHOD_LM:
    gsl_blas_ddot(solverlm->f, solverlm->f, &this->fmin);
    gsl_multifit_gradient(solverlm->J, solverlm->f, g);
    gsl_vector_scale(g, 2);
    {
      gsl_vector *g2 = gsl_vector_alloc(g->size);
      F->computeFuncAndGrad(x_vec, NULL, g2);
      gsl_vector_sub(g2, g);
      if (gsl_vector_max(g2) > 1e-10 || gsl_vector_min(g2) < -1e-10) {
        Log::lprintf(Log::LOG_LEVEL_NOTIFY,
               "Gradient error, max = %14.10f,  min = %14.10f  ...",
               gsl_vector_max(g2), gsl_vector_min(g2));
        print_vec(g2);
      }
      gsl_vector_free(g2);
    }
    if (itLog != NULL) {
      itLog->reportIteration(0, solverlm->x, this->fmin, g);
    }
    break;
  case SLRA_OPT_METHOD_QN:
    this->fmin = gsl_multimin_fdfminimizer_minimum(solverqn);
    if (itLog != NULL) {
      itLog->reportIteration(0, solverqn->x, this->fmin, solverqn->gradient);
    }
    break;
  case SLRA_OPT_METHOD_NM:
    this->fmin = gsl_multimin_fminimizer_minimum( solvernm );
    if (itLog != NULL) {
      itLog->reportIteration(this->iter, solvernm->x, this->fmin, NULL);
    }
    break;
  }

  while (status_dx == GSL_CONTINUE && 
	 status_grad == GSL_CONTINUE &&
	 status == GSL_SUCCESS &&
	 this->iter < this->maxiter) {
  	if (this->method == SLRA_OPT_METHOD_LM && this->maxx > 0) {
  	  if (gsl_vector_max(solverlm->x) > this->maxx || 
  	      gsl_vector_min(solverlm->x) < -this->maxx ){
  	    break;
	    }
	  }

    this->iter++;
    switch (this->method) {
    case SLRA_OPT_METHOD_LM: /* Levenberg-Marquardt */
      status = gsl_multifit_fdfsolver_iterate(solverlm);
      gsl_multifit_gradient(solverlm->J, solverlm->f, g);
      gsl_vector_scale(g, 2);

      /* check the convergence criteria */
      if (this->epsabs != 0 || this->epsrel != 0) {
        status_dx = gsl_multifit_test_delta(solverlm->dx, solverlm->x, 
	  				  this->epsabs, this->epsrel);
	  	} else {
	  	  status_dx = GSL_CONTINUE;
	  	}
      status_grad = gsl_multifit_test_gradient(g, this->epsgrad);
      gsl_blas_ddot(solverlm->f, solverlm->f, &this->fmin);
      if (itLog != NULL) {
        itLog->reportIteration(this->iter, solverlm->x, this->fmin, g);
      }
      break;
    case SLRA_OPT_METHOD_QN:
      status = gsl_multimin_fdfminimizer_iterate( solverqn );

      /* check the convergence criteria */
      status_grad = gsl_multimin_test_gradient(
          gsl_multimin_fdfminimizer_gradient(solverqn), this->epsgrad);
      status_dx = gsl_multifit_test_delta(solverqn->dx, solverqn->x, 
	 				 this->epsabs, this->epsrel);  		    
      this->fmin = gsl_multimin_fdfminimizer_minimum(solverqn);      
      if (itLog != NULL) {
        itLog->reportIteration(this->iter, solverqn->x, this->fmin, solverqn->gradient);
      }
      break;
    case SLRA_OPT_METHOD_NM:
      status = gsl_multimin_fminimizer_iterate( solvernm );
      /* check the convergence criteria */
      size = gsl_multimin_fminimizer_size( solvernm );
      status_dx = gsl_multimin_test_size( size, this->epsx );
      this->fmin = gsl_multimin_fminimizer_minimum( solvernm );
      if (itLog != NULL) {
        itLog->reportIteration(this->iter, solvernm->x, this->fmin, NULL);
      }
      break;
    }
  } 
  if (this->iter >= this->maxiter) {
    status = EITER;
  }

  switch (this->method) {
  case  SLRA_OPT_METHOD_LM:
    gsl_vector_memcpy(x_vec, solverlm->x);
    if (v != NULL) {
      gsl_multifit_covar(solverlm->J, this->epscov, v); /* ??? Different eps */
    }
    gsl_blas_ddot(solverlm->f, solverlm->f, &this->fmin);
    break;
  case SLRA_OPT_METHOD_QN:
    gsl_vector_memcpy(x_vec, solverqn->x);
    this->fmin = solverqn->f;
    break;
  case SLRA_OPT_METHOD_NM:
    gsl_vector_memcpy(x_vec, solvernm->x);
    this->fmin = solvernm->fval;
    break;
  }
  
  /* print exit information */  
  if (Log::getMaxLevel() >= Log::LOG_LEVEL_FINAL) { /* unless "off" */
    switch (status) {
    case EITER: 
      Log::lprintf("SLRA optimization terminated by reaching " 
                  "the maximum number of iterations.\n" 
                  "The result could be far from optimal.\n");
      break;
    case GSL_ETOLF:
      Log::lprintf("Lack of convergence: "
                  "progress in function value < machine EPS.\n");
      break;
    case GSL_ETOLX:
      Log::lprintf("Lack of convergence: "
                  "change in parameters < machine EPS.\n");
      break;
    case GSL_ETOLG:
      Log::lprintf("Lack of convergence: "
                  "change in gradient < machine EPS.\n");
      break;
    case GSL_ENOPROG:
      Log::lprintf("Possible lack of convergence: no progress.\n");
      break;
    }
    
    if (status_grad != GSL_CONTINUE && status_dx != GSL_CONTINUE) {
      Log::lprintf("Optimization terminated by reaching the convergence "
                  "tolerance for both X and the gradient.\n"); 
    
    } else {
      if (status_grad != GSL_CONTINUE) {
        Log::lprintf("Optimization terminated by reaching the convergence "
	            "tolerance for the gradient.\n");
      } else {
        Log::lprintf("Optimization terminated by reaching the convergence "
                    "tolerance for X.\n");
      }
    }
  }

  /* Cleanup  */
  switch (this->method) {
  case SLRA_OPT_METHOD_LM: /* LM */
    gsl_multifit_fdfsolver_free(solverlm);
    gsl_vector_free(g);
    break;
  case SLRA_OPT_METHOD_QN: /* QN */
    gsl_multimin_fdfminimizer_free(solverqn);
    break;
  case SLRA_OPT_METHOD_NM: /* NM */
    gsl_multimin_fminimizer_free(solvernm);
    gsl_vector_free(stepnm);
    break;
  }

  return GSL_SUCCESS; /* <- correct with status */
}
示例#28
0
// Relax the map
void rmap_relax(rmap_t *self, int num_cycles)
{
  int i, n;
  gsl_vector *x, *y;
  gsl_multimin_function_fdf fdf;
  gsl_multimin_fdfminimizer *s;
  double step_size, tol;
  rmap_scan_t *scan;

  // HACK
  step_size = 0.01;
  tol = 0.001;
  
  // Compute number of free variables
  n = 3 * self->num_key_scans;

  // Set the initial vector
  x = gsl_vector_alloc(n);
  for (i = 0; i < self->num_scans; i++)
  {
    scan = self->scans + i;
    if (scan->index >= 0)
    {
      gsl_vector_set(x, 3 * scan->index + 0, scan->pose.pos.x);
      gsl_vector_set(x, 3 * scan->index + 1, scan->pose.pos.y);
      gsl_vector_set(x, 3 * scan->index + 2, scan->pose.rot);
    }
  }
  
  // Allocate minimizer
  fdf.f = (double (*) (const gsl_vector*, void*)) rmap_fit_f;
  fdf.df = (void (*) (const gsl_vector*, void*, gsl_vector*)) rmap_fit_df;
  fdf.fdf = (void (*) (const gsl_vector*, void*, double*, gsl_vector*)) rmap_fit_fdf;
  fdf.n = n;
  fdf.params = self;  
  s = gsl_multimin_fdfminimizer_alloc(gsl_multimin_fdfminimizer_vector_bfgs, n);

  // Initialize minimizer
  gsl_multimin_fdfminimizer_set(s, &fdf, x, step_size, tol);

  // Optimize
  for (i = 0; i < num_cycles; i++)
  {
    if (gsl_multimin_fdfminimizer_iterate(s) != GSL_SUCCESS)
      break;
  }
  
  self->relax_err = gsl_multimin_fdfminimizer_minimum(s);
  
  // Copy corrections back to data structures
  y = gsl_multimin_fdfminimizer_x(s);
  for (i = 0; i < self->num_scans; i++)
  {
    scan = self->scans + i;
    if (scan->index >= 0)
    {
      scan->delta.pos.x = gsl_vector_get(y, 3 * scan->index + 0) - scan->pose.pos.x;
      scan->delta.pos.y = gsl_vector_get(y, 3 * scan->index + 1) - scan->pose.pos.y;
      scan->delta.rot = gsl_vector_get(y, 3 * scan->index + 2) - scan->pose.rot;
    }
  }

  // Clean up
  gsl_multimin_fdfminimizer_free(s);
  gsl_vector_free(x);

  return;
}
示例#29
0
int main(int argc, char **argv) {

#ifdef _OPENMP
  printf("ERKALE - Geometry optimization from Hel, OpenMP version, running on %i cores.\n",omp_get_max_threads());
#else
  printf("ERKALE - Geometry optimization from Hel, serial version.\n");
#endif
  print_copyright();
  print_license();
#ifdef SVNRELEASE
  printf("At svn revision %s.\n\n",SVNREVISION);
#endif
  print_hostname();

  if(argc!=2) {
    printf("Usage: $ %s runfile\n",argv[0]);
    return 0;
  }

  // Initialize libint
  init_libint_base();
  // Initialize libderiv
  init_libderiv_base();

  Timer tprog;
  tprog.print_time();

  // Parse settings
  Settings set;
  set.add_scf_settings();
  set.add_string("SaveChk","File to use as checkpoint","erkale.chk");
  set.add_string("LoadChk","File to load old results from","");
  set.add_bool("ForcePol","Force polarized calculation",false);
  set.add_bool("FreezeCore","Freeze the atomic cores?",false);
  set.add_string("Optimizer","Optimizer to use: CGFR, CGPR, BFGS, BFGS2 (default), SD","BFGS2");
  set.add_int("MaxSteps","Maximum amount of geometry steps",256);
  set.add_string("Criterion","Convergence criterion to use: LOOSE, NORMAL, TIGHT, VERYTIGHT","NORMAL");
  set.add_string("OptMovie","xyz movie to store progress in","optimize.xyz");
  set.add_string("Result","File to save optimized geometry in","optimized.xyz");
  set.set_string("Logfile","erkale_geom.log");
  set.parse(std::string(argv[1]),true);
  set.print();

  bool verbose=set.get_bool("Verbose");
  int maxiter=set.get_int("MaxSteps");
  std::string optmovie=set.get_string("OptMovie");
  std::string result=set.get_string("Result");

  // Interpret optimizer
  enum minimizer alg;
  std::string method=set.get_string("Optimizer");
  if(stricmp(method,"CGFR")==0)
    alg=gCGFR;
  else if(stricmp(method,"CGPR")==0)
    alg=gCGPR;
  else if(stricmp(method,"BFGS")==0)
    alg=gBFGS;
  else if(stricmp(method,"BFGS2")==0)
    alg=gBFGS2;
  else if(stricmp(method,"SD")==0)
    alg=gSD;
  else {
    ERROR_INFO();
    throw std::runtime_error("Unknown optimization method.\n");
  }

  // Interpret optimizer
  enum convergence crit;
  method=set.get_string("Criterion");
  if(stricmp(method,"LOOSE")==0)
    crit=LOOSE;
  else if(stricmp(method,"NORMAL")==0)
    crit=NORMAL;
  else if(stricmp(method,"TIGHT")==0)
    crit=TIGHT;
  else if(stricmp(method,"VERYTIGHT")==0)
    crit=VERYTIGHT;
  else {
    ERROR_INFO();
    throw std::runtime_error("Unknown optimization method.\n");
  }

  // Redirect output?
  std::string logfile=set.get_string("Logfile");
  if(stricmp(logfile,"stdout")!=0) {
    // Redirect stdout to file
    FILE *outstream=freopen(logfile.c_str(),"w",stdout);
    if(outstream==NULL) {
      ERROR_INFO();
      throw std::runtime_error("Unable to redirect output!\n");
    } else
      fprintf(stderr,"\n");
  }

  // Read in atoms.
  std::string atomfile=set.get_string("System");
  const std::vector<atom_t> origgeom=load_xyz(atomfile);
  std::vector<atom_t> atoms(origgeom);

  // Are any atoms fixed?
  std::vector<size_t> dofidx;
  for(size_t i=0;i<atoms.size();i++) {
    bool fixed=false;

    if(atoms[i].el.size()>3)
      if(stricmp(atoms[i].el.substr(atoms[i].el.size()-3),"-Fx")==0) {
	fixed=true;
	atoms[i].el=atoms[i].el.substr(0,atoms[i].el.size()-3);
      }

    // Add to degrees of freedom
    if(!fixed)
      dofidx.push_back(i);
  }

  // Read in basis set
  BasisSetLibrary baslib;
  std::string basfile=set.get_string("Basis");
  baslib.load_gaussian94(basfile);
  printf("\n");

  // Save to output
  save_xyz(atoms,"Initial configuration",optmovie,false);

  // Minimizer options
  opthelper_t pars;
  pars.atoms=atoms;
  pars.baslib=baslib;
  pars.set=set;
  pars.dofidx=dofidx;

  /* Starting point */
  gsl_vector *x = gsl_vector_alloc (3*dofidx.size());
  for(size_t i=0;i<dofidx.size();i++) {
    gsl_vector_set(x,3*i,atoms[dofidx[i]].x);
    gsl_vector_set(x,3*i+1,atoms[dofidx[i]].y);
    gsl_vector_set(x,3*i+2,atoms[dofidx[i]].z);
  }

  // GSL status
  int status;

  const gsl_multimin_fdfminimizer_type *T;
  gsl_multimin_fdfminimizer *s;

  gsl_multimin_function_fdf minimizer;

  minimizer.n = x->size;
  minimizer.f = calc_E;
  minimizer.df = calc_f;
  minimizer.fdf = calc_Ef;
  minimizer.params = (void *) &pars;

  if(alg==gCGFR) {
    T = gsl_multimin_fdfminimizer_conjugate_fr;
    if(verbose) printf("Using Fletcher-Reeves conjugate gradients.\n");
  } else if(alg==gCGPR) {
    T = gsl_multimin_fdfminimizer_conjugate_pr;
    if(verbose) printf("Using Polak-Ribière conjugate gradients.\n");
  } else if(alg==gBFGS) {
    T = gsl_multimin_fdfminimizer_vector_bfgs;
    if(verbose) printf("Using the BFGS minimizer.\n");
  } else if(alg==gBFGS2) {
    T = gsl_multimin_fdfminimizer_vector_bfgs2;
    if(verbose) printf("Using the BFGS2 minimizer.\n");
  } else if(alg==gSD) {
    T = gsl_multimin_fdfminimizer_steepest_descent;
    if(verbose) printf("Using the steepest descent minimizer.\n");
  } else {
    ERROR_INFO();
    throw std::runtime_error("Unsupported minimizer\n");
  }

  // Run an initial calculation
  double oldE=calc_E(x,minimizer.params);

  // Turn off verbose setting
  pars.set.set_bool("Verbose",false);
  // and load from old checkpoint
  pars.set.set_string("LoadChk",pars.set.get_string("SaveChk"));

  // Initialize minimizer
  s = gsl_multimin_fdfminimizer_alloc (T, minimizer.n);

  // Use initial step length of 0.02 bohr, and a line search accuracy
  // 1e-1 (recommended in the GSL manual for BFGS)
  gsl_multimin_fdfminimizer_set (s, &minimizer, x, 0.02, 1e-1);

  // Store old force
  arma::mat oldf=interpret_force(s->gradient);

  fprintf(stderr,"Geometry optimizer initialized in %s.\n",tprog.elapsed().c_str());
  fprintf(stderr,"Entering minimization loop with %s optimizer.\n",set.get_string("Optimizer").c_str());

  fprintf(stderr,"%4s %16s %10s %10s %9s %9s %9s %9s %s\n","iter","E","dE","dE/dEproj","disp max","disp rms","f max","f rms", "titer");

  std::vector<atom_t> oldgeom(atoms);

  bool convd=false;
  int iter;

  for(iter=1;iter<=maxiter;iter++) {
    printf("\nGeometry iteration %i\n",(int) iter);
    fflush(stdout);

    Timer titer;

    status = gsl_multimin_fdfminimizer_iterate (s);

    if (status) {
      fprintf(stderr,"GSL encountered error: \"%s\".\n",gsl_strerror(status));
      break;
    }

    // New geometry is
    std::vector<atom_t> geom=get_atoms(s->x,pars);

    // Calculate displacements
    double dmax, drms;
    get_displacement(geom, oldgeom, dmax, drms);

    // Calculate projected change of energy
    double dEproj=calculate_projection(geom,oldgeom,oldf,pars.dofidx);
    // Actual change of energy is
    double dE=s->f - oldE;

    // Switch geometries
    oldgeom=geom;
    // Save old force

    // Get forces
    double fmax, frms;
    get_forces(s->gradient, fmax, frms);

    // Save geometry step
    char comment[80];
    sprintf(comment,"Step %i",(int) iter);
    save_xyz(get_atoms(s->x,pars),comment,optmovie,true);

    // Check convergence
    bool fmaxconv=false, frmsconv=false;
    bool dmaxconv=false, drmsconv=false;

    switch(crit) {

    case(LOOSE):
      if(fmax < 2.5e-3)
	fmaxconv=true;
      if(frms < 1.7e-3)
	frmsconv=true;
      if(dmax < 1.0e-2)
	dmaxconv=true;
      if(drms < 6.7e-3)
	drmsconv=true;
      break;

    case(NORMAL):
      if(fmax < 4.5e-4)
	fmaxconv=true;
      if(frms < 3.0e-4)
	frmsconv=true;
      if(dmax < 1.8e-3)
	dmaxconv=true;
      if(drms < 1.2e-3)
	drmsconv=true;
      break;

    case(TIGHT):
      if(fmax < 1.5e-5)
	fmaxconv=true;
      if(frms < 1.0e-5)
	frmsconv=true;
      if(dmax < 6.0e-5)
	dmaxconv=true;
      if(drms < 4.0e-5)
	drmsconv=true;
      break;

    case(VERYTIGHT):
      if(fmax < 2.0e-6)
	fmaxconv=true;
      if(frms < 1.0e-6)
	frmsconv=true;
      if(dmax < 6.0e-6)
	dmaxconv=true;
      if(drms < 4.0e-6)
	drmsconv=true;
      break;

    default:
      ERROR_INFO();
      throw std::runtime_error("Not implemented!\n");
    }

    // Converged?
    const static char cconv[]=" *";

    double dEfrac;
    if(dEproj!=0.0)
      dEfrac=dE/dEproj;
    else
      dEfrac=0.0;

    fprintf(stderr,"%4d % 16.8f % .3e % .3e %.3e%c %.3e%c %.3e%c %.3e%c %s\n", (int) iter, s->f, dE, dEfrac, dmax, cconv[dmaxconv], drms, cconv[drmsconv], fmax, cconv[fmaxconv], frms, cconv[frmsconv], titer.elapsed().c_str());
    fflush(stderr);

    convd=dmaxconv && drmsconv && fmaxconv && frmsconv;

    if(convd) {
      fprintf(stderr,"Converged.\n");
      break;
    }

    // Store old energy
    oldE=s->f;
    // Store old force
    oldf=interpret_force(s->gradient);
  }

  if(convd)
    save_xyz(get_atoms(s->x,pars),"Optimized geometry",result);

  gsl_multimin_fdfminimizer_free (s);

  gsl_vector_free (x);

  if(iter==maxiter && !convd) {
    printf("Geometry convergence was not achieved!\n");
  }


  printf("Running program took %s.\n",tprog.elapsed().c_str());

  return 0;
}