Example #1
0
static VALUE rb_gsl_fminimizer_test_size(VALUE obj, VALUE ea)
{
  gsl_multimin_fminimizer *gmf = NULL;
  Need_Float(ea);
  Data_Get_Struct(obj, gsl_multimin_fminimizer, gmf);
  return INT2FIX(gsl_multimin_test_size(gmf->size, NUM2DBL(ea)));
}
Example #2
0
int optimizewavefn(int MaxIter, int Omega, int NumTerms, int qmax, int pmax, int IsTriplet, int Ordering, int Method, double alpha, double beta, double gamma)
{
	int par[7] = { Omega, NumTerms, qmax, pmax, IsTriplet, Ordering, Method };

	const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;  //gsl_multimin_fminimizer_nmsimplex2;
	gsl_multimin_fminimizer *s = NULL;
	gsl_vector *ss, *x;
	gsl_multimin_function minex_func;
	 
	int iter = 0, status;
	double size;
	
	x = gsl_vector_alloc(3);
	gsl_vector_set(x, 0, alpha);
	gsl_vector_set(x, 1, beta);
	gsl_vector_set(x, 2, gamma);
	 
	/* Set initial step sizes to 1 */
	ss = gsl_vector_alloc(3);
	gsl_vector_set_all(ss, 0.05);
	 
	/* Initialize method and iterate */
	minex_func.n = 3;
	minex_func.f = (void*)test;
	minex_func.params = par;
	 
	//s = gsl_multimin_fminimizer_alloc (T, 2);
	s = gsl_multimin_fminimizer_alloc(T, 3);
	gsl_multimin_fminimizer_set(s, &minex_func, x, ss);
	 
	do
	{
		iter++;
		status = gsl_multimin_fminimizer_iterate(s);
		   
		if (status) 
			break;
	 
		size = gsl_multimin_fminimizer_size(s);
		status = gsl_multimin_test_size(size, 1e-5);
	 
		if (status == GSL_SUCCESS) {
			printf ("converged to minimum at\n");
		}
	 
		printf ("%5d %10.5e f() = %12.7f size = %.5f\n", 
				iter,
				gsl_vector_get (s->x, 0), 
				gsl_vector_get (s->x, 1), 
				gsl_vector_get (s->x, 2), 
				s->fval, size);
	} while (status == GSL_CONTINUE && iter < MaxIter);
	   
	gsl_vector_free(x);
	gsl_vector_free(ss);
	gsl_multimin_fminimizer_free(s);
	 
	return 0;  //@TODO: How do I make this into a void subroutine?
}
Example #3
0
CAMLprim value ml_gsl_multimin_test_size(value S, value epsabs)
{
  int status;
  double size = 
    gsl_multimin_fminimizer_size(GSLMULTIMINFMINIMIZER_VAL(S));
  status = gsl_multimin_test_size(size, Double_val(epsabs));
  return Val_negbool(status);
}
Example #4
0
int
test_f(const char * desc, gsl_multimin_function *f, initpt_function initpt,
       const gsl_multimin_fminimizer_type *T)
{
  int status;
  size_t i, iter = 0;

  gsl_vector *x = gsl_vector_alloc (f->n);

  gsl_vector *step_size = gsl_vector_alloc (f->n);

  gsl_multimin_fminimizer *s;

  fcount = 0; gcount = 0;
  (*initpt) (x);

  for (i = 0; i < f->n; i++) 
    gsl_vector_set (step_size, i, 1);

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

  gsl_multimin_fminimizer_set (s, f, x, step_size);

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

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

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

      status = gsl_multimin_test_size (gsl_multimin_fminimizer_size (s),
                                       1e-3);
    }
  while (iter < 5000 && status == GSL_CONTINUE);

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

  gsl_test(status, "%s, on %s: %d iter (fn=%d), f(x)=%g",
           gsl_multimin_fminimizer_name(s),desc, iter, fcount, s->fval);

  gsl_multimin_fminimizer_free(s);
  gsl_vector_free(x);
  gsl_vector_free(step_size);

  return status;
}
void NMSimplexMinimization::minimizeEnergy(VMC &vmc)
{
    const gsl_multimin_fminimizer_type * T = gsl_multimin_fminimizer_nmsimplex2;
    gsl_multimin_fminimizer * s = nullptr;
    gsl_vector * ss, * x;
    gsl_multimin_function minex_func;

    int myrank = MPIVMC::MyRank();

    vmc_nms w(vmc, *this);

    // Starting point
    const auto nvp = static_cast<size_t>(vmc.getNVP());
    double vpar[nvp];
    vmc.getVP(vpar);

    x = gsl_vector_alloc(nvp);
    for (size_t i = 0; i < nvp; ++i) {
        gsl_vector_set(x, i, vpar[i]);
    }

    // Set initial step sizes to 1
    ss = gsl_vector_alloc(nvp);
    gsl_vector_set_all(ss, _rstart);

    // Initialize method and iterate
    minex_func.n = nvp;
    minex_func.f = vmc_cost;
    minex_func.params = &w;

    s = gsl_multimin_fminimizer_alloc(T, nvp);
    gsl_multimin_fminimizer_set(s, &minex_func, x, ss);

    size_t iter = 0;
    int status;
    do {
        status = gsl_multimin_fminimizer_iterate(s);

        if (status != 0) { break; }

        double size = gsl_multimin_fminimizer_size(s);
        status = gsl_multimin_test_size(size, _rend);

        if (myrank == 0) {
            if (status == GSL_SUCCESS) {
                std::cout << "converged to minimum at" << std::endl;
            }
            std::cout << iter << " f() = " << s->fval << " size = " << size << std::endl;
        }
        ++iter;
    } while (status == GSL_CONTINUE && (_max_n_iter <= 0 || iter < _max_n_iter));

    gsl_vector_free(x);
    gsl_vector_free(ss);
    gsl_multimin_fminimizer_free(s);
}
Example #6
0
double *Fit::fitGslMultimin(int &iterations, int &status) {
  double *result = new double[d_p];

  // declare input data
  struct FitData data = {static_cast<size_t>(d_n),
                         static_cast<size_t>(d_p),
                         d_x,
                         d_y,
                         d_y_errors,
                         this};
  gsl_multimin_function f;
  f.f = d_fsimplex;
  f.n = d_p;
  f.params = &data;

  // step size (size of the simplex)
  // can be increased for faster convergence
  gsl_vector *ss = gsl_vector_alloc(f.n);
  gsl_vector_set_all(ss, 10.0);

  // initialize minimizer
  const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;
  gsl_multimin_fminimizer *s_min = gsl_multimin_fminimizer_alloc(T, f.n);
  gsl_multimin_fminimizer_set(s_min, &f, d_param_init, ss);

  // iterate minimization algorithm
  for (iterations = 0; iterations < d_max_iterations; iterations++) {
    status = gsl_multimin_fminimizer_iterate(s_min);
    if (status) break;

    double size = gsl_multimin_fminimizer_size(s_min);
    status = gsl_multimin_test_size(size, d_tolerance);
    if (status != GSL_CONTINUE) break;
  }

  // grab results
  for (int i = 0; i < d_p; i++) result[i] = gsl_vector_get(s_min->x, i);
  chi_2 = s_min->fval;
  gsl_matrix *J = gsl_matrix_alloc(d_n, d_p);
  d_df(s_min->x, (void *)f.params, J);
  gsl_multifit_covar(J, 0.0, covar);
  if (d_y_error_source == UnknownErrors) {
    // multiply covar by variance of residuals, which is used as an estimate for
    // the
    // statistical errors (this relies on the Y errors being set to 1.0)
    gsl_matrix_scale(covar, chi_2 / (d_n - d_p));
  }

  // free previously allocated memory
  gsl_matrix_free(J);
  gsl_multimin_fminimizer_free(s_min);
  gsl_vector_free(ss);

  return result;
}
Example #7
0
double expfit::findmle(double &mleintercept, double &mlelambda, double &mlesigma2) {
    size_t iter = 0;
    int status;

    const gsl_multimin_fminimizer_type *T;
    gsl_multimin_fminimizer *s;
    gsl_vector *x;
    gsl_vector *steps;
    gsl_multimin_function my_func;

    my_func.n = 2;
    my_func.f = neglogd;
    my_func.params = this;
    x = gsl_vector_alloc (2);
    steps = gsl_vector_alloc (2);
    gsl_vector_set (x, 0, 0.5);
    gsl_vector_set (x, 1, 100.0);
    gsl_vector_set (steps, 0, 0.01);
    gsl_vector_set (steps, 1, 10.0);
    T = gsl_multimin_fminimizer_nmsimplex;
    s = gsl_multimin_fminimizer_alloc (T, 2);
         
    gsl_multimin_fminimizer_set (s, &my_func, x, steps);

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

        if (status)
            break;

        status = gsl_multimin_test_size(gsl_multimin_fminimizer_size(s),1e-3);

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

        if ( io::debug >= 1){
            printf ("%5d %.5f %.5f %10.5f\n", iter,
                    gsl_vector_get (s->x, 0), 
                    gsl_vector_get (s->x, 1), 
                    s->fval);
         }

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


    mleintercept = gsl_vector_get(s->x,0);
    mlelambda = gsl_vector_get(s->x,1);
    mlesigma2 =  s->fval;

    gsl_multimin_fminimizer_free (s);
    gsl_vector_free (x);
}
int main(void) {
	double par[5] = { 1.0, 2.0, 10.0, 20.0, 30.0 };

	const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex2;
	gsl_multimin_fminimizer *s = NULL;
	gsl_vector *ss, *x;
	gsl_multimin_function minex_func;

	size_t iter = 0;
	int status;
	double size;

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

	/* Set initial step sizes to 1 */
	ss = gsl_vector_alloc(2);
	gsl_vector_set_all(ss, 1.0);

	/* Initialize method and iterate */
	minex_func.n = 2;
	minex_func.f = my_f;
	minex_func.params = par;

	s = gsl_multimin_fminimizer_alloc(T, 2);
	gsl_multimin_fminimizer_set(s, &minex_func, x, ss);

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

		if (status)
			break;

		size = gsl_multimin_fminimizer_size(s);
		status = gsl_multimin_test_size(size, 1e-2);

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

		printf("%5d %10.3e %10.3e f() = %7.3f size = %.3f\n", iter,
				gsl_vector_get(s->x, 0), gsl_vector_get(s->x, 1), s->fval,
				size);
	} while (status == GSL_CONTINUE && iter < 100);

	gsl_vector_free(x);
	gsl_vector_free(ss);
	gsl_multimin_fminimizer_free(s);

	return EXIT_SUCCESS;
}
Example #9
0
gsl_multimin_fminimizer * Fit::fitSimplex(gsl_multimin_function f, int &iterations, int &status)
{
	const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;

	//size of the simplex
	gsl_vector *ss;
	//initial vertex size vector
	ss = gsl_vector_alloc (f.n);
	//set all step sizes to 1 can be increased to converge faster
	gsl_vector_set_all (ss, 10.0);

	gsl_multimin_fminimizer *s_min = gsl_multimin_fminimizer_alloc (T, f.n);
	status = gsl_multimin_fminimizer_set (s_min, &f, d_param_init, ss);
	double size;
	size_t iter = 0;
	bool inRange = true;
	for (int i=0; i<d_p; i++){
		double p = gsl_vector_get(d_param_init, i);
		d_results[i] = p;
		if (p < d_param_range_left[i] || p > d_param_range_right[i]){
			inRange = false;
			break;
		}
	}

	do{
		iter++;
		status = gsl_multimin_fminimizer_iterate (s_min);

		if (status)
			break;

        for (int i=0; i<d_p; i++){
			double p = gsl_vector_get(s_min->x, i);
			if (p < d_param_range_left[i] || p > d_param_range_right[i]){
				inRange = false;
				break;
			}
		}
		if (!inRange)
			break;

		for (int i=0; i<d_p; i++)
			d_results[i] = gsl_vector_get(s_min->x, i);

		size = gsl_multimin_fminimizer_size (s_min);
		status = gsl_multimin_test_size (size, d_tolerance);
	}
	while (inRange && status == GSL_CONTINUE && (int)iter < d_max_iterations);

	iterations = iter;
	gsl_vector_free(ss);
	return s_min;
}
Example #10
0
int cis_data::learnBetaParameters(vector < double > & pval, double & beta_shape1, double & beta_shape2) {

	//Set starting point to moment matching estimates
	gsl_vector * x = gsl_vector_alloc (2);
	gsl_vector_set (x, 0, beta_shape1);
	gsl_vector_set (x, 1, beta_shape2);

	//Set initial step sizes to shape1 and shape2 scales
	gsl_vector * ss = gsl_vector_alloc (2);
	gsl_vector_set (ss, 0, beta_shape1/10);
	gsl_vector_set (ss, 1, beta_shape2/10);

	//Initialize method and iterate
	double par [3];
	par[0] = 0.0;
	par[1] = 0.0;
	for (int e = 0 ; e < pval.size(); e ++) {
		if (pval[e] == 1.0) pval[e] = 0.99999999;
		par[0] += log (pval[e]);
		par[1] += log (1 - pval[e]);
	}
	par[2] = pval.size();
	gsl_multimin_function minex_func;
	minex_func.n = 2;
	minex_func.f = cis_betaLogLikelihood;
	minex_func.params = par;

	//Initialize optimization machinery
	const gsl_multimin_fminimizer_type * T = gsl_multimin_fminimizer_nmsimplex2;
	gsl_multimin_fminimizer * s = gsl_multimin_fminimizer_alloc (T, 2);
	gsl_multimin_fminimizer_set (s, &minex_func, x, ss);

	//Optimization iteration
	size_t iter = 0;
	int status;
	double size;
	do {
		iter++;
		status = gsl_multimin_fminimizer_iterate(s);
		if (status) break;
		size = gsl_multimin_fminimizer_size (s);
		status = gsl_multimin_test_size (size, 0.01);
	} while (status == GSL_CONTINUE && iter < 1000);

	//Output new beta shape values
	beta_shape1 = gsl_vector_get (s->x, 0);
	beta_shape2 = gsl_vector_get (s->x, 1);

	//Free allocated memory
	gsl_vector_free(x);
	gsl_vector_free(ss);
	gsl_multimin_fminimizer_free (s);
	return (status == GSL_SUCCESS);
}
Example #11
0
/* estimateDelta: estimate pi, delta, and epsilon using 
 * the Nelder-Mead Simplex algorithm; code adapted 
 * from Galassi, M., Davies, J., Theiler, J., Gough, B., 
 * Jungman, G., Booth, M., Rossi, F. (2005). GNU 
 * Scientific Library Reference Manual. Edition 1.6, 
 * for GSL Version 1.6, 17 March 2005, p 472f.
 */
Result *estimateDelta(Node **profilePairs, int numProfiles, Args *args, Result *result, int dist){
  const gsl_multimin_fminimizer_type *T;
  gsl_multimin_fminimizer *s;
  gsl_vector *ss, *x;
  gsl_multimin_function minex_func;
  size_t iter;
  int status, numPara;
  double size;

  globalProfilePairs = profilePairs;
  globalNumProfiles = numProfiles;
  T =  gsl_multimin_fminimizer_nmsimplex;
  s = NULL;
  iter = 0;
  numPara = 1; /* one parameter estimation */
  globalPi = result->pi;
  globalEpsilon = result->ee;
  globalDist = dist;
  /* initialize vertex size vector */
  ss = gsl_vector_alloc(numPara);
  /* set all step sizes */
  gsl_vector_set_all(ss, args->s);
  /* starting point */
  x = gsl_vector_alloc(numPara);
  gsl_vector_set(x, 0, args->D);
  /* initialize method and iterate */
  minex_func.f = &myF;
  minex_func.n = numPara;
  minex_func.params = (void *)NULL;
  s = gsl_multimin_fminimizer_alloc(T, numPara);
  gsl_multimin_fminimizer_set(s, &minex_func, x, ss);
  do{
    iter++;
    status = gsl_multimin_fminimizer_iterate(s);
    if(status)
      break;
    size = gsl_multimin_fminimizer_size(s);
    status = gsl_multimin_test_size(size, args->t);
  }while(status == GSL_CONTINUE && iter < args->i);
  if(status != GSL_SUCCESS)
    printf("WARNING: Estimation of \\Delta failed: %d\n",status);
  result->de = gsl_vector_get(s->x, 0);
  result->l = s->fval;
  result->i = iter;
  result->rh = rhoFromDelta(result->pi,result->de)/dist;
  conf(args, result);
  result->rLo = rhoFromDelta(result->pi,result->dUp)/dist;
  result->rUp = rhoFromDelta(result->pi,result->dLo)/dist;
  gsl_vector_free(x);
  gsl_vector_free(ss);
  gsl_multimin_fminimizer_free(s);
  /* freeMlComp(); */
  return result;
}
int Minimizer<dimension>::minimize(const double start[dimension])
{
   assert(function && "Minimizer<dimension>::minimize: function pointer"
          " must not be zero!");

   gsl_multimin_fminimizer *minimizer;
   gsl_multimin_function minex_func;

   // Set starting point
   for (std::size_t i = 0; i < dimension; i++)
      gsl_vector_set(minimum_point, i, start[i]);

   // Set initial step sizes
   gsl_vector_set_all(step_size, initial_step_size);

   // Initialize method and iterate
   minex_func.n = dimension;
   minex_func.f = function;
   minex_func.params = parameters;

   minimizer = gsl_multimin_fminimizer_alloc(solver_type, dimension);
   gsl_multimin_fminimizer_set(minimizer, &minex_func, minimum_point, step_size);

   size_t iter = 0;
   int status;

   do {
      iter++;
      status = gsl_multimin_fminimizer_iterate(minimizer);

      if (status)
         break;

      const double size = gsl_multimin_fminimizer_size(minimizer);
      status = gsl_multimin_test_size(size, precision);

#ifdef ENABLE_VERBOSE
      print_state(minimizer, iter);
#endif
   } while (status == GSL_CONTINUE && iter < max_iterations);

#ifdef ENABLE_VERBOSE
   printf("\tMinimization status = %s\n", gsl_strerror(status));
#endif

   // save minimum point and function value
   gsl_vector_memcpy(minimum_point, minimizer->x);
   minimum_value = minimizer->fval;

   gsl_multimin_fminimizer_free(minimizer);

   return status;
}
Example #13
0
static PyObject*
PyGSL_multimin_test_size(PyObject * self, PyObject *args)
{
     double size, epsabs;
     int flag = GSL_EFAILED;
     FUNC_MESS_BEGIN();
     if (0==PyArg_ParseTuple(args,"dd", &size, &epsabs))
	  return NULL;     
     flag = gsl_multimin_test_size(size, epsabs);
     FUNC_MESS_END();
     return PyGSL_ERROR_FLAG_TO_PYINT(flag);
     
}
Example #14
0
static PyObject* 
PyGSL_multimin_test_size_method(PyGSL_solver *self, PyObject *args) 
{
     int flag=GSL_EFAILED;
     double epsabs;

     FUNC_MESS_BEGIN();

     if (0==PyArg_ParseTuple(args,"d", &epsabs))
	  return NULL;            
     flag = gsl_multimin_test_size(gsl_multimin_fminimizer_size(self->solver), epsabs);
     FUNC_MESS_END();
     return PyGSL_ERROR_FLAG_TO_PYINT(flag);
}
Example #15
0
/**
 * Do one iteration.
 * @return :: true if iterations to be continued, false if they can stop
 */
bool SimplexMinimizer::iterate(size_t) {
  int status = gsl_multimin_fminimizer_iterate(m_gslSolver);
  if (status) {
    m_errorString = gsl_strerror(status);
    return false;
  }
  double size = gsl_multimin_fminimizer_size(m_gslSolver);
  status = gsl_multimin_test_size(size, m_epsabs);
  if (status != GSL_CONTINUE) {
    m_errorString = gsl_strerror(status);
    return false;
  }
  return true;
}
Example #16
0
double GSLOptimizer::optimize(unsigned int iter,
                              const gsl_multimin_fminimizer_type*t,
                              double ms, double mxs) {
  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_fminimizer *s=gsl_multimin_fminimizer_alloc (t, n);

  gsl_vector *x= gsl_vector_alloc(get_dimension());
  update_state(x);
  gsl_vector *ss= gsl_vector_alloc(get_dimension());
  gsl_vector_set_all(ss, mxs);

  gsl_multimin_function f= internal::create_f_function_data(this);
  gsl_multimin_fminimizer_set (s, &f, x, ss);
  try {
    int status;
    do {
      --iter;
      //update_state(x);
      status = gsl_multimin_fminimizer_iterate(s);
      if (status) {
        IMP_LOG(TERSE, "Ending optimization because of state " << s
                << std::endl);
        break;
      }
      double sz= gsl_multimin_fminimizer_size(s);
      status= gsl_multimin_test_size(sz, ms);
      update_states();
      if (status == GSL_SUCCESS) {
        IMP_LOG(TERSE, "Ending optimization because of small size " << sz
                << std::endl);
        break;
      }
    } while (status == GSL_CONTINUE && iter >0);
  } catch (AllDone){
  }
  gsl_vector *ret=gsl_multimin_fminimizer_x (s);
  best_score_=gsl_multimin_fminimizer_minimum (s);
  write_state(ret);
  gsl_multimin_fminimizer_free (s);
  gsl_vector_free (x);
  return best_score_;
}
Example #17
0
static void func_iteration(gsl_multimin_fminimizer *s){
  size_t iter = 0;
  int status;
  double size;
  do{
    iter++;
    status = gsl_multimin_fminimizer_iterate(s);  /* 繰り返し計算を1回行う。予期しない問題が発生した場合はエラーコードを返す。 */
    if(status) break;
    size = gsl_multimin_fminimizer_size(s);       /* sのその時点での最小点の最良推定値を返す */
    status = gsl_multimin_test_size(size, 1e-3);  /* sizeが閾値(1e-3)より小さければGSL_SUCCESS を、そうでなければGSL_CONTINUEを返す。 */
    if(status == GSL_SUCCESS){ LOG("converged to minimum at\n");}
    LOG("%5zd p=%.5f n=%.5f p0=%.5f f() = %10.5f size = %f\n", iter, gsl_vector_get(s->x, 0), gsl_vector_get(s->x, 1), gsl_vector_get(s->x, 2), gsl_multimin_fminimizer_minimum(s), size);
  }while(status == GSL_CONTINUE && iter < 1000);

  return;
}
Example #18
0
int MultiDimMinimizer::Main(void)
{
	double size;
	fminimizer_type = gsl_multimin_fminimizer_nmsimplex; 
	s = gsl_multimin_fminimizer_alloc (fminimizer_type, np);
	gsl_multimin_fminimizer_set (s, &F, x, ss);
	do
	{
		iter++;
		status = gsl_multimin_fminimizer_iterate(s);
		if (status) break;
		size = gsl_multimin_fminimizer_size (s);
		status = gsl_multimin_test_size (size, epsabs);
	}
	while (status == GSL_CONTINUE && iter < max_iter);
	return status;
}
void multidim_minimization_simplex()
{
	// Position of the minimum (1,2)
	double par[2] = { 1.0, 2.0 };

	gsl_multimin_function my_func;
	my_func.f = &local::my_f;
	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);
	gsl_vector *step_size = gsl_vector_alloc(2);
	gsl_vector_set(step_size, 0, 0.01);
	gsl_vector_set(step_size, 1, 0.01);

	const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;
	gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc(T, 2);
	gsl_multimin_fminimizer_set(s, &my_func, x, step_size);

	size_t iter = 0;
	int status;
	do
	{
		++iter;
		status = gsl_multimin_fminimizer_iterate(s);
		if (status)
			break;
		status = gsl_multimin_test_size(s->size, 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->fval);
	} while (status == GSL_CONTINUE && iter < 1000);

	//
	gsl_multimin_fminimizer_free(s);
	gsl_vector_free(x);
}
Example #20
0
double GSL_Minimization_Simplex (Parameter_Fitting * F,
				 gsl_vector * Initial_Guess,
				 gsl_vector * Solution,
				 double ( * Function )( const gsl_vector * , void * ) )
{
  int i;
  //int key;
  double value;

  Parameter_Space * Space  = F->Space;
  // Parameter_Model * P      = F->P;

  const gsl_multimin_fminimizer_type *T =
    gsl_multimin_fminimizer_nmsimplex;
  gsl_multimin_fminimizer *s = NULL;
  gsl_vector *ss;
  gsl_multimin_function minex_func;

  size_t iter = 0;
  int status;
  double size;

  int No_of_PARAMETERS     = Space->No_of_PARAMETERS;
  double TOLERANCE         = Space->TOLERANCE;
  int MAX_No_of_ITERATIONS = Space->MAX_No_of_ITERATIONS;

  /* Set initial step sizes */
  ss = gsl_vector_alloc ( No_of_PARAMETERS );
  // gsl_vector_set_all (ss, 0.01);
  gsl_vector_memcpy (ss, Space->Accuracy );

  /* Initialize method and iterate */

  if ( F->Verbose == 1 ) // Rprintf("No_of_PARAMETERS = %d\n", No_of_PARAMETERS);
    Rprintf("No_of_PARAMETERS = %d\n", No_of_PARAMETERS);

  minex_func.n = No_of_PARAMETERS;
  minex_func.f = Function;
  minex_func.params = (void *)F;

  //s = gsl_multimin_fminimizer_alloc (T, Space->No_of_PARAMETERS);
  s = gsl_multimin_fminimizer_alloc (T, No_of_PARAMETERS);
  gsl_multimin_fminimizer_set (s, &minex_func, Initial_Guess, ss);

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

      if (status)
        break;

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

       if (F->Verbose == 1) {
	 if (status == GSL_SUCCESS)
	   {
	     // Rprintf("converged to minimum at\n");
	     Rprintf("converged to minimum at\n");
	   }

	 // Rprintf("%5d ", (int)iter);
	 Rprintf("%5d ", (int)iter);
	 // for( i=0; i<Space->No_of_PARAMETERS; i++ ) {
	 // key  = Space->Parameter_Index[i];
	 // Rprintf("%s = %10.3e\t", P->Symbol[key], gsl_vector_get (s->x, i) );

	 for( i=0; i<No_of_PARAMETERS; i++ ) {
	   if (i == 0) //printf("Colonization = %10.3e; ", gsl_vector_get (s->x, i) );
	     Rprintf("Colonization (C) = %10.3e; ", gsl_vector_get (s->x, i) );
	   if (i == 1) //printf("Extinction   = %10.3e; ", gsl_vector_get (s->x, i) );
	     Rprintf("Extinction (E)  = %10.3e; ", gsl_vector_get (s->x, i) );
	   if (i == 2) //printf("Detectability = %10.3e; ", gsl_vector_get (s->x, i) );
	     Rprintf("Detectability (D) = %10.3e; ", gsl_vector_get (s->x, i) );
	   if (i == 3) //printf("Phi_0   = %10.3e\t", gsl_vector_get (s->x, i) );
	     Rprintf("Phi_0 (P)  = %10.3e\t", gsl_vector_get (s->x, i) );
	 }
	 //printf("f() = %7.3f size = %.3f\n", s->fval, size);
	 Rprintf("NLL(C,E,D,P|Data) = %7.3f size = %.3f\n", s->fval, size);
       }

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

  gsl_vector_memcpy (Solution, s->x );
  value = s->fval; // Min Value !!!

  gsl_vector_free(ss);
  gsl_multimin_fminimizer_free (s);

  //return status;
  return( value );
}
Example #21
0
Parameters CalibratorGaussian::train(const std::vector<ObsEns>& iData) const {
   if(iData.size() == 0) {
      std::cout << "No data to train on...";
      return Parameters();
   }
   std::vector<float> obs, mean, spread;
   obs.resize(iData.size(), Util::MV);
   mean.resize(iData.size(), Util::MV);
   spread.resize(iData.size(), Util::MV);
   // Compute predictors in model
   for(int i = 0; i < iData.size(); i++) {
      obs[i] = iData[i].first;
      std::vector<float> ens = iData[i].second;
      mean[i] = Util::calculateStat(ens, Util::StatTypeMean);
      spread[i] = Util::calculateStat(ens, Util::StatTypeStd);
   }

   int N = mean.size();
   double* p = new double[1+3*N]; 
   p[0] = N;
   for(int n = 0; n < N; n++) {
      p[1+n] = obs[n];
      p[1+n+N] = mean[n];
      p[1+n+2*N] = spread[n];
   }

   /*
   gsl_multimin_function_fdf my_func;
   double p[8] = { 0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1 }; 

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

   */

   gsl_multimin_function my_func;
   my_func.n = mNumParameters;
   my_func.f = &CalibratorGaussian::my_f;
   my_func.params = (void *)p;

   // Initialize parameters
   gsl_vector* x = gsl_vector_alloc (mNumParameters);
   gsl_vector_set (x, 0, 0);
   gsl_vector_set (x, 1, 1);

   const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;
   gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc (T, mNumParameters);
   gsl_vector *ss = gsl_vector_alloc (mNumParameters);
   gsl_vector_set_all (ss, 0.01);
   gsl_multimin_fminimizer_set (s, &my_func, x, ss);

   int iter = 0;
   int status = GSL_CONTINUE;
   do
   {
      iter++;
      gsl_multimin_fminimizer_iterate (s);

      double size = gsl_multimin_fminimizer_size (s);
      status = gsl_multimin_test_size (size, mLogLikelihoodTolerance);
      /*
      for(int i = 0; i < 4; i++) {
         std::cout << gsl_vector_get (s->x, i) << " ";
      }
      std::cout << std::endl;
      */

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

   std::vector<float> values(mNumParameters,0);
   for(int i = 0; i < mNumParameters; i++) {
      values[i] = gsl_vector_get (s->x, i);
   }

   // gsl_multimin_fdfminimizer_free (s);
   gsl_multimin_fminimizer_free (s);
   gsl_vector_free (x);
   gsl_vector_free (ss);

   Parameters par(values);

   std::cout << "Num of iterations: " << iter << std::endl;
   return par;
}
Example #22
0
static void optimize_remd_parameters(t_remd_data *d, int maxiter,
                                     real tol)
{
    real   size, d2;
    int    iter   = 0;
    int    status = 0;
    int    i;

    const gsl_multimin_fminimizer_type *T;
    gsl_multimin_fminimizer            *s;

    gsl_vector                         *x, *dx;
    gsl_multimin_function               my_func;

    my_func.f      = &my_f;
    my_func.n      = d->nparams;
    my_func.params = (void *) d;

    /* Starting point */
    x = gsl_vector_alloc (my_func.n);
    for (i = 0; (i < my_func.n); i++)
    {
        gsl_vector_set (x, i, d->params[i]);
    }

    /* Step size, different for each of the parameters */
    dx = gsl_vector_alloc (my_func.n);
    for (i = 0; (i < my_func.n); i++)
    {
        gsl_vector_set (dx, i, 0.1*d->params[i]);
    }

    T = gsl_multimin_fminimizer_nmsimplex;
    s = gsl_multimin_fminimizer_alloc (T, my_func.n);

    gsl_multimin_fminimizer_set (s, &my_func, x, dx);
    gsl_vector_free (x);
    gsl_vector_free (dx);

    printf ("%5s", "Iter");
    for (i = 0; (i < my_func.n); i++)
    {
        printf(" %12s", epnm(my_func.n, i));
    }
    printf (" %12s %12s\n", "NM Size", "Chi2");

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

        if (status != 0)
        {
            gmx_fatal(FARGS, "Something went wrong in the iteration in minimizer %s",
                      gsl_multimin_fminimizer_name(s));
        }

        d2     = gsl_multimin_fminimizer_minimum(s);
        size   = gsl_multimin_fminimizer_size(s);
        status = gsl_multimin_test_size(size, tol);

        if (status == GSL_SUCCESS)
        {
            printf ("Minimum found using %s at:\n",
                    gsl_multimin_fminimizer_name(s));
        }

        printf ("%5d", iter);
        for (i = 0; (i < my_func.n); i++)
        {
            printf(" %12.4e", gsl_vector_get (s->x, i));
        }
        printf (" %12.4e %12.4e\n", size, d2);
    }
    while ((status == GSL_CONTINUE) && (iter < maxiter));

    gsl_multimin_fminimizer_free (s);
}
int main(int argc, char *argv[]) {
    FILE *fpin;
    FILE *fpout;
    double *input_data[2];
    int nchan;
    gsl_vector *x;
    gsl_vector *step_size;
    const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;
    gsl_multimin_fminimizer *s = NULL;
    gsl_multimin_function minex_func;
    double size;
    const double eps = 1.0e-6;
    double *model_spectrum;
    int i;
    int status;

    if(argc!=12) {
        fprintf(stderr, "Usage: %s <inputfilename> <frequency> <vmin> <vmax> <tau_core> <tau_env> <vlsr> <vin> <sigma> <tpeak> <outputfile>\n", argv[0]);
        exit(1);
    }

    fpin = fopen(argv[1],"r");
    nchan = read_data(fpin,2,132,input_data);
    fclose(fpin);

    x = gsl_vector_alloc(6);
    gsl_vector_set(x,0,atof(argv[5]));
    gsl_vector_set(x,1,atof(argv[6]));
    gsl_vector_set(x,2,atof(argv[7]));
    gsl_vector_set(x,3,atof(argv[8]));
    gsl_vector_set(x,4,atof(argv[9]));
    gsl_vector_set(x,5,atof(argv[10]));
    step_size = gsl_vector_alloc(6);
    gsl_vector_set(step_size,0,0.1);
    gsl_vector_set(step_size,1,0.1);
    gsl_vector_set(step_size,2,0.005);
    gsl_vector_set(step_size,3,0.005);
    gsl_vector_set(step_size,4,0.005);
    gsl_vector_set(step_size,5,0.05);

    minex_func.f = hill6core_gsl;
    minex_func.n = 6;
    minex_func.params = NULL;

    hill6core_init(nchan,input_data[0],input_data[1],atof(argv[2]),atof(argv[3]),atof(argv[4]));

    s = gsl_multimin_fminimizer_alloc(T,6);
    gsl_multimin_fminimizer_set(s,&minex_func,x,step_size);

    i=0;
    do {
        i++;
        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) {
            printf("converged in %d iterations\n", i);
        }

    } while(status==GSL_CONTINUE && i<MAXITER);

    if(status!=GSL_SUCCESS) {
        printf("Failed to converge after %d iterations\n", i);
        exit(1);
    }

    fpout = fopen(argv[11],"w");
    fprintf(fpout,"# Tau_c: %g\n",gsl_vector_get(s->x,0));
    fprintf(fpout,"# Tau_e: %g\n",gsl_vector_get(s->x,1));
    fprintf(fpout,"# Vlsr:  %g\n",gsl_vector_get(s->x,2));
    fprintf(fpout,"# Vin:   %g\n",gsl_vector_get(s->x,3));
    fprintf(fpout,"# sigma: %g\n",gsl_vector_get(s->x,4));
    fprintf(fpout,"# Tpeak: %g\n",gsl_vector_get(s->x,5));
    fprintf(fpout,"# Attained Chisq: %g\n",hill6core_gsl(s->x,NULL));

    model_spectrum = hill6core_getfit();

    for(i=0; i<nchan; i++) {
        fprintf(fpout,"%g\t%g\t%g\n", input_data[0][i],input_data[1][i],model_spectrum[i]);
    }
    fclose(fpout);

    gsl_vector_free(x);
    gsl_vector_free(step_size);
    gsl_multimin_fminimizer_free(s);
    hill6core_free();
    free(input_data[0]);
    free(input_data[1]);

    exit(0);
}
Example #24
0
/** Executes the algorithm
 *
 *  @throw runtime_error Thrown if algorithm cannot execute
 */
void Fit1D::exec() {

  // Custom initialization
  prepare();

  // check if derivative defined in derived class
  bool isDerivDefined = true;
  gsl_matrix *M = NULL;
  try {
    const std::vector<double> inTest(m_parameterNames.size(), 1.0);
    std::vector<double> outTest(m_parameterNames.size());
    const double xValuesTest = 0;
    JacobianImpl J;
    M = gsl_matrix_alloc(m_parameterNames.size(), 1);
    J.setJ(M);
    // note nData set to zero (last argument) hence this should avoid further
    // memory problems
    functionDeriv(&(inTest.front()), &J, &xValuesTest, 0);
  } catch (Exception::NotImplementedError &) {
    isDerivDefined = false;
  }
  gsl_matrix_free(M);

  // Try to retrieve optional properties
  int histNumber = getProperty("WorkspaceIndex");
  const int maxInterations = getProperty("MaxIterations");

  // Get the input workspace
  MatrixWorkspace_const_sptr localworkspace = getProperty("InputWorkspace");

  // number of histogram is equal to the number of spectra
  const size_t numberOfSpectra = localworkspace->getNumberHistograms();
  // Check that the index given is valid
  if (histNumber >= static_cast<int>(numberOfSpectra)) {
    g_log.warning("Invalid Workspace index given, using first Workspace");
    histNumber = 0;
  }

  // Retrieve the spectrum into a vector
  const MantidVec &XValues = localworkspace->readX(histNumber);
  const MantidVec &YValues = localworkspace->readY(histNumber);
  const MantidVec &YErrors = localworkspace->readE(histNumber);

  // Read in the fitting range data that we were sent
  double startX = getProperty("StartX");
  double endX = getProperty("EndX");
  // check if the values had been set, otherwise use defaults
  if (isEmpty(startX)) {
    startX = XValues.front();
    modifyStartOfRange(startX); // does nothing by default but derived class may
                                // provide a more intelligent value
  }
  if (isEmpty(endX)) {
    endX = XValues.back();
    modifyEndOfRange(endX); // does nothing by default but derived class may
                            // previde a more intelligent value
  }

  int m_minX;
  int m_maxX;

  // Check the validity of startX
  if (startX < XValues.front()) {
    g_log.warning("StartX out of range! Set to start of frame.");
    startX = XValues.front();
  }
  // Get the corresponding bin boundary that comes before (or coincides with)
  // this value
  for (m_minX = 0; XValues[m_minX + 1] < startX; ++m_minX) {
  }

  // Check the validity of endX and get the bin boundary that come after (or
  // coincides with) it
  if (endX >= XValues.back() || endX < startX) {
    g_log.warning("EndX out of range! Set to end of frame");
    endX = XValues.back();
    m_maxX = static_cast<int>(YValues.size());
  } else {
    for (m_maxX = m_minX; XValues[m_maxX] < endX; ++m_maxX) {
    }
  }

  afterDataRangedDetermined(m_minX, m_maxX);

  // create and populate GSL data container warn user if l_data.n < l_data.p
  // since as a rule of thumb this is required as a minimum to obtained
  // 'accurate'
  // fitting parameter values.

  FitData l_data(this, getProperty("Fix"));

  l_data.n =
      m_maxX -
      m_minX; // m_minX and m_maxX are array index markers. I.e. e.g. 0 & 19.
  if (l_data.n == 0) {
    g_log.error("The data set is empty.");
    throw std::runtime_error("The data set is empty.");
  }
  if (l_data.n < l_data.p) {
    g_log.error(
        "Number of data points less than number of parameters to be fitted.");
    throw std::runtime_error(
        "Number of data points less than number of parameters to be fitted.");
  }
  l_data.X = new double[l_data.n];
  l_data.sigmaData = new double[l_data.n];
  l_data.forSimplexLSwrap = new double[l_data.n];
  l_data.parameters = new double[nParams()];

  // check if histogram data in which case use mid points of histogram bins

  const bool isHistogram = localworkspace->isHistogramData();
  for (unsigned int i = 0; i < l_data.n; ++i) {
    if (isHistogram)
      l_data.X[i] =
          0.5 * (XValues[m_minX + i] +
                 XValues[m_minX + i + 1]); // take mid-point if histogram bin
    else
      l_data.X[i] = XValues[m_minX + i];
  }

  l_data.Y = &YValues[m_minX];

  // check that no error is negative or zero
  for (unsigned int i = 0; i < l_data.n; ++i) {
    if (YErrors[m_minX + i] <= 0.0) {
      l_data.sigmaData[i] = 1.0;
    } else
      l_data.sigmaData[i] = YErrors[m_minX + i];
  }

  // create array of fitted parameter. Take these to those input by the user.
  // However, for doing the
  // underlying fitting it might be more efficient to actually perform the
  // fitting on some of other
  // form of the fitted parameters. For instance, take the Gaussian sigma
  // parameter. In practice it
  // in fact more efficient to perform the fitting not on sigma but 1/sigma^2.
  // The methods
  // modifyInitialFittedParameters() and modifyFinalFittedParameters() are used
  // to allow for this;
  // by default these function do nothing.

  m_fittedParameter.clear();
  for (size_t i = 0; i < nParams(); i++) {
    m_fittedParameter.push_back(getProperty(m_parameterNames[i]));
  }
  modifyInitialFittedParameters(
      m_fittedParameter); // does nothing except if overwritten by derived class
  for (size_t i = 0; i < nParams(); i++) {
    l_data.parameters[i] = m_fittedParameter[i];
  }

  // set-up initial guess for fit parameters

  gsl_vector *initFuncArg;
  initFuncArg = gsl_vector_alloc(l_data.p);

  for (size_t i = 0, j = 0; i < nParams(); i++) {
    if (l_data.active[i])
      gsl_vector_set(initFuncArg, j++, m_fittedParameter[i]);
  }

  // set-up GSL container to be used with GSL simplex algorithm

  gsl_multimin_function gslSimplexContainer;
  gslSimplexContainer.n = l_data.p; // n here refers to number of parameters
  gslSimplexContainer.f = &gsl_costFunction;
  gslSimplexContainer.params = &l_data;

  // set-up GSL least squares container

  gsl_multifit_function_fdf f;
  f.f = &gsl_f;
  f.df = &gsl_df;
  f.fdf = &gsl_fdf;
  f.n = l_data.n;
  f.p = l_data.p;
  f.params = &l_data;

  // set-up remaining GSL machinery for least squared

  const gsl_multifit_fdfsolver_type *T = gsl_multifit_fdfsolver_lmsder;
  gsl_multifit_fdfsolver *s = NULL;
  if (isDerivDefined) {
    s = gsl_multifit_fdfsolver_alloc(T, l_data.n, l_data.p);
    gsl_multifit_fdfsolver_set(s, &f, initFuncArg);
  }

  // set-up remaining GSL machinery to use simplex algorithm

  const gsl_multimin_fminimizer_type *simplexType =
      gsl_multimin_fminimizer_nmsimplex;
  gsl_multimin_fminimizer *simplexMinimizer = NULL;
  gsl_vector *simplexStepSize = NULL;
  if (!isDerivDefined) {
    simplexMinimizer = gsl_multimin_fminimizer_alloc(simplexType, l_data.p);
    simplexStepSize = gsl_vector_alloc(l_data.p);
    gsl_vector_set_all(simplexStepSize,
                       1.0); // is this always a sensible starting step size?
    gsl_multimin_fminimizer_set(simplexMinimizer, &gslSimplexContainer,
                                initFuncArg, simplexStepSize);
  }

  // finally do the fitting

  int iter = 0;
  int status;
  double finalCostFuncVal;
  double dof = static_cast<double>(
      l_data.n - l_data.p); // dof stands for degrees of freedom

  // Standard least-squares used if derivative function defined otherwise
  // simplex
  Progress prog(this, 0.0, 1.0, maxInterations);
  if (isDerivDefined) {

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

      if (status) // break if error
        break;

      status = gsl_multifit_test_delta(s->dx, s->x, 1e-4, 1e-4);
      prog.report();
    } while (status == GSL_CONTINUE && iter < maxInterations);

    double chi = gsl_blas_dnrm2(s->f);
    finalCostFuncVal = chi * chi / dof;

    // put final converged fitting values back into m_fittedParameter
    for (size_t i = 0, j = 0; i < nParams(); i++)
      if (l_data.active[i])
        m_fittedParameter[i] = gsl_vector_get(s->x, j++);
  } else {
    do {
      iter++;
      status = gsl_multimin_fminimizer_iterate(simplexMinimizer);

      if (status) // break if error
        break;

      double size = gsl_multimin_fminimizer_size(simplexMinimizer);
      status = gsl_multimin_test_size(size, 1e-2);
      prog.report();
    } while (status == GSL_CONTINUE && iter < maxInterations);

    finalCostFuncVal = simplexMinimizer->fval / dof;

    // put final converged fitting values back into m_fittedParameter
    for (unsigned int i = 0, j = 0; i < m_fittedParameter.size(); i++)
      if (l_data.active[i])
        m_fittedParameter[i] = gsl_vector_get(simplexMinimizer->x, j++);
  }

  modifyFinalFittedParameters(
      m_fittedParameter); // do nothing except if overwritten by derived class

  // Output summary to log file

  std::string reportOfFit = gsl_strerror(status);

  g_log.information() << "Iteration = " << iter << "\n"
                      << "Status = " << reportOfFit << "\n"
                      << "Chi^2/DoF = " << finalCostFuncVal << "\n";
  for (size_t i = 0; i < m_fittedParameter.size(); i++)
    g_log.information() << m_parameterNames[i] << " = " << m_fittedParameter[i]
                        << "  \n";

  // also output summary to properties

  setProperty("OutputStatus", reportOfFit);
  setProperty("OutputChi2overDoF", finalCostFuncVal);
  for (size_t i = 0; i < m_fittedParameter.size(); i++)
    setProperty(m_parameterNames[i], m_fittedParameter[i]);

  std::string output = getProperty("Output");
  if (!output.empty()) {
    // calculate covariance matrix if derivatives available

    gsl_matrix *covar(NULL);
    std::vector<double> standardDeviations;
    std::vector<double> sdExtended;
    if (isDerivDefined) {
      covar = gsl_matrix_alloc(l_data.p, l_data.p);
      gsl_multifit_covar(s->J, 0.0, covar);

      int iPNotFixed = 0;
      for (size_t i = 0; i < nParams(); i++) {
        sdExtended.push_back(1.0);
        if (l_data.active[i]) {
          sdExtended[i] = sqrt(gsl_matrix_get(covar, iPNotFixed, iPNotFixed));
          iPNotFixed++;
        }
      }
      modifyFinalFittedParameters(sdExtended);
      for (size_t i = 0; i < nParams(); i++)
        if (l_data.active[i])
          standardDeviations.push_back(sdExtended[i]);

      declareProperty(
          new WorkspaceProperty<API::ITableWorkspace>(
              "OutputNormalisedCovarianceMatrix", "", Direction::Output),
          "The name of the TableWorkspace in which to store the final "
          "covariance matrix");
      setPropertyValue("OutputNormalisedCovarianceMatrix",
                       output + "_NormalisedCovarianceMatrix");

      Mantid::API::ITableWorkspace_sptr m_covariance =
          Mantid::API::WorkspaceFactory::Instance().createTable(
              "TableWorkspace");
      m_covariance->addColumn("str", "Name");
      std::vector<std::string>
          paramThatAreFitted; // used for populating 1st "name" column
      for (size_t i = 0; i < nParams(); i++) {
        if (l_data.active[i]) {
          m_covariance->addColumn("double", m_parameterNames[i]);
          paramThatAreFitted.push_back(m_parameterNames[i]);
        }
      }

      for (size_t i = 0; i < l_data.p; i++) {

        Mantid::API::TableRow row = m_covariance->appendRow();
        row << paramThatAreFitted[i];
        for (size_t j = 0; j < l_data.p; j++) {
          if (j == i)
            row << 1.0;
          else {
            row << 100.0 * gsl_matrix_get(covar, i, j) /
                       sqrt(gsl_matrix_get(covar, i, i) *
                            gsl_matrix_get(covar, j, j));
          }
        }
      }

      setProperty("OutputNormalisedCovarianceMatrix", m_covariance);
    }

    declareProperty(new WorkspaceProperty<API::ITableWorkspace>(
                        "OutputParameters", "", Direction::Output),
                    "The name of the TableWorkspace in which to store the "
                    "final fit parameters");
    declareProperty(
        new WorkspaceProperty<MatrixWorkspace>("OutputWorkspace", "",
                                               Direction::Output),
        "Name of the output Workspace holding resulting simlated spectrum");

    setPropertyValue("OutputParameters", output + "_Parameters");
    setPropertyValue("OutputWorkspace", output + "_Workspace");

    // Save the final fit parameters in the output table workspace
    Mantid::API::ITableWorkspace_sptr m_result =
        Mantid::API::WorkspaceFactory::Instance().createTable("TableWorkspace");
    m_result->addColumn("str", "Name");
    m_result->addColumn("double", "Value");
    if (isDerivDefined)
      m_result->addColumn("double", "Error");
    Mantid::API::TableRow row = m_result->appendRow();
    row << "Chi^2/DoF" << finalCostFuncVal;

    for (size_t i = 0; i < nParams(); i++) {
      Mantid::API::TableRow row = m_result->appendRow();
      row << m_parameterNames[i] << m_fittedParameter[i];
      if (isDerivDefined && l_data.active[i]) {
        // perhaps want to scale standard deviations with sqrt(finalCostFuncVal)
        row << sdExtended[i];
      }
    }
    setProperty("OutputParameters", m_result);

    // Save the fitted and simulated spectra in the output workspace
    MatrixWorkspace_const_sptr inputWorkspace = getProperty("InputWorkspace");
    int iSpec = getProperty("WorkspaceIndex");
    const MantidVec &inputX = inputWorkspace->readX(iSpec);
    const MantidVec &inputY = inputWorkspace->readY(iSpec);

    int histN = isHistogram ? 1 : 0;
    Mantid::DataObjects::Workspace2D_sptr ws =
        boost::dynamic_pointer_cast<Mantid::DataObjects::Workspace2D>(
            Mantid::API::WorkspaceFactory::Instance().create(
                "Workspace2D", 3, l_data.n + histN, l_data.n));
    ws->setTitle("");
    ws->getAxis(0)->unit() =
        inputWorkspace->getAxis(0)
            ->unit(); //    UnitFactory::Instance().create("TOF");

    for (int i = 0; i < 3; i++)
      ws->dataX(i)
          .assign(inputX.begin() + m_minX, inputX.begin() + m_maxX + histN);

    ws->dataY(0).assign(inputY.begin() + m_minX, inputY.begin() + m_maxX);

    MantidVec &Y = ws->dataY(1);
    MantidVec &E = ws->dataY(2);

    double *lOut =
        new double[l_data.n]; // to capture output from call to function()
    modifyInitialFittedParameters(m_fittedParameter); // does nothing except if
                                                      // overwritten by derived
                                                      // class
    function(&m_fittedParameter[0], lOut, l_data.X, l_data.n);
    modifyInitialFittedParameters(m_fittedParameter); // reverse the effect of
    // modifyInitialFittedParameters - if any

    for (unsigned int i = 0; i < l_data.n; i++) {
      Y[i] = lOut[i];
      E[i] = l_data.Y[i] - Y[i];
    }

    delete[] lOut;

    setProperty("OutputWorkspace",
                boost::dynamic_pointer_cast<MatrixWorkspace>(ws));

    if (isDerivDefined)
      gsl_matrix_free(covar);
  }

  // clean up dynamically allocated gsl stuff

  if (isDerivDefined)
    gsl_multifit_fdfsolver_free(s);
  else {
    gsl_vector_free(simplexStepSize);
    gsl_multimin_fminimizer_free(simplexMinimizer);
  }

  delete[] l_data.X;
  delete[] l_data.sigmaData;
  delete[] l_data.forSimplexLSwrap;
  delete[] l_data.parameters;
  gsl_vector_free(initFuncArg);

  return;
}
/** Fit peaks' offset by minimize the fitting function
  */
void GetDetOffsetsMultiPeaks::fitPeaksOffset(
    const size_t inpnparams, const double minD, const double maxD,
    const std::vector<double> &vec_peakPosRef,
    const std::vector<double> &vec_peakPosFitted,
    const std::vector<double> &vec_peakHeights,
    FitPeakOffsetResult &fitresult) {
  // Set up array for minimization/optimization by GSL library
  size_t nparams = inpnparams;
  if (nparams > 50)
    nparams = 50;

  double params[153];
  params[0] = static_cast<double>(nparams);
  params[1] = minD;
  params[2] = maxD;
  for (size_t i = 0; i < nparams; i++) {
    params[i + 3] = vec_peakPosRef[i];
  }
  for (size_t i = 0; i < nparams; i++) {
    params[i + 3 + nparams] = vec_peakPosFitted[i];
  }

  // the reason to put these codes here is that nparams may be altered in this
  // method
  fitresult.peakPosFittedSize = static_cast<double>(vec_peakPosFitted.size());
  for (size_t i = 0; i < nparams; i++) {
    params[i + 3 + 2 * nparams] =
        (vec_peakHeights[i] * vec_peakHeights[i]); // vec_fitChi2[i];
    fitresult.chisqSum +=
        1. / (vec_peakHeights[i] * vec_peakHeights[i]); // vec_fitChi2[i];
  }

  // Set up GSL minimzer
  const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;
  gsl_multimin_fminimizer *s = NULL;
  gsl_vector *ss, *x;
  gsl_multimin_function minex_func;

  // Finally do the fitting
  size_t nopt = 1;
  size_t iter = 0;
  int status = 0;
  double size;

  /* Starting point */
  x = gsl_vector_alloc(nopt);
  gsl_vector_set_all(x, 0.0);

  /* Set initial step sizes to 0.001 */
  ss = gsl_vector_alloc(nopt);
  gsl_vector_set_all(ss, 0.001);

  /* Initialize method and iterate */
  minex_func.n = nopt;
  minex_func.f = &gsl_costFunction;
  minex_func.params = &params;

  s = gsl_multimin_fminimizer_alloc(T, nopt);
  gsl_multimin_fminimizer_set(s, &minex_func, x, ss);

  do {
    iter++;
    status = gsl_multimin_fminimizer_iterate(s);
    if (status)
      break;

    size = gsl_multimin_fminimizer_size(s);
    status = gsl_multimin_test_size(size, 1e-4);

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

  // Output summary to log file
  std::string reportOfDiffractionEventCalibrateDetectors = gsl_strerror(status);
  /*
  g_log.debug() << " Workspace Index = " << wi <<
                   " Method used = " << " Simplex" <<
                   " Iteration = " << iter <<
                   " Status = " << reportOfDiffractionEventCalibrateDetectors <<
                   " Minimize Sum = " << s->fval <<
                   " Offset   = " << gsl_vector_get (s->x, 0) << "  \n";
  */
  fitresult.offset = gsl_vector_get(s->x, 0);
  fitresult.fitSum = s->fval;

  fitresult.fitoffsetstatus = reportOfDiffractionEventCalibrateDetectors;
  fitresult.chi2 = s->fval;

  gsl_vector_free(x);
  gsl_vector_free(ss);
  gsl_multimin_fminimizer_free(s);
  return;
}
int VelStereoMatcher::findOptimalStereo(StereoProperties init)
{

  const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex2;
  gsl_multimin_fminimizer *s = NULL;
  gsl_vector *ss, *x;
  gsl_multimin_function minex_func;

  size_t iter = 0;
  int status;
  double size;

  // Starting point
  x = stereoToVec(init);

  // Set initial step sizes to 1
  ss = gsl_vector_alloc(11);
  gsl_vector_set(ss, 0, 0.1);
  gsl_vector_set(ss, 1, 0.1);
  gsl_vector_set(ss, 2, 0.1);
  gsl_vector_set(ss, 3, 0.05);
  gsl_vector_set(ss, 4, 0.05);
  gsl_vector_set(ss, 5, 0.05);
  gsl_vector_set(ss, 6, 5);
  gsl_vector_set(ss, 7, 5);
  gsl_vector_set(ss, 8, 5);
  gsl_vector_set(ss, 9, 5);
  gsl_vector_set(ss, 10, 0.001);

  // Initialize method and iterate
  minex_func.n = 11;
  minex_func.f = this->optFuncWrapper;
  minex_func.params = this;

  s = gsl_multimin_fminimizer_alloc(T, 11);
  gsl_multimin_fminimizer_set(s, &minex_func, x, ss);

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

    if (status)
      break;

    size = gsl_multimin_fminimizer_size(s);
    status = gsl_multimin_test_size(size, 1e-4);

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

    printf("%5d x:%2.3f y:%2.3f z:%2.3f rx:%2.3f ry:%2.3f rz:%2.3f fx:%3.1f fy:%3.1f cx:%3.1f cy:%3.1f baseline:%2.3f f() = %7.3f size = %.3f\n", iter,
           gsl_vector_get(s->x, 0), gsl_vector_get(s->x, 1), gsl_vector_get(s->x, 2), gsl_vector_get(s->x, 3),
           gsl_vector_get(s->x, 4), gsl_vector_get(s->x, 5), gsl_vector_get(s->x, 6), gsl_vector_get(s->x, 7), gsl_vector_get(s->x, 8), gsl_vector_get(s->x, 9), gsl_vector_get(s->x, 10), s->fval, size);
  } while (status == GSL_CONTINUE && iter < 100);

  gsl_vector_free(x);
  gsl_vector_free(ss);
  gsl_multimin_fminimizer_free(s);

  return status;
}
Example #27
0
static VALUE rb_gsl_multimin_test_size(VALUE obj, VALUE ss, VALUE ea)
{
  Need_Float(ss); Need_Float(ea);
  return INT2FIX(gsl_multimin_test_size(NUM2DBL(ss), NUM2DBL(ea)));
}
Example #28
0
int SimplexMinimizer::hasConverged()
{
  double size = gsl_multimin_fminimizer_size(m_gslSolver);
  return gsl_multimin_test_size(size, 1e-2);
}
/** Executes the algorithm
*
*  @throw runtime_error Thrown if algorithm cannot execute
*/
void DiffractionEventCalibrateDetectors::exec() {
  // Try to retrieve optional properties
  const int maxIterations = getProperty("MaxIterations");
  const double peakOpt = getProperty("LocationOfPeakToOptimize");

  // Get the input workspace
  EventWorkspace_sptr inputW = getProperty("InputWorkspace");

  // retrieve the properties
  const std::string rb_params = getProperty("Params");

  // Get some stuff from the input workspace
  Instrument_const_sptr inst = inputW->getInstrument();

  // Build a list of Rectangular Detectors
  std::vector<boost::shared_ptr<RectangularDetector>> detList;
  // --------- Loading only one bank ----------------------------------
  std::string onebank = getProperty("BankName");
  bool doOneBank = (onebank != "");
  for (int i = 0; i < inst->nelements(); i++) {
    boost::shared_ptr<RectangularDetector> det;
    boost::shared_ptr<ICompAssembly> assem;
    boost::shared_ptr<ICompAssembly> assem2;

    det = boost::dynamic_pointer_cast<RectangularDetector>((*inst)[i]);
    if (det) {
      if (det->getName().compare(onebank) == 0)
        detList.push_back(det);
      if (!doOneBank)
        detList.push_back(det);
    } else {
      // Also, look in the first sub-level for RectangularDetectors (e.g. PG3).
      // We are not doing a full recursive search since that will be very long
      // for lots of pixels.
      assem = boost::dynamic_pointer_cast<ICompAssembly>((*inst)[i]);
      if (assem) {
        for (int j = 0; j < assem->nelements(); j++) {
          det = boost::dynamic_pointer_cast<RectangularDetector>((*assem)[j]);
          if (det) {
            if (det->getName().compare(onebank) == 0)
              detList.push_back(det);
            if (!doOneBank)
              detList.push_back(det);

          } else {
            // Also, look in the second sub-level for RectangularDetectors (e.g.
            // PG3).
            // We are not doing a full recursive search since that will be very
            // long for lots of pixels.
            assem2 = boost::dynamic_pointer_cast<ICompAssembly>((*assem)[j]);
            if (assem2) {
              for (int k = 0; k < assem2->nelements(); k++) {
                det = boost::dynamic_pointer_cast<RectangularDetector>(
                    (*assem2)[k]);
                if (det) {
                  if (det->getName().compare(onebank) == 0)
                    detList.push_back(det);
                  if (!doOneBank)
                    detList.push_back(det);
                }
              }
            }
          }
        }
      }
    }
  }

  // set-up minimizer

  std::string inname = getProperty("InputWorkspace");
  std::string outname = inname + "2"; // getProperty("OutputWorkspace");

  IAlgorithm_sptr algS = createChildAlgorithm("SortEvents");
  algS->setProperty("InputWorkspace", inputW);
  algS->setPropertyValue("SortBy", "X Value");
  algS->executeAsChildAlg();

  // Write DetCal File
  std::string filename = getProperty("DetCalFilename");
  std::fstream outfile;
  outfile.open(filename.c_str(), std::ios::out);

  if (detList.size() > 1) {
    outfile << "#\n";
    outfile << "#  Mantid Optimized .DetCal file for SNAP with TWO detector "
               "panels\n";
    outfile << "#  Old Panel, nominal size and distance at -90 degrees.\n";
    outfile << "#  New Panel, nominal size and distance at +90 degrees.\n";
    outfile << "#\n";
    outfile << "# Lengths are in centimeters.\n";
    outfile << "# Base and up give directions of unit vectors for a local\n";
    outfile << "# x,y coordinate system on the face of the detector.\n";
    outfile << "#\n";
    outfile << "# " << DateAndTime::getCurrentTime().toFormattedString("%c")
            << "\n";
    outfile << "#\n";
    outfile << "6         L1     T0_SHIFT\n";
    IComponent_const_sptr source = inst->getSource();
    IComponent_const_sptr sample = inst->getSample();
    outfile << "7  " << source->getDistance(*sample) * 100 << "            0\n";
    outfile << "4 DETNUM  NROWS  NCOLS  WIDTH   HEIGHT   DEPTH   DETD   "
               "CenterX   CenterY   CenterZ    BaseX    BaseY    BaseZ      "
               "UpX      UpY      UpZ\n";
  }

  Progress prog(this, 0.0, 1.0, detList.size());
  for (int det = 0; det < static_cast<int>(detList.size()); det++) {
    std::string par[6];
    par[0] = detList[det]->getName();
    par[1] = inname;
    par[2] = outname;
    std::ostringstream strpeakOpt;
    strpeakOpt << peakOpt;
    par[3] = strpeakOpt.str();
    par[4] = rb_params;

    // --- Create a GroupingWorkspace for this detector name ------
    CPUTimer tim;
    IAlgorithm_sptr alg2 =
        AlgorithmFactory::Instance().create("CreateGroupingWorkspace", 1);
    alg2->initialize();
    alg2->setProperty("InputWorkspace", inputW);
    alg2->setPropertyValue("GroupNames", detList[det]->getName());
    std::string groupWSName = "group_" + detList[det]->getName();
    alg2->setPropertyValue("OutputWorkspace", groupWSName);
    alg2->executeAsChildAlg();
    par[5] = groupWSName;
    std::cout << tim << " to CreateGroupingWorkspace\n";

    const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;
    gsl_multimin_fminimizer *s = nullptr;
    gsl_vector *ss, *x;
    gsl_multimin_function minex_func;

    // finally do the fitting

    int nopt = 6;
    int iter = 0;
    int status = 0;

    /* Starting point */
    x = gsl_vector_alloc(nopt);
    gsl_vector_set(x, 0, 0.0);
    gsl_vector_set(x, 1, 0.0);
    gsl_vector_set(x, 2, 0.0);
    gsl_vector_set(x, 3, 0.0);
    gsl_vector_set(x, 4, 0.0);
    gsl_vector_set(x, 5, 0.0);

    /* Set initial step sizes to 0.1 */
    ss = gsl_vector_alloc(nopt);
    gsl_vector_set_all(ss, 0.1);

    /* Initialize method and iterate */
    minex_func.n = nopt;
    minex_func.f = &Mantid::Algorithms::gsl_costFunction;
    minex_func.params = &par;

    s = gsl_multimin_fminimizer_alloc(T, nopt);
    gsl_multimin_fminimizer_set(s, &minex_func, x, ss);

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

      if (status)
        break;

      double size = gsl_multimin_fminimizer_size(s);
      status = gsl_multimin_test_size(size, 1e-2);

    } while (status == GSL_CONTINUE && iter < maxIterations &&
             s->fval != -0.000);

    // Output summary to log file
    if (s->fval != -0.000)
      movedetector(gsl_vector_get(s->x, 0), gsl_vector_get(s->x, 1),
                   gsl_vector_get(s->x, 2), gsl_vector_get(s->x, 3),
                   gsl_vector_get(s->x, 4), gsl_vector_get(s->x, 5), par[0],
                   getProperty("InputWorkspace"));
    else {
      gsl_vector_set(s->x, 0, 0.0);
      gsl_vector_set(s->x, 1, 0.0);
      gsl_vector_set(s->x, 2, 0.0);
      gsl_vector_set(s->x, 3, 0.0);
      gsl_vector_set(s->x, 4, 0.0);
      gsl_vector_set(s->x, 5, 0.0);
    }

    std::string reportOfDiffractionEventCalibrateDetectors =
        gsl_strerror(status);
    if (s->fval == -0.000)
      reportOfDiffractionEventCalibrateDetectors = "No events";

    g_log.information() << "Detector = " << det << "\n"
                        << "Method used = "
                        << "Simplex"
                        << "\n"
                        << "Iteration = " << iter << "\n"
                        << "Status = "
                        << reportOfDiffractionEventCalibrateDetectors << "\n"
                        << "Minimize PeakLoc-" << peakOpt << " = " << s->fval
                        << "\n";
    // Move in cm for small shifts
    g_log.information() << "Move (X)   = " << gsl_vector_get(s->x, 0) * 0.01
                        << "  \n";
    g_log.information() << "Move (Y)   = " << gsl_vector_get(s->x, 1) * 0.01
                        << "  \n";
    g_log.information() << "Move (Z)   = " << gsl_vector_get(s->x, 2) * 0.01
                        << "  \n";
    g_log.information() << "Rotate (X) = " << gsl_vector_get(s->x, 3) << "  \n";
    g_log.information() << "Rotate (Y) = " << gsl_vector_get(s->x, 4) << "  \n";
    g_log.information() << "Rotate (Z) = " << gsl_vector_get(s->x, 5) << "  \n";

    Kernel::V3D CalCenter =
        V3D(gsl_vector_get(s->x, 0) * 0.01, gsl_vector_get(s->x, 1) * 0.01,
            gsl_vector_get(s->x, 2) * 0.01);
    Kernel::V3D Center = detList[det]->getPos() + CalCenter;
    int pixmax = detList[det]->xpixels() - 1;
    int pixmid = (detList[det]->ypixels() - 1) / 2;
    BoundingBox box;
    detList[det]->getAtXY(pixmax, pixmid)->getBoundingBox(box);
    double baseX = box.xMax();
    double baseY = box.yMax();
    double baseZ = box.zMax();
    Kernel::V3D Base = V3D(baseX, baseY, baseZ) + CalCenter;
    pixmid = (detList[det]->xpixels() - 1) / 2;
    pixmax = detList[det]->ypixels() - 1;
    detList[det]->getAtXY(pixmid, pixmax)->getBoundingBox(box);
    double upX = box.xMax();
    double upY = box.yMax();
    double upZ = box.zMax();
    Kernel::V3D Up = V3D(upX, upY, upZ) + CalCenter;
    Base -= Center;
    Up -= Center;
    // Rotate around x
    baseX = Base[0];
    baseY = Base[1];
    baseZ = Base[2];
    double deg2rad = M_PI / 180.0;
    double angle = gsl_vector_get(s->x, 3) * deg2rad;
    Base = V3D(baseX, baseY * cos(angle) - baseZ * sin(angle),
               baseY * sin(angle) + baseZ * cos(angle));
    upX = Up[0];
    upY = Up[1];
    upZ = Up[2];
    Up = V3D(upX, upY * cos(angle) - upZ * sin(angle),
             upY * sin(angle) + upZ * cos(angle));
    // Rotate around y
    baseX = Base[0];
    baseY = Base[1];
    baseZ = Base[2];
    angle = gsl_vector_get(s->x, 4) * deg2rad;
    Base = V3D(baseZ * sin(angle) + baseX * cos(angle), baseY,
               baseZ * cos(angle) - baseX * sin(angle));
    upX = Up[0];
    upY = Up[1];
    upZ = Up[2];
    Up = V3D(upZ * cos(angle) - upX * sin(angle), upY,
             upZ * sin(angle) + upX * cos(angle));
    // Rotate around z
    baseX = Base[0];
    baseY = Base[1];
    baseZ = Base[2];
    angle = gsl_vector_get(s->x, 5) * deg2rad;
    Base = V3D(baseX * cos(angle) - baseY * sin(angle),
               baseX * sin(angle) + baseY * cos(angle), baseZ);
    upX = Up[0];
    upY = Up[1];
    upZ = Up[2];
    Up = V3D(upX * cos(angle) - upY * sin(angle),
             upX * sin(angle) + upY * cos(angle), upZ);
    Base.normalize();
    Up.normalize();
    Center *= 100.0;
    // << det+1  << "  "
    outfile << "5  " << detList[det]->getName().substr(4) << "  "
            << detList[det]->xpixels() << "  " << detList[det]->ypixels()
            << "  " << 100.0 * detList[det]->xsize() << "  "
            << 100.0 * detList[det]->ysize() << "  "
            << "0.2000"
            << "  " << Center.norm() << "  ";
    Center.write(outfile);
    outfile << "  ";
    Base.write(outfile);
    outfile << "  ";
    Up.write(outfile);
    outfile << "\n";

    // clean up dynamically allocated gsl stuff
    gsl_vector_free(x);
    gsl_vector_free(ss);
    gsl_multimin_fminimizer_free(s);

    // Remove the now-unneeded grouping workspace
    AnalysisDataService::Instance().remove(groupWSName);
    prog.report(detList[det]->getName());
  }

  // Closing
  outfile.close();
}
Example #30
0
extern real fitGemRecomb(double *ct, double *time, double **ctFit,
			const int nData, t_gemParams *params)
{

  int    nThreads, i, iter, status, maxiter;
  real   size, d2, tol, *dumpdata;
  size_t p, n;
  gemFitData *GD;
  char *dumpstr, dumpname[128];

  /* nmsimplex2 had convergence problems prior to gsl v1.14,
   * but it's O(N) instead of O(N) operations, so let's use it if v >= 1.14 */
#ifdef HAVE_LIBGSL
  gsl_multimin_fminimizer *s;
  gsl_vector *x,*dx;             /* parameters and initial step size */
  gsl_multimin_function fitFunc;
#ifdef GSL_MAJOR_VERSION
#ifdef GSL_MINOR_VERSION
#if ((GSL_MAJOR_VERSION == 1 && GSL_MINOR_VERSION >= 14) || \
  (GSL_MAJOR_VERSION > 1))
    const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex2;
#else
  const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;
#endif /* #if ... */
#endif /* GSL_MINOR_VERSION */
#else
  const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;
#endif /* GSL_MAJOR_VERSION */
  fprintf(stdout, "Will fit ka and kd to the ACF according to the reversible geminate recombination model.\n");
#else  /* HAVE_LIBGSL */
  fprintf(stderr, "Sorry, can't do reversible geminate recombination without gsl. "
	 "Recompile using --with-gsl.\n");
  return -1;
#endif /* HAVE_LIBGSL */

#ifdef HAVE_LIBGSL
#ifdef HAVE_OPENMP
  nThreads = omp_get_num_procs();
  omp_set_num_threads(nThreads);
  fprintf(stdout, "We will be using %i threads.\n", nThreads);
#endif

  iter    = 0;
  status  = 0;
  maxiter = 100;
  tol     = 1e-10;

  p = 2;                  /* Number of parameters to fit. ka and kd.  */
  n = params->nFitPoints; /* params->nLin*2 */;       /* Number of points in the reduced dataset  */

  if (params->D <= 0)
    {
      fprintf(stderr, "Fitting of D is not implemented yet. It must be provided on the command line.\n");
      return -1;
    }
  
/*   if (nData<n) { */
/*     fprintf(stderr, "Reduced data set larger than the complete data set!\n"); */
/*     n=nData; */
/*   } */
  snew(dumpdata, nData);
  snew(GD,1);

  GD->n = n;
  GD->y = ct;
  GD->ctTheory=NULL;
  snew(GD->ctTheory, nData);
  GD->LinLog=NULL;
  snew(GD->LinLog, n);
  GD->time = time;
  GD->ka = 0;
  GD->kd = 0;
  GD->tDelta = time[1]-time[0];
  GD->nData = nData;
  GD->params = params;
  snew(GD->logtime,params->nFitPoints);
  snew(GD->doubleLogTime,params->nFitPoints);

  for (i=0; i<params->nFitPoints; i++)
    {
      GD->doubleLogTime[i] = (double)(getLogIndex(i, params));
      GD->logtime[i] = (int)(GD->doubleLogTime[i]);
      GD->doubleLogTime[i]*=GD->tDelta;

      if (GD->logtime[i] >= nData)
	{
	  fprintf(stderr, "Ayay. It seems we're indexing out of bounds.\n");
	  params->nFitPoints = i;
	}      
    }

  fitFunc.f = &gemFunc_residual2;
  fitFunc.n = 2;
  fitFunc.params = (void*)GD;

  x  = gsl_vector_alloc (fitFunc.n);
  dx = gsl_vector_alloc (fitFunc.n);
  gsl_vector_set (x,  0, 25);
  gsl_vector_set (x,  1, 0.5);
  gsl_vector_set (dx, 0, 0.1);
  gsl_vector_set (dx, 1, 0.01);
  
  
  s = gsl_multimin_fminimizer_alloc (T, fitFunc.n);
  gsl_multimin_fminimizer_set (s, &fitFunc, x, dx);
  gsl_vector_free (x);
  gsl_vector_free (dx);

  do  {
    iter++;
    status = gsl_multimin_fminimizer_iterate (s);
    
    if (status != 0)
      gmx_fatal(FARGS,"Something went wrong in the iteration in minimizer %s:\n \"%s\"\n",
		gsl_multimin_fminimizer_name(s), gsl_strerror(status));
    
    d2     = gsl_multimin_fminimizer_minimum(s);
    size   = gsl_multimin_fminimizer_size(s);
    params->ka = gsl_vector_get (s->x, 0);
    params->kd = gsl_vector_get (s->x, 1);
    
    if (status)
      {
	fprintf(stderr, "%s\n", gsl_strerror(status));
	break;
      }

    status = gsl_multimin_test_size(size,tol);

    if (status == GSL_SUCCESS) {
      fprintf(stdout, "Converged to minimum at\n");
    }

    printf ("iter %5d: ka = %2.5f  kd = %2.5f  f() = %7.3f  size = %.3f  chi2 = %2.5f\n",
	    iter,
	    params->ka,
	    params->kd,
	    s->fval, size, d2);

    if (iter%1 == 0)
      {
	eq10v2(GD->ctTheory, time, nData, params->ka, params->kd, params);
	/* fixGemACF(GD->ctTheory, nFitPoints); */
	sprintf(dumpname, "Iter_%i.xvg", iter);
	for(i=0; i<GD->nData; i++)
	  {
	    dumpdata[i] = (real)(GD->ctTheory[i]);
	    if (!gmx_isfinite(dumpdata[i]))
	      {
		gmx_fatal(FARGS, "Non-finite value in acf.");
	      }
	  }
	dumpN(dumpdata, GD->nData, dumpname);
      }
  }
  while ((status == GSL_CONTINUE) && (iter < maxiter));

  /*   /\* Calculate the theoretical ACF from the parameters one last time. *\/ */
  eq10v2(GD->ctTheory, time, nData, params->ka, params->kd, params);
  *ctFit = GD->ctTheory;

  sfree(GD);
  gsl_multimin_fminimizer_free (s);


  return d2;

#endif /* HAVE_LIBGSL */
}