コード例 #1
0
double MLFitterGSL::iteration(){
  //do one itteration
  //lock the model so user can not add or remove components during itteration
  modelptr->setlocked(true);
  //if the model has changed (a new or removed component eg.) create a new solver
  if (modelptr->has_changed()){
      createmodelinfo();     //this automaticaly calls initfitter() via created_modelinfo()
  }
  //do an itteration step  
  try{
    const int status=gsl_multifit_fdfsolver_iterate(solver);
    #ifdef FITTER_DEBUG
    std::cout <<"solver status: "<<gsl_strerror(status)<<"\n";
    std::cout <<"chi square/dof: "<<gsl_blas_dnrm2(solver->f)<<"\n";
    #endif
    this->setstatus(gsl_strerror(status)); //update status info of fitter
    convertxtoparam(solver->x);
    
    
    
  }
  catch(...){
    Saysomething mysay(0,"Error","Problem with call to gsl_multifit_fdfsolver_iterate, exit MLFitterGSL",true);
    delete(this);
  }
 //unlock the model so user can add or remove components
  modelptr->setlocked(false);
  //put the goodness in the goodnessqueue to check for convergence
  const double newgoodness= goodness_of_fit();
  addgoodness(newgoodness);
  return newgoodness;
}
コード例 #2
0
      /**
       * C++ version of gsl_multifit_fdfsolver_iterate().
       * @param s The fdfsolver.
       * @return Error code on failure.
       */
      inline static int iterate( fdfsolver& s ){
	int const result = gsl_multifit_fdfsolver_iterate( s.get() ); 
	s.x_v.wrap_gsl_vector_without_ownership( s.get()->x );
	s.f_v.wrap_gsl_vector_without_ownership( s.get()->x );
	s.dx_v.wrap_gsl_vector_without_ownership( s.get()->dx );
	s.J_m.wrap_gsl_matrix_without_ownership( s.get()->J );
	return result;
      }
コード例 #3
0
      /**
       * C++ version of gsl_multifit_fdfsolver_iterate().
       * @return Error code on failure.
       */
      int iterate(){
	int const result = gsl_multifit_fdfsolver_iterate( get() );
	x_v.wrap_gsl_vector_without_ownership( get()->x );
	f_v.wrap_gsl_vector_without_ownership( get()->f );
	dx_v.wrap_gsl_vector_without_ownership( get()->dx );
	J_m.wrap_gsl_matrix_without_ownership( get()->J );
	return result;
      }
コード例 #4
0
Vector MultiSolver::NLLeastSquareSolver(MultiSolverInput *input)
{
	/**/condition.analyzer->solverSolving.startTimer();	// ---- ---- T5 start
	const gsl_multifit_fdfsolver_type *T;
	gsl_multifit_fdfsolver *s;
	gsl_multifit_function_fdf f;
	
	double x_init[3] = {0.0, 0.0, 150.0};
//	x_init[0] = input->initLocation.x;
//	x_init[1] = input->initLocation.y;
//	x_init[2] = input->initLocation.z;
	
	gsl_vector_view x = gsl_vector_view_array(x_init, 3);

	int n = (int)input->data.size();

	// sort restriction..
//	n = 3;

	int p = 3;

	f.f = &ms_f;
	f.df = &ms_df;
	f.fdf = &ms_fdf;
	f.n = n;
	f.p = p;	
	f.params = input;

	T = gsl_multifit_fdfsolver_lmsder;
	s = gsl_multifit_fdfsolver_alloc(T, n, p);
	gsl_multifit_fdfsolver_set(s, &f, &x.vector);

	gsl_vector *gradt = gsl_vector_alloc(p);

	int iter = 0;
	int status;
	do
	{
		iter ++;
		status = gsl_multifit_fdfsolver_iterate(s);
		if (status) break;
///		status = gsl_multifit_test_delta(s->dx, s->x, 1e-4, 1e-4);
		gsl_multifit_gradient(s->J, s->f, gradt);
		status = gsl_multifit_test_gradient(gradt, 1e-6);
	}
	while (status == GSL_CONTINUE && iter < 500);

	

	Vector point = Vector(gsl_vector_get(s->x, 0), gsl_vector_get(s->x, 1), gsl_vector_get(s->x, 2));

	gsl_vector_free(gradt);
	gsl_multifit_fdfsolver_free(s);


	/**/condition.analyzer->solverSolving.stopTimer();	// ---- ---- T5 end
	return point;	
}
コード例 #5
0
ファイル: Fit.cpp プロジェクト: BackupTheBerlios/qtiplot-svn
gsl_multifit_fdfsolver * Fit::fitGSL(gsl_multifit_function_fdf f, int &iterations, int &status)
{
	const gsl_multifit_fdfsolver_type *T;
	if (d_solver)
		T = gsl_multifit_fdfsolver_lmder;
	else
		T = gsl_multifit_fdfsolver_lmsder;

	gsl_set_error_handler_off();

	gsl_multifit_fdfsolver *s = gsl_multifit_fdfsolver_alloc (T, d_n, d_p);
	status = gsl_multifit_fdfsolver_set (s, &f, d_param_init);

	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;
		}
	}

	if (status){
	    gsl_multifit_covar (s->J, 0.0, covar);
	    iterations = 0;
	    return s;
	}

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

		for (int i=0; i<d_p; i++){
			double p = gsl_vector_get(s->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->x, i);

		status = gsl_multifit_test_delta (s->dx, s->x, d_tolerance, d_tolerance);
	} while (inRange && status == GSL_CONTINUE && (int)iter < d_max_iterations);

	gsl_multifit_covar (s->J, 0.0, covar);

	iterations = iter;
	return s;
}
コード例 #6
0
void
test_lmder (gsl_multifit_function_fdf * f, double x0[], 
            double * X, double F[], double * cov)
{
  const gsl_multifit_fdfsolver_type *T;
  gsl_multifit_fdfsolver *s;

  const size_t n = f->n;
  const size_t p = f->p;

  int status;
  size_t iter = 0, i;
  
  gsl_vector_view x = gsl_vector_view_array (x0, p);

  T = gsl_multifit_fdfsolver_lmsder;
  s = gsl_multifit_fdfsolver_alloc (T, n, p);
  gsl_multifit_fdfsolver_set (s, f, &x.vector);

  do
    {
      status = gsl_multifit_fdfsolver_iterate (s);

      for (i = 0 ; i < p; i++)
        {
          gsl_test_rel (gsl_vector_get (s->x, i), X[p*iter+i], 1e-5, 
                        "lmsder, iter=%u, x%u", iter, i);
        }

      gsl_test_rel (gsl_blas_dnrm2 (s->f), F[iter], 1e-5, 
                    "lmsder, iter=%u, f", iter);

      iter++;
    }
  while (iter < 20);
  
  {
    size_t i, j;
    gsl_matrix * covar = gsl_matrix_alloc (4, 4);
    gsl_multifit_covar (s->J, 0.0, covar);

    for (i = 0; i < 4; i++) 
      {
        for (j = 0; j < 4; j++)
          {
            gsl_test_rel (gsl_matrix_get(covar,i,j), cov[i*p + j], 1e-7, 
                          "gsl_multifit_covar cov(%d,%d)", i, j) ;
          }
      }

    gsl_matrix_free (covar);
  }

  gsl_multifit_fdfsolver_free (s);

}
コード例 #7
0
ファイル: Fit.cpp プロジェクト: mantidproject/mantid
gsl_multifit_fdfsolver *Fit::fitGSL(gsl_multifit_function_fdf f,
                                    int &iterations, int &status) {
  const gsl_multifit_fdfsolver_type *T;
  if (d_solver)
    T = gsl_multifit_fdfsolver_lmder;
  else
    T = gsl_multifit_fdfsolver_lmsder;

  gsl_multifit_fdfsolver *s = gsl_multifit_fdfsolver_alloc(T, d_n, d_p);
  gsl_multifit_fdfsolver_set(s, &f, d_param_init);

  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_multifit_fdfsolver_iterate(s);
    if (status)
      break;

    for (int i = 0; i < d_p; i++) {
      double p = gsl_vector_get(s->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->x, i);

    status = gsl_multifit_test_delta(s->dx, s->x, d_tolerance, d_tolerance);
  } while (inRange && status == GSL_CONTINUE && (int)iter < d_max_iterations);

#if GSL_MAJOR_VERSION < 2
  gsl_multifit_covar(s->J, 0.0, covar);
#else
  gsl_matrix *J = gsl_matrix_alloc(d_n, d_p);
  gsl_multifit_fdfsolver_jac(s, J);
  gsl_multifit_covar(J, 0.0, covar);
  gsl_matrix_free(J);
#endif
  iterations = static_cast<int>(iter);
  return s;
}
コード例 #8
0
ファイル: fdfridge.c プロジェクト: jfcaron3/gsl-steffen-devel
int
gsl_multifit_fdfridge_iterate (gsl_multifit_fdfridge * w)
{
  int status = gsl_multifit_fdfsolver_iterate(w->s);

  /* update function/Jacobian evaluations */
  w->fdf->nevalf = w->fdftik.nevalf;
  w->fdf->nevaldf = w->fdftik.nevaldf;

  return status;
}
コード例 #9
0
ファイル: NonLinearLSQ.cpp プロジェクト: corburn/ISIS
int NonLinearLSQ::curvefit() {

  size_t n(nSize());
  size_t p(nParms());

  //  Initialize the solver function information
  _nlsqPointer d = { this };
  gsl_multifit_function_fdf mf;
  mf.f      = &f;
  mf.df     = &df;
  mf.fdf    = &fdf;
  mf.n      =  n;
  mf.p      = p;
  mf.params =  &d;

  const gsl_multifit_fdfsolver_type *T = gsl_multifit_fdfsolver_lmsder;
  gsl_multifit_fdfsolver *s = gsl_multifit_fdfsolver_alloc(T, n, p);

  _fitParms = guess();
  gsl_vector *x = NlsqTogsl(_fitParms);
  gsl_matrix *covar = gsl_matrix_alloc(p, p);
  gsl_multifit_fdfsolver_set(s, &mf, x);

  _nIters = 0;
  checkIteration(_nIters, gslToNlsq(s->x), NLVector(p,999.0),
                  gsl_blas_dnrm2(s->f), GSL_CONTINUE);


  do {
    _nIters++;

    _status = gsl_multifit_fdfsolver_iterate(s);
    _fitParms = gslToNlsq(s->x);

    gsl_multifit_covar(s->J, 0.0, covar);
    _uncert = getUncertainty(covar);

    _status = checkIteration(_nIters, _fitParms, _uncert, gsl_blas_dnrm2(s->f),
                             _status);
    if ( _status  ) { break; }
    if(!doContinue()) { break; }

    _status = gsl_multifit_test_delta(s->dx, s->x, absErr(), relErr());
  } while ((_status == GSL_CONTINUE) && (_nIters < _maxIters));

  // Clean up
  gsl_multifit_fdfsolver_free(s);
  gsl_matrix_free(covar);

  return (_status);
}
コード例 #10
0
ファイル: my_gsl.cpp プロジェクト: mar80nik/Tracker
int MultiFitter::MainFDF()
{	
	multifit_fdfsolver_type = gsl_multifit_fdfsolver_lmsder;
	s = gsl_multifit_fdfsolver_alloc (multifit_fdfsolver_type, n, p);
	gsl_multifit_fdfsolver_set (s, &F, &x.vector);
	do
	{
		iter++;
		status = gsl_multifit_fdfsolver_iterate (s);
		status = gsl_multifit_test_delta (s->dx, s->x, epsabs, epsrel);
	}
	while (status == GSL_CONTINUE && iter < max_iter);
    return status;	
}
コード例 #11
0
ファイル: polysomy.c プロジェクト: andrewjesaitis/bcftools
static int gauss_fit(dist_t *dist, int ngauss, double *params)
{
    data_t *dat = &dist->dat;
    dat->ngauss = ngauss;

    gsl_multifit_function_fdf mfunc;
    mfunc.f   = &func_f;
    mfunc.df  = &func_df;
    mfunc.fdf = &func_set;
    mfunc.n   = dat->nvals;
    mfunc.p   = ngauss*3;      // number of fitting parameters
    mfunc.params = dat;

    const gsl_multifit_fdfsolver_type *solver_type;
    gsl_multifit_fdfsolver *solver;
    gsl_vector_view vview = gsl_vector_view_array(params, mfunc.p);
    solver_type = gsl_multifit_fdfsolver_lmsder;
    solver = gsl_multifit_fdfsolver_alloc(solver_type, dat->nvals, mfunc.p);
    gsl_multifit_fdfsolver_set(solver, &mfunc, &vview.vector);

    int i, status;
    size_t iter = 0;
    do
    {
        status = gsl_multifit_fdfsolver_iterate(solver);
        if ( status ) break;
        status = gsl_multifit_test_delta(solver->dx, solver->x, 1e-4, 1e-4);
    }
    while (status == GSL_CONTINUE && iter++ < 500);

    for (i=0; i<mfunc.p; i++)
        params[i] = gsl_vector_get(solver->x, i);

    gsl_multifit_fdfsolver_free(solver);
    return iter>500 ? -1 : 0;
}
コード例 #12
0
ファイル: geminate.c プロジェクト: alexholehouse/gromacs
/* Removes the ballistic term from the beginning of the ACF,
 * just like in Omer's paper.
 */
extern void takeAwayBallistic(double *ct, double *t, int len, real tMax, int nexp, gmx_bool bDerivative)
{

  /* Use nonlinear regression with GSL instead.
   * Fit with 4 exponentials and one constant term,
   * subtract the fatest exponential. */

  int nData,i,status, iter;
  balData *BD;
  double *guess,              /* Initial guess. */
    *A,                       /* The fitted parameters. (A1, B1, A2, B2,... C) */
    a[2],
    ddt[2];
  gmx_bool sorted;
  size_t n;
  size_t p;

  nData = 0;
  do {
    nData++;
  } while (t[nData]<tMax+t[0] && nData<len);

  p = nexp*2+1;              /* Number of parameters. */

#ifdef HAVE_LIBGSL
  const gsl_multifit_fdfsolver_type *T
    = gsl_multifit_fdfsolver_lmsder;

  gsl_multifit_fdfsolver *s;              /* The solver itself. */
  gsl_multifit_function_fdf fitFunction;  /* The function to be fitted. */
  gsl_matrix *covar;  /* Covariance matrix for the parameters.
		       * We'll not use the result, though. */
  gsl_vector_view theParams;

  nData = 0;
  do {
    nData++;
  } while (t[nData]<tMax+t[0] && nData<len);

  guess = NULL;
  n = nData;

  snew(guess, p);
  snew(A, p);
  covar = gsl_matrix_alloc (p, p);

  /* Set up an initial gess for the parameters.
   * The solver is somewhat sensitive to the initial guess,
   * but this worked fine for a TIP3P box with -geminate dd
   * EDIT: In fact, this seems like a good starting pont for other watermodels too. */
  for (i=0; i<nexp; i++)
    {
      guess[i*2] = 0.1;
      guess[i*2+1] = -0.5 + (((double)i)/nexp - 0.5)*0.3;
    }
  guess[nexp * 2] = 0.01;

  theParams = gsl_vector_view_array(guess, p);

  snew(BD,1);
  BD->n     = n;
  BD->y     = ct;
  BD->tDelta = t[1]-t[0];
  BD->nexp = nexp;

  fitFunction.f      =  &balFunc_f;
  fitFunction.df     =  &balFunc_df;
  fitFunction.fdf    =  &balFunc_fdf;
  fitFunction.n      =  nData;
  fitFunction.p      =  p;
  fitFunction.params =  BD;

  s = gsl_multifit_fdfsolver_alloc (T, nData, p);
  if (s==NULL)
    gmx_fatal(FARGS, "Could not set up the nonlinear solver.");

  gsl_multifit_fdfsolver_set(s, &fitFunction, &theParams.vector);

  /* \=============================================/ */

  iter = 0;
  do
    {
      iter++;
      status = gsl_multifit_fdfsolver_iterate (s);
      
      if (status)
	break;
      status = gsl_multifit_test_delta (s->dx, s->x, 1e-4, 1e-4);
    }
  while (iter < 5000 && status == GSL_CONTINUE);

  if (iter == 5000)
    {
      fprintf(stderr, "The non-linear fitting did not converge in 5000 steps.\n"
	     "Check the quality of the fit!\n");
    }
  else
    {
      fprintf(stderr, "Non-linear fitting of ballistic term converged in %d steps.\n\n", (int)iter);
    }
  for (i=0; i<nexp; i++) {
    fprintf(stdout, "%c * exp(%c * t) + ", 'A'+(char)i*2, 'B'+(char)i*2);
  }

  fprintf(stdout, "%c\n", 'A'+(char)nexp*2);
  fprintf(stdout, "Here are the actual numbers for A-%c:\n", 'A'+nexp*2);

  for (i=0; i<nexp; i++)
    {
      A[i*2]  = gsl_vector_get(s->x, i*2);
      A[i*2+1] = gsl_vector_get(s->x, i*2+1);
      fprintf(stdout, " %g*exp(%g * x) +", A[i*2], A[i*2+1]);
    }
  A[i*2] = gsl_vector_get(s->x, i*2);          /* The last and constant term */
  fprintf(stdout, " %g\n", A[i*2]);

  fflush(stdout);

  /* Implement some check for parameter quality */
  for (i=0; i<nexp; i++)
    {
      if (A[i*2]<0 || A[i*2]>1) {
	fprintf(stderr, "WARNING: ----------------------------------\n"
	       " | A coefficient does not lie within [0,1].\n"
	       " | This may or may not be a problem.\n"
	       " | Double check the quality of the fit!\n");
      }
      if (A[i*2+1]>0) {
	fprintf(stderr, "WARNING: ----------------------------------\n"
	       " | One factor in the exponent is positive.\n"
	       " | This could be a problem if the coefficient\n"
	       " | is large. Double check the quality of the fit!\n");
      }
    }
  if (A[i*2]<0 || A[i*2]>1) {
    fprintf(stderr, "WARNING: ----------------------------------\n"
	   " | The constant term does not lie within [0,1].\n"
	   " | This may or may not be a problem.\n"
	   " | Double check the quality of the fit!\n");
  }

  /* Sort the terms */
  sorted = (nexp > 1) ?  FALSE : TRUE;
  while (!sorted)
    {
      sorted = TRUE;
      for (i=0;i<nexp-1;i++)
	{
	  ddt[0] = A[i*2] * A[i*2+1];
	  ddt[1] =A[i*2+2] * A[i*2+3];
	  
	  if ((bDerivative && (ddt[0]<0 && ddt[1]<0 && ddt[0]>ddt[1])) || /* Compare derivative at t=0... */
	      (!bDerivative && (A[i*2+1] > A[i*2+3])))                    /* Or just the coefficient in the exponent */
	    {
	      sorted = FALSE;
	      a[0] = A[i*2];  /* coefficient */
	      a[1] = A[i*2+1]; /* parameter in the exponent */
	      
	      A[i*2] = A[i*2+2];
	      A[i*2+1] = A[i*2+3];
	      
	      A[i*2+2] = a[0];
	      A[i*2+3] = a[1];
	    }
	}
    }

  /* Subtract the fastest component */
  fprintf(stdout, "Fastest component is %g * exp(%g * t)\n"
	 "Subtracting fastest component from ACF.\n", A[0], A[1]);

  for (i=0; i<len; i++) {
    ct[i] = (ct[i] - A[0] * exp(A[1] * i*BD->tDelta)) / (1-A[0]);
  }

  sfree(guess);
  sfree(A);

  gsl_multifit_fdfsolver_free(s);
  gsl_matrix_free(covar);
  fflush(stdout);

#else
  /* We have no gsl. */
  fprintf(stderr, "Sorry, can't take away ballistic component without gsl. "
	 "Recompile using --with-gsl.\n");
  return;
#endif /* HAVE_LIBGSL */

}
コード例 #13
0
int InterpolaVPR_GSL::interpola_VPR(const float* vpr, int hvprmax, int livmin)
{
    LOG_CATEGORY("radar.vpr");
    static const unsigned N = 10;
    const gsl_multifit_fdfsolver_type *T;
    gsl_multifit_fdfsolver *s;
    int status;
    unsigned int i;
    const size_t n = N;
    const size_t p = 5;
    char file_vprint[512];
    gsl_matrix *covar = gsl_matrix_alloc (p, p);
    double a[5];
    struct data d(N);
    gsl_multifit_function_fdf f;
    double x_init[5] = { 4, 0.2, 3. , 1.4, -0.4 };
    gsl_vector_view x = gsl_vector_view_array (x_init, p);

    //////////////////////////////////////////////////////////////////////////////
    int ier_int=0;
    double xint,yint;
    /* punti interessanti per inizializzare parametri*/
    int  in1=(int)((hvprmax-TCK_VPR/2)/TCK_VPR); //indice del massimo
    int  in2=(int)((hvprmax+HALF_BB)/TCK_VPR); //indice del massimo + 500 m
    int  in3=in2+1;
    int  in4=in2+5; //indice del massimo + 1000 m
    if (in4 > NMAXLAYER-1) {
        ier_int=1;
        return ier_int;
    }

    B=vpr[in1]-vpr[in2];
    E=hvprmax/1000.;
    G=0.25;
    C=vpr[in2-1];
    F=vpr[in4]<vpr[in3]?(vpr[in4]-vpr[in3])/((in4-in3)*TCK_VPR/1000.):0.;
    // fprintf(stderr, "const unsigned NMAXLAYER=%d;\n", NMAXLAYER);
    // fprintf(stderr, "float vpr[] = {");
    // for (unsigned i = 0; i < NMAXLAYER; ++i)
    //     fprintf(stderr, "%s%f", i==0?"":",", (double)vpr[i]);
    // fprintf(stderr, "};\n");

    x_init[0]= a[0]=B;
    x_init[1]= a[1]=E;
    x_init[2]= a[2]=G;
    x_init[3]= a[3]=C;
    x_init[4]= a[4]=F;


    /////////////////////////////////////////////////////////////////////////////////////////////////////////

    f.f = &expb_f;
    f.df = &expb_df;
    f.fdf = &expb_fdf;
    f.n = n;
    f.p = p;
    f.params = &d;

    /* This is the data to be fitted */

    for (i = 0; i < n; i++)
    {
        d.t[i]= ((hvprmax-1000.)>livmin)? (i*TCK_VPR+(hvprmax-800)-TCK_VPR)/1000. : (livmin+i*TCK_VPR)/1000.;
        d.y[i]= ((hvprmax-1000.)>livmin)? vpr[i+(int)(((hvprmax-800)-TCK_VPR)/TCK_VPR)] : vpr[i+(int)(livmin/TCK_VPR)];
        d.sigma[i] = 0.5;
    };

    T = gsl_multifit_fdfsolver_lmsder;
    s = gsl_multifit_fdfsolver_alloc (T, n, p);
    gsl_multifit_fdfsolver_set (s, &f, &x.vector);

    //print_state (0, s);
    bool found = false;
    for (unsigned iter = 0; !found && iter < 500; ++iter)
    {
        //fprintf(stderr, "Iter %d\n", iter);
        //d.print();
        int status = gsl_multifit_fdfsolver_iterate (s);
        if (status != 0)
        {
            LOG_ERROR("gsl_multifit_fdfsolver_iterate: %s", gsl_strerror(status));
            return 1;
        }

        //print_state (iter, s);

        status = gsl_multifit_test_delta (s->dx, s->x,
                1e-4, 1e-4);
        switch (status)
        {
            case GSL_SUCCESS: found = true; break;
            case GSL_CONTINUE: break;
            default:
                LOG_ERROR("gsl_multifit_test_delta: %s", gsl_strerror(status));
                return 1;
        }
    }

#if GSL_MAJOR_VERSION == 2
    // Use of GSL 2.0 taken from https://sft.its.cern.ch/jira/browse/ROOT-7776
    gsl_matrix* J = gsl_matrix_alloc(s->fdf->n, s->fdf->p);
    gsl_multifit_fdfsolver_jac(s, J);
    gsl_multifit_covar(J, 0.0, covar);
#else
    gsl_multifit_covar(s->J, 0.0, covar);
#endif

#define FIT(i) gsl_vector_get(s->x, i)
#define ERR(i) sqrt(gsl_matrix_get(covar,i,i))

    { 
        double chi = gsl_blas_dnrm2(s->f);
        double dof = n - p;
        double c = GSL_MAX_DBL(1, chi / sqrt(dof)); 

        // printf("chisq/dof = %g\n",  pow(chi, 2.0) / dof);

        // printf ("B      = %.5f +/- %.5f\n", FIT(0), c*ERR(0));
        // printf ("E = %.5f +/- %.5f\n", FIT(1), c*ERR(1));
        // printf ("G     = %.5f +/- %.5f\n", FIT(2), c*ERR(2));
        // printf ("C = %.5f +/- %.5f\n", FIT(3), c*ERR(3));
        // printf ("F     = %.5f +/- %.5f\n", FIT(4), c*ERR(4));
    }

    B = a[0] = FIT(0);
    E = a[1] = FIT(1);
    G = a[2] = FIT(2);
    C = a[3] = FIT(3);
    F = a[4] = FIT(4);

    gsl_multifit_fdfsolver_free (s);
    gsl_matrix_free (covar);

    /////////////////////////////////////////////////////////

    if (testfit(a) == 1)
        return 1;

    for (i=1; i<=N; i++)
    {
        xint=(i*TCK_VPR-TCK_VPR/2)/1000.;
        yint= lineargauss(xint, a);
        vpr_int[i-1] = yint;
    }

    return 0;
}
コード例 #14
0
ファイル: gauss.c プロジェクト: eddyem/fitsview-hartmann
/*
 * Gaussian parameters calculation y=A/sqrt(2*pi*sigma^2) exp(-(x-x_0)^2/2/sigma^2),
 * which approximates the points set pts
 * Parameters A_, sigma_, x0_ may be NULL (if you don't need any of them)
 */
void gauss_fit(Points *pts, double *C_, double *A_, double *sigma_, double *x0_){
	// VVVV lower parameters may be formed as a structure to change as function argument
	double
		epsabs   = 1e-8,// absolute error
		epsrel   = 1e-5,// relative error
		chi_max  = 0.01;// max chi value for iterations criteria
	int max_iter = 300; // limit iterations number of gsl_multifit_fdfsolver
	size_t N_MIN = 10;	// minimum points for approximation
	double x_init[4];
	// AAAA upper parameters may be formed as a structure to change as function argument
/* x_init, the best approximations:
 * x0 - not far from real (the nearest is the better)
 * sigma - not far from real (the nearest is the better)
 * A - not large ~10 (it has a weak effect)
 */
	const gsl_multifit_fdfsolver_type *T;
	gsl_multifit_fdfsolver *s;
	int status;
	#ifdef EBUG
	int appNo = 0;
	#endif
	int iter;
	size_t i, j, n = pts->n, oldn;
	const size_t p = 4;
	gsl_matrix *covar = gsl_matrix_alloc (p, p);
	#ifdef EBUG
	double t0;
	#endif
	double *x, *y, *dy, chi, C, A, sigma, x0;
	if(n < 1) return;
	x = malloc(n * sizeof(double));
	y = malloc(n * sizeof(double));
	dy = malloc(n * sizeof(double));
	struct data d = {n, x, y, dy};
	gsl_multifit_function_fdf f;
	gsl_vector_view xx = gsl_vector_view_array(x_init, p);
	const gsl_rng_type *type;
	gsl_rng *r;

	gsl_rng_env_setup();
	type = gsl_rng_default;
	r = gsl_rng_alloc (type);
	f.f = &gauss_f;
	f.df = &gauss_df;
	f.fdf = &gauss_fdf;
	f.n = n;
	f.p = p;
	f.params = &d;
	// fill data structure. Don't forget Okkam's razor!!!
	{
		Point *pt = pts->data;
		double *px = x, *py = y, *pdy = dy, sum = 0.;
		for(i = 0; i < n; i++, pt++){
			*pdy++ = 1.; // I have no idea what is it, so init by 1
			*px++  = pt->x;
			*py++  = pt->y;
			sum   += pt->y;
			//DBG("point %d: (%g, %g)", i, pt->x, pt->y);
		}
		// fill x_init: x0, sigma, C, A (it can be a funtion parameter)
		x_init[3] = (*(--px) + *x) / 2.;
		x_init[2] = fabs((*x - *px) / 4.);
		x_init[0] = sum/(double)n;
		x_init[1] = sum;
		DBG("\nInitial parameters: x0=%.1f, sigma=%.1f, A=%.1f, C=%.1f",
			x_init[3], x_init[2], x_init[1], x_init[0]);
	}
	T = gsl_multifit_fdfsolver_lmder; // or also gsl_multifit_fdfsolver_lmsder
	s = gsl_multifit_fdfsolver_alloc(T, n, p);
	#ifdef EBUG
	t0 = dtime();
	#endif
	do{
		double dof, tres, c;
		DBG("\n************ Approximation %d ******************\n", appNo++);
		iter = 0;
		gsl_multifit_fdfsolver_set(s, &f, &xx.vector);
		do{
			iter++;
			status = gsl_multifit_fdfsolver_iterate(s);
			if(status)
				break;
			status = gsl_multifit_test_delta(s->dx, s->x, epsabs, epsrel);
		}while(status == GSL_CONTINUE && iter < max_iter);
		DBG("time=%g\n", dtime()-t0);
		gsl_multifit_covar(s->J, 0.0, covar);
		chi = gsl_blas_dnrm2(s->f);
		dof = n - p;
		tres = chi;
		c = chi / sqrt(dof); // GSL_MAX_DBL(1., chi / sqrt(dof));
		C = FIT(0), A = FIT(1), sigma = FIT(2), x0 = FIT(3);
		DBG("Number of iteratons = %d\n", iter);
		DBG("chi = %g, chi/dof = %g\n", chi, chi / sqrt(dof));
		DBG("C      = %.5f +/- %.5f\n", C, c*ERR(0));
		DBG("A      = %.5f +/- %.5f\n", A, c*ERR(1));
		DBG("sigma = %.5f +/- %.5f\n", sigma, c*ERR(2));
		DBG("x0     = %.5f +/- %.5f\n", x0, c*ERR(3));
		j = 0;
		oldn = n;
		if(c < chi_max) break;
		// throw out bad (by chi) data
		for(i = 0; i < n; i++){
			if(fabs(FN(i)) < tres){
				if(i != j){
					x[j] = x[i];
					y[j] = y[i];
					dy[j] = dy[i];
				}
				j++; continue;
			}
		}
		if(j != n){
			DBG("Chi tresholding %g, %zd points of %zd\n", tres, j, n);
			n = j;
			d.n = n;
		}
	}while(chi > chi_max && n != oldn && n > N_MIN);
	if(C_) *C_ = C;
	if(A_) *A_ = A;
	if(sigma_) *sigma_ = sigma;
	if(x0_) *x0_ = x0;
	//printf ("status = %s\n", gsl_strerror (status));
	gsl_multifit_fdfsolver_free(s);
	gsl_matrix_free(covar);
	gsl_rng_free(r);
	free(x); free(y); free(dy);
}
コード例 #15
0
ファイル: listcal.cpp プロジェクト: Christian-Clear/xgtools
//------------------------------------------------------------------------------
// findCorrection () : Uses a GSL Levenberg-Marquardt algorithm to fit the lines
// in FittedLines to the wavenumbers in the user-specified calibration standard.
// The result is the optimal wavenumber correction factor for the uncalibrated
// data, which is stored in the class variable WaveCorrection. Information about
// the fit residuals are saved by calling calcDiffStats().
//
void ListCal::findCorrection () {

  // Prepare the GSL Solver and associated objects. A non-linear solver is used,
  // the precise type of which is determined by SOLVER_TYPE, defined in 
  // MgstFcn.h. 
  const size_t NumParameters = 1;
  const size_t NumLines = FittedLines.size ();
  
  double GuessArr [NumParameters];
  for (unsigned int i = 0; i < NumParameters; i ++) { GuessArr[i] = WaveCorrection; }

  const gsl_multifit_fdfsolver_type *SolverType;
  gsl_multifit_fdfsolver *Solver;  
  gsl_multifit_function_fdf FitFunction;
  gsl_matrix *Covariance = gsl_matrix_alloc (NumParameters, NumParameters);
  gsl_vector_view VectorView = gsl_vector_view_array (GuessArr, NumParameters);

  FitFunction.f = &fitFn;
  FitFunction.df = &derivFn;
  FitFunction.fdf = &fitAndDerivFns;
  FitFunction.n = NumLines;
  FitFunction.p = NumParameters;
  FitFunction.params = &FittedLines;
 
  SolverType = SOLVER_TYPE;
  Solver = gsl_multifit_fdfsolver_alloc(SolverType, NumLines, NumParameters);
  gsl_multifit_fdfsolver_set (Solver, &FitFunction, &VectorView.vector);

  // Perform the fitting, one iteration at a time until one of the following
  // conditions is met: The absolute and relative changes in the fit parameters
  // become smaller than SOLVER_TOL, or the max number of allowed iterations,
  // SOLVER_MAX_ITERATIONS, is reached.
  unsigned int Iteration = 0;
  int Status;
  do {
    Iteration ++;
    Status = gsl_multifit_fdfsolver_iterate (Solver);
    if (Status) break;
    Status = gsl_multifit_test_delta (Solver->dx, Solver->x, SOLVER_TOL, SOLVER_TOL);
  } while (Status == GSL_CONTINUE && Iteration < SOLVER_MAX_ITERATIONS);

  // Output all the fit parameters with their associated error.
  gsl_multifit_covar (Solver -> J, 0.0, Covariance);
#define FIT(i) gsl_vector_get (Solver -> x, i)
#define ERR(i) sqrt (gsl_matrix_get (Covariance, i, i))

  double chi = gsl_blas_dnrm2 (Solver -> f);
  double dof = NumLines - double(NumParameters);
  double c = chi / sqrt (dof);
  
  cout << "Correction factor: " << FIT(0) << " +/- " << c*ERR(0) << " ("
    << "reduced chi^2 = " << pow(chi, 2) / dof << ", "
    << "lines fitted = " << NumLines << ", c = " << c << ")" << endl;

  // Apply the wavenumber correction to all the lines loaded from the
  // uncalibrated spectrum
  WaveCorrection = FIT(0);
  WaveCorrectionError = c*ERR(0);
  calcDiffStats ();
  cout << "dSig/Sig Mean Residual: " << DiffMean / LC_DATA_SCALE 
    << ", StdDev: " << DiffStdDev / LC_DATA_SCALE
    << ", StdErr: " << DiffStdErr / LC_DATA_SCALE << endl;

  // Clean up the memory and exit
  gsl_multifit_fdfsolver_free (Solver);
  gsl_matrix_free (Covariance);
}
コード例 #16
0
static int MLalgo(struct dataStruct *data) {
    
    /* declare solvers */
    const gsl_multifit_fdfsolver_type *T;
    gsl_multifit_fdfsolver *s;
    
    gsl_vector_view x = gsl_vector_view_array(data->x_init, data->np);
    
    const gsl_rng_type *type;
    
    gsl_rng_env_setup();
    
    type = gsl_rng_default;
    
    gsl_multifit_function_fdf f;
    f.f = &gaussian_f;
    f.df = &gaussian_df;
    f.fdf = &gaussian_fdf;
    f.n = data->nValid;
    f.p = data->np;
    f.params = data;
    
    
    T = gsl_multifit_fdfsolver_lmsder;
    s = gsl_multifit_fdfsolver_alloc(T, data->nValid, data->np);
    gsl_multifit_fdfsolver_set(s, &f, &x.vector);
    
    int status, status2;
    int iter = 0;
    gsl_vector *gradt = gsl_vector_alloc(data->np);
    
    do {
        iter++;
        status = gsl_multifit_fdfsolver_iterate(s);
        if (status)
            break;
        
        status = gsl_multifit_test_delta(s->dx, s->x, data->eAbs, data->eRel);
        gsl_multifit_gradient(s->J, s->f, gradt);
        status2 = gsl_multifit_test_gradient(gradt, data->eAbs);
    }
    while ((status == GSL_CONTINUE || status2 == GSL_CONTINUE) && iter < data->maxIter);
    
    gsl_vector_free(gradt);
    
    int i;
    for (i=0; i<data->np; ++i) {
        data->prmVect[data->estIdx[i]] = gsl_vector_get(s->x, i);
    }
    data->prmVect[3] = fabs(data->prmVect[3]);
    
    /* copy residuals */
    data->residuals = gsl_vector_alloc(data->nValid);
    gsl_vector_memcpy(data->residuals, s->f);
    
    /* copy Jacobian */
    data->J = gsl_matrix_alloc(data->nValid, data->np);
    gsl_matrix_memcpy(data->J, s->J);
    
    gsl_multifit_fdfsolver_free(s);
    return 0;
}
コード例 #17
0
ファイル: Fit1D.cpp プロジェクト: spaceyatom/mantid
/** 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;
}
コード例 #18
0
ファイル: imagetile.cpp プロジェクト: jjdmol/LOFAR
void ImageTile::FitBackground()
{

	// Chose to use the Levenberg-Marquardt solver with scaling
	const gsl_multifit_fdfsolver_type * T = gsl_multifit_fdfsolver_lmsder;

	// Construct solver
	gsl_multifit_fdfsolver *solver = gsl_multifit_fdfsolver_alloc (T, _channelCount * _scanCount, _timeOrder + _freqOrder + 1);
	if(solver == 0) throw std::exception();

	// Initialize function information structure
	gsl_multifit_function_fdf functionInfo;

	/*if(_useMPF) {
		functionInfo.f = &BaselineFunctionMPF;
		functionInfo.df = &BaselineDerivativeMPF;
		functionInfo.fdf = &BaselineCombinedMPF;
		// chose 256 bits precision for intermediate values in the evaluation of the function and its derivative
		mpf_set_default_prec (256); 
	} else {*/
		functionInfo.f = &BaselineFunction;
		functionInfo.df = &BaselineDerivative;
		functionInfo.fdf = &BaselineCombined;
	//}
	functionInfo.n = _channelCount * _scanCount;
	functionInfo.p = _timeOrder + _freqOrder + 1;
	functionInfo.params = this;

	// Initialize initial value of parameters
	//gsl_vector x;
	double x_init[_timeOrder + _freqOrder + 1];
	for(int i = 0;i < _timeOrder + _freqOrder + 1;++i)
		x_init[i] = _baselineConsts[i];
	gsl_vector_view x_view = gsl_vector_view_array (x_init, _timeOrder + _freqOrder + 1);
	
	gsl_multifit_fdfsolver_set (solver, &functionInfo, &x_view.vector);

	// Start iterating
	int status, iter=0;
	do {
		iter++;
		status = gsl_multifit_fdfsolver_iterate(solver);
		//PrintState(iter, solver);

		if (status && status != GSL_CONTINUE) {
			// std::cout << "Error: status = " << gsl_strerror (status) << std::endl;
			break;
		}

		status = gsl_multifit_test_delta(solver->dx, solver->x, 0, 0);
	} while (status == GSL_CONTINUE && iter < 250);
	
	// Save coefficients
	for(int i = 0;i<_freqOrder + _timeOrder + 1;++i)
		this->_baselineConsts[i] = gsl_vector_get(solver->x, i);

	//PrintState(iter, solver);

	// Clean up
	gsl_multifit_fdfsolver_free(solver);
}
コード例 #19
0
ファイル: APR_fit.cpp プロジェクト: fixinf/RMF-gui
double fit_n(set_const* Init, double n0){
		const gsl_multifit_fdfsolver_type *T;
		gsl_multifit_fdfsolver *s;
		int status;
		unsigned int i, iter = 0;
		const size_t n = 11;
		const size_t p = 5;
		double k = n0/0.16;
		gsl_matrix *covar = gsl_matrix_alloc (p, p);
		double y[11] = {4.45, 6.45 , 9.65, 13.29, 17.94, 22.92, 27.49, 38.82, 54.95, 75.13, 99.75}; 
		double t[11] = {k*0.02,k*0.04, k*0.08,k*0.12,k*0.16,k*0.2,k*0.24, k*0.32, k*0.4,k*0.48, k*0.56};
		struct data d = { n, y, t, Init};
		gsl_multifit_function_fdf f;
		double x_init[5] = {Init->C_s,Init->C_o, Init->b,Init->c, Init->C_r};

		//double x_init[6]  = {11.56279437,7.49931859,0.00871711,0.00267620,0.86859184,0.5};
		//double x_init[4] = { sqrt(130.746),sqrt(120.7244),1.0,10.0};
		gsl_vector_view x = gsl_vector_view_array (x_init, p);
		const gsl_rng_type * type;
		gsl_rng * r;

		gsl_rng_env_setup();

		type = gsl_rng_default;
		r = gsl_rng_alloc (type);

		f.f = &func_fit_n;
		f.df = NULL;
		f.fdf = NULL;
		f.n = n;
		f.p = p;
		f.params = &d;

		/* This is the data to be fitted */

		/*for (i = 0; i < n; i++)
		{
			double t = i;
			y[i] = 1.0 + 5 * exp (-0.1 * t) 
				+ gsl_ran_gaussian (r, 0.1);
			sigma[i] = 0.1;
			printf ("data: %u %g %g\n", i, y[i], sigma[i]);
		};*/

		T = gsl_multifit_fdfsolver_lmsder;
		
		s = gsl_multifit_fdfsolver_alloc (T, n, p);

		gsl_multifit_fdfsolver_set (s, &f, &x.vector);
	
		print_state (iter, s);

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

			//printf ("status = %s\n", gsl_strerror (status));

			print_state (iter, s);

			if (status)
				break;

			status = gsl_multifit_test_delta (s->dx, s->x,
				1e-15, 0.0);
		}
		while (status == GSL_CONTINUE && iter < 2000);

		gsl_multifit_covar (s->J, 0.0, covar);

#define FIT(i) gsl_vector_get(s->x, i)
#define ERR(i) sqrt(gsl_matrix_get(covar,i,i))


		cond(Init, FIT(0), FIT(1), FIT(2), FIT(3), FIT(4));

		{ 
			double chi = gsl_blas_dnrm2(s->f);
			double dof = n - p;
			double c = GSL_MAX_DBL(1, chi / sqrt(dof)); 
			//double c = 1.0;
			/*printf("chisq/dof = %g\n",  pow(chi, 2.0) / dof);

			printf ("Cs      = %.5f +/- %.5f\n", Init->C_s, c*ERR(0));
			printf ("Co = %.5f +/- %.5f\n", Init->C_o, c*ERR(1));
			printf ("b      = %.5f +/- %.5f\n", Init->c, c*ERR(2));
			printf ("c      = %.5f +/- %.5f\n", Init->b, c*ERR(3));
			printf ("Cr      = %.5f +/- %.5f\n", Init->C_r, c*ERR(4));*/
		}
		
	//	printf ("status = %s\n", gsl_strerror (status));
		double z = 0.65;

		
		gsl_matrix_free (covar);
		gsl_rng_free (r);

		double yi = 0;
		/*for (int i = 0; i < 11; i++){
		double yi = EoS::t_E(t[i],0, Init)/(D*t[i]) - m_n ;
		printf("n = %.3f, %.3f  %.3f  %.3f \n",
		t[i],
		yi,
		y[i],
		yi-y[i]);

		}*/
	
		/*return *(new set_const("APR_fit return constant set",FIT(0), FIT(1), 10.0, FIT(2),abs(FIT(3)), z, 
			[](double f){return (1-f);},
			[](double f){return 1.0;},
			[=](double f){return eta_o(f);},
			[](double f){return 1.0;}));*/
		double rr = gsl_blas_dnrm2(s->x);
		gsl_multifit_fdfsolver_free (s);
		return rr;
	}
コード例 #20
0
ファイル: nlfit.c プロジェクト: Ayato-Harashima/CMVS-PMVS
int
main (void)
{
  const gsl_multifit_fdfsolver_type *T;
  gsl_multifit_fdfsolver *s;
  int status;
  unsigned int i, iter = 0;
  const size_t n = N;
  const size_t p = 3;

  gsl_matrix *covar = gsl_matrix_alloc (p, p);
  double y[N], sigma[N];
  struct data d = { n, y, sigma};
  gsl_multifit_function_fdf f;
  double x_init[3] = { 1.0, 0.0, 0.0 };
  gsl_vector_view x = gsl_vector_view_array (x_init, p);
  const gsl_rng_type * type;
  gsl_rng * r;

  gsl_rng_env_setup();

  type = gsl_rng_default;
  r = gsl_rng_alloc (type);

  f.f = &expb_f;
  f.df = &expb_df;
  f.fdf = &expb_fdf;
  f.n = n;
  f.p = p;
  f.params = &d;

  /* This is the data to be fitted */

  for (i = 0; i < n; i++)
    {
      double t = i;
      y[i] = 1.0 + 5 * exp (-0.1 * t) 
                 + gsl_ran_gaussian (r, 0.1);
      sigma[i] = 0.1;
      printf ("data: %u %g %g\n", i, y[i], sigma[i]);
    };

  T = gsl_multifit_fdfsolver_lmsder;
  s = gsl_multifit_fdfsolver_alloc (T, n, p);
  gsl_multifit_fdfsolver_set (s, &f, &x.vector);

  print_state (iter, s);

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

      printf ("status = %s\n", gsl_strerror (status));

      print_state (iter, s);

      if (status)
        break;

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

  gsl_multifit_covar (s->J, 0.0, covar);

#define FIT(i) gsl_vector_get(s->x, i)
#define ERR(i) sqrt(gsl_matrix_get(covar,i,i))

  { 
    double chi = gsl_blas_dnrm2(s->f);
    double dof = n - p;
    double c = GSL_MAX_DBL(1, chi / sqrt(dof)); 

    printf("chisq/dof = %g\n",  pow(chi, 2.0) / dof);

    printf ("A      = %.5f +/- %.5f\n", FIT(0), c*ERR(0));
    printf ("lambda = %.5f +/- %.5f\n", FIT(1), c*ERR(1));
    printf ("b      = %.5f +/- %.5f\n", FIT(2), c*ERR(2));
  }

  printf ("status = %s\n", gsl_strerror (status));

  gsl_multifit_fdfsolver_free (s);
  gsl_matrix_free (covar);
  gsl_rng_free (r);
  return 0;
}
コード例 #21
0
ファイル: fitModel.C プロジェクト: anhi/ball
		void FitModel::train()
		{	
			if (descriptor_matrix_.cols() == 0)
			{
				throw Exception::InconsistentUsage(__FILE__, __LINE__, "Data must be read into the model before training!"); 
			}
			if (allEquations_.empty())
			{
				cout<<"ERROR: No equations specified! Use method setEquations first."<<endl; 
				return;
			}
				
			training_result_.resize(descriptor_matrix_.cols(), Y_.cols());
			
			for (c = 0; c < (unsigned int)Y_.cols(); c++)
			{	
 				fitY = new Eigen::MatrixXd(Y_.rows(), 1);
				for (int n = 0; n < Y_.rows(); n++)
				{
					(*fitY)(n, 0) = Y_(n, c);
				}
				
				fitX = &descriptor_matrix_;
				equation = &allEquations_[c];
				
				if (allDiffEquations_.size() < c)
				{
					diffEquations = &allDiffEquations_[c]; 
				}
				else
				{
					diffEquations = NULL; 
				}
					
				const gsl_multifit_fdfsolver_type* T = gsl_multifit_fdfsolver_lmsder; 
				gsl_multifit_fdfsolver* s = gsl_multifit_fdfsolver_alloc(T, fitX->rows(), fitX->cols()); 
				
				const size_t n = descriptor_matrix_.rows();
				const size_t p = descriptor_matrix_.cols();
				gsl_multifit_function_fdf fdf; 
						
				fdf = make_fdf(&setF, &setDf, &setFdf, n, p, 0);
				
				double* g = new double[initial_guess_.size()];
				for (unsigned int m = 0; m < initial_guess_.size(); m++)
				{
					g[m] = initial_guess_[m];
				}
				
				gsl_vector_view ini = gsl_vector_view_array (g, p);
				
				gsl_multifit_fdfsolver_set(s, &fdf, &ini.vector); 
			
				int status;
				
				for (unsigned int i = 0; i < 50; i++)
				{
					status = gsl_multifit_fdfsolver_iterate(s); 
				}
				
				// save the predicted coefficients
				for (unsigned int m = 0; m < s->x->size; m++)
				{
					training_result_(m, c) = gsl_vector_get(s->x, m);
				}
				
				delete fitY;
				delete [] g;
				gsl_multifit_fdfsolver_free(s); 
			}
			cout <<training_result_<<endl;
		}
コード例 #22
0
ファイル: cspl_qrs_fit.c プロジェクト: hsonntag/approx
int cspl_qrs_fit (void * params) {
    int status;
    unsigned int iter;
    struct cspl_qrs_data * data = (struct cspl_qrs_data *) params;
    /* This is the data to be fitted */

    gsl_multifit_function_fdf f;
    //    const gsl_rng_type * type;
    //    gsl_rng * r;

    //    gsl_rng_env_setup();

    //    type = gsl_rng_default;
    //    r = gsl_rng_alloc (type);

    f.f = &cspl_qrs_f;
    f.df = &cspl_qrs_df;
    f.fdf = &cspl_qrs_fdf;
    f.n = data->n;
    f.p = data->p;
    f.params = data;

    gsl_multifit_fdfsolver_set (data->s, &f, &data->x.vector);
    iter = 0;
    //print_state (iter, data->s);

    do
    {
        iter++;
        status = gsl_multifit_fdfsolver_iterate (data->s);
#ifdef DEBUG
        printf ("status = %s\n", gsl_strerror (status));

        print_state (iter, data->s);
#endif
        if (status)
            break;

        status = gsl_multifit_test_delta (data->s->dx, data->s->x,
                1e-12, 1e-12);
    }
    while (status == GSL_CONTINUE && iter < 500);

    gsl_multifit_covar (data->s->J, 0.0, data->covar);



    double chi = gsl_blas_dnrm2(data->s->f);
    double dof = data->n - data->p;
    double c = GSL_MAX_DBL(1, chi / sqrt(dof));
    data->c = c;
    data->chisq_pdof = pow(chi, 2.0) / dof;

#ifdef DEBUG
#define FIT(i) gsl_vector_get(data->s->x, i)
#define ERR(i) sqrt(gsl_matrix_get(data->covar,i,i))
    printf("chisq/dof = %g\n",  pow(chi, 2.0) / dof); 

    printf ("A        = %.5f +/- %.5f\n", FIT(0), c*ERR(0)); 
    printf ("t_beat   = %.5f +/- %.5f\n", FIT(1), c*ERR(1)); 
    printf ("S_0      = %.5f +/- %.5f\n", FIT(2), c*ERR(2)); 
    printf ("S_1      = %.5f +/- %.5f\n", FIT(3), c*ERR(3)); 


    printf ("status = %s\n", gsl_strerror (status));
#endif
    //    gsl_rng_free (r);
    return GSL_SUCCESS;
}
コード例 #23
0
void
test_fdf (const char * name, gsl_multifit_function_fdf * f, 
          double x0[], double x_final[], 
          double f_sumsq, double sigma[])
{
  const gsl_multifit_fdfsolver_type *T;
  gsl_multifit_fdfsolver *s;

  const size_t n = f->n;
  const size_t p = f->p;

  int status;
  size_t iter = 0;

  gsl_vector_view x = gsl_vector_view_array (x0, p);

  T = gsl_multifit_fdfsolver_lmsder;
  s = gsl_multifit_fdfsolver_alloc (T, n, p);
  gsl_multifit_fdfsolver_set (s, f, &x.vector);

  do
    {
      status = gsl_multifit_fdfsolver_iterate (s);

#ifdef DEBUG
       printf("iter = %d  status = %d  |f| = %.18e x = \n", 
         iter, status, gsl_blas_dnrm2 (s->f));
         
         gsl_vector_fprintf(stdout, s->x, "%.8e");
#endif       
      status = gsl_multifit_test_delta (s->dx, s->x, 0.0, 1e-7);

      iter++;
    }
  while (status == GSL_CONTINUE && iter < 1000);
  
  {
    size_t i;
    gsl_matrix * covar = gsl_matrix_alloc (p, p);
    gsl_multifit_covar (s->J, 0.0, covar);

    for (i = 0 ; i < p; i++)
      {
        gsl_test_rel (gsl_vector_get (s->x, i), x_final[i], 1e-5, 
                      "%s, lmsder, x%u", name, i);
      }


    {
      double s2 = pow(gsl_blas_dnrm2 (s->f), 2.0);

      gsl_test_rel (s2, f_sumsq, 1e-5, "%s, lmsder, |f|^2", name);

      for (i = 0; i < p; i++) 
        {
          double ei = sqrt(s2/(n-p))*sqrt(gsl_matrix_get(covar,i,i));
          gsl_test_rel (ei, sigma[i], 1e-4, 
                        "%s, sigma(%d)", name, i) ;
        }
    }

    gsl_matrix_free (covar);
  }

  gsl_multifit_fdfsolver_free (s);
}
コード例 #24
0
/*******************************************************************************
 * fit_gaussian
 * Fit data to a guassian and return the results. Ideally, this should give the
 * same results as scipy.optimize.curve_fit.
 * Input:
 *      hist:           Histogram to fit the gaussian to
 * Output:
 *      chisq:          Chi^2 of the histogram
 *      ndf:            Number of degrees of freedom of the fit
 *      fit_params:     Fit parameters
 ******************************************************************************/
gsl_vector *fit_gaussian(gsl_histogram *hist,
        double *chisq, long *ndf, gsl_matrix *covar){
    double tol;
    double *hbin, *hrange, bin_width, xdata, min, max;
    double magnitude, mean, sigma;
    double error, ythr;
    int status;
    long gpars, nonzero, nbins;
    long i;
    gsl_vector *pars, *fit_params;
    gsl_multifit_fdfsolver *gfit;
    gsl_multifit_function_fdf gaus;
    const gsl_multifit_fdfsolver_type *ftype;

    /* Allowed relative error is what scipy uses */
    /* tol = 1.49012e-8; scipy least squares default */
    tol = 1e-14;

    /* get number of bins containing data */
    nbins = hist -> n;
    hbin = hist -> bin;
    hrange = hist -> range;
    nonzero = 0;
    for (i=0; i<nbins; i++){
        if (hbin[i]) nonzero++;
    }

    /* Set the function */
    gaus.f = &gaus_f;
    gaus.df = &gaus_df;
    gaus.fdf = &gaus_fdf;
    gaus.n = nonzero;
    gaus.p = 3;
    gaus.params = hist;

    /* Initialize the solver */
    gpars = 3;
    pars = gsl_vector_alloc(gpars);
    gsl_vector_set_all(pars, 1.0);
    ftype = gsl_multifit_fdfsolver_lmsder;
    gfit = gsl_multifit_fdfsolver_alloc(ftype, nonzero, gpars);
    gsl_multifit_fdfsolver_set(gfit, &gaus, pars);

    /* loop the solver and solve this thing */
    do {
        status = gsl_multifit_fdfsolver_iterate(gfit);
        status = gsl_multifit_test_delta(gfit -> dx, gfit -> x, 0, tol);
    } while (status == GSL_CONTINUE);

    magnitude = gsl_vector_get(gfit -> x, 0);
    mean = gsl_vector_get(gfit -> x, 1);
    /* The fitted sigma might be negative, but it is squared when computing the
     * gaussian, so taking the absolute value of sigma is ok */
    sigma = fabs(gsl_vector_get(gfit -> x, 2));

    /* Compute the chi^2 */
    min = hrange[0];
    max = hrange[nbins];
    bin_width = (max - min) / nbins;
    *chisq = 0;
    for (i = 0; i<nbins; i++){
        if (hbin[i]){
            xdata = hrange[i] + bin_width/2.0;
            error = sqrt(hbin[i]);
            ythr = gaussian(xdata, magnitude, mean, sigma);
            *chisq += pow((hbin[i] - ythr)/error, 2);
        }
    }
    *ndf = nonzero - gpars;

    /* Copy results to return vector */
    fit_params = gsl_vector_alloc(gpars);
    gsl_vector_memcpy(fit_params, gfit -> x);

    /* Compute the covariance matrix */
    gsl_multifit_covar(gfit -> J, 0.0, covar);

    /* Free the solver's memory */
    gsl_vector_free(pars);
    gsl_multifit_fdfsolver_free(gfit);

    /* Return the results of the fit */
    return fit_params;
}
コード例 #25
0
void PlaneDetector::solve()
{
	// prepare calculation data

	DetectionData baseData;

	// prepare gsl variables
	const gsl_multifit_fdfsolver_type *T;
	gsl_multifit_fdfsolver *s;

	int n = (int)data.size();
#ifdef VECTOR_SOLVER
	const int p = 4;
	double x_init[p] = {0.0, 0.0, 1.0, 0.0};
#endif
#ifdef ANGLE_SOLVER
	const int p = 3;
//	double x_init[p] = {0.0, 0.0, 0.0};
	double x_init[p] = {0.0, 90.0 / 180.0 * M_PI, 0.0};
#endif
#ifdef VECTOR2_SOLVER
	const int p = 6;
//	double x_init[p] = {1.0, 0.0, 0.0, 500.0, 0.0, 0.0};
	double x_init[p] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
#endif
#ifdef ANGLE2_SOLVER
	const int p = 5;
	double x_init[p] = {0.0, M_PI / 2.0 + 0.1, 000.0, 0.0, 0.0};
#endif

	gsl_multifit_function_fdf f;
	f.f = &pd_func_f;
	f.df = &pd_func_df;
	f.fdf = &pd_func_fdf;
	f.n = n;
	f.p = p;
	f.params = &data;
	gsl_vector_view x = gsl_vector_view_array(x_init, p);

	T = gsl_multifit_fdfsolver_lmsder;
	s = gsl_multifit_fdfsolver_alloc(T, n, p);
	gsl_multifit_fdfsolver_set(s, &f, &x.vector);

	gsl_vector *gradt = gsl_vector_alloc(p);

	int iter = 0;
	int status;
	do
	{
		iter ++;
		status = gsl_multifit_fdfsolver_iterate(s);
		if (status)
		{
//			printf ("error: %s\n", gsl_strerror (status));
			break;
		}
		gsl_multifit_gradient(s->J, s->f, gradt);
		status = gsl_multifit_test_gradient(gradt, 1e-6);
	} while (status == GSL_CONTINUE && iter < 10000);

#ifdef VECTOR_SOLVER
	vN = Vector(
			gsl_vector_get(s->x, 0),
			gsl_vector_get(s->x, 1),
			gsl_vector_get(s->x, 2)).getUnitVector();
	fD = gsl_vector_get(s->x, 3);
#endif
#ifdef ANGLE_SOLVER
	double theta = gsl_vector_get(s->x, 0);
	double pi = gsl_vector_get(s->x, 1);
	vN = Vector(sin(pi)*cos(theta), sin(pi)*sin(theta), cos(pi));
	double d = gsl_vector_get(s->x, 2);
	fD = - ((vN & vListener) + d);
#endif
#ifdef VECTOR2_SOLVER
	vN = Vector(
			gsl_vector_get(s->x, 0),
			gsl_vector_get(s->x, 1),
			gsl_vector_get(s->x, 2)).getUnitVector();
	Vector vX1 = Vector(
			gsl_vector_get(s->x, 3),
			gsl_vector_get(s->x, 4),
			gsl_vector_get(s->x, 5));
	fD = -(vN & vX1);
#endif
#ifdef ANGLE2_SOLVER
	double theta = gsl_vector_get(s->x, 0);
	double pi = gsl_vector_get(s->x, 1);
	vN = Vector(sin(pi)*cos(theta), sin(pi)*sin(theta), cos(pi));
	Vector vX1 = Vector(
			gsl_vector_get(s->x, 2),
			gsl_vector_get(s->x, 3),
			gsl_vector_get(s->x, 4));
	fD = -(vN & vX1);
#endif

#if 0
	for (double  pp = 0; pp < M_PI; pp += 0.1)
	{
		for (double tt = 0; tt < M_PI; tt += 0.1)
		{
			Vector vNN = Vector(sin(pp)*cos(tt), sin(pp)*sin(tt), cos(pp));
			printf("vN = ");
			vNN.print();
			double sum = 0;
			for (size_t i = 0; i < data.size(); i++)
			{
				sum += pow(data[i].getF(tt, pp, fD), 2);
			}
			printf(" , sum = %f\n", sum);
		}
	}
#endif


#if 0
	double sqrsum = 0;
	for (size_t i = 0; i < data.size(); i++)
	{
#ifdef VECTOR_SOLVER
		sqrsum += pow(data[i].getF(vN, fD), 2);
#endif
#ifdef ANGLE_SOLVER
		sqrsum += pow(data[i].getF(theta, pi, fD), 2);
#endif
#ifdef VECTOR2_SOLVER
		sqrsum += pow(data[i].getF(vN, fD), 2);
#endif
//		printf ("%f/", sqrsum);
	}
	vN.print();
	printf(" %f %f\n", fD, sqrt(sqrsum));	
#endif





//	for (size_t i = 0; i < data.size(); i++)
//		printf ("F_%d = %f\n", i, data[i].getF(vN));


	gsl_vector_free(gradt);
	gsl_multifit_fdfsolver_free(s);

	vP.clear();
	for (size_t i = 0; i < data.size(); i++)
	{
		vP.push_back(data[i].getP(vN));
	}
}
コード例 #26
0
ファイル: fitting.cpp プロジェクト: zhaoyongfeng1990/DDM
//Fitting. Allow fitting multiple q curves simultaneously to decrease the chance of converging to local minimum.
void ddm::fitting()
{
    int cnum_fit=num_fit;
    int ctimeWindow=timeWindow;
    //Find the truncation time if time window is set
    for (int itert=0; itert<num_fit; ++itert)
    {
        if (tau[itert]>ctimeWindow)
        {
            cnum_fit=itert;
            break;
        }
    }
    
    //Local variables
    int cqsize=qsize-qIncreList[num_qCurve-1];  //number of fitting result
    int cnum_qCurve=num_qCurve;
    int ctnum_fit=cnum_fit*num_qCurve;
    int cnumOfPara=numOfPara+2*num_qCurve;  //Total number of parameters
    
    fittedPara=gsl_matrix_alloc(cqsize, cnumOfPara);
    //To store the fitting result and error.
    fitErr=gsl_matrix_alloc(cqsize, cnumOfPara);
    status = new int[cqsize];		//Record the status of fitting.
    
    //Using Levenberg-Marquardt algorithm as implemented in the scaled lmder routine in minpack. Jacobian is given.
    const gsl_multifit_fdfsolver_type *solverType = gsl_multifit_fdfsolver_lmsder;
    
    int progress=0;		//Indicator of progress.
    
    //Objects to do numerical inverse Laplace transformation
#ifdef ISFRTD
    NILT NILT1(OMP_NUM_THREADS), NILT2(OMP_NUM_THREADS), NILT3(OMP_NUM_THREADS), NILT4(OMP_NUM_THREADS);
#endif
    
#ifdef ISFRTDP
    NILT NILT1(OMP_NUM_THREADS), NILT2(OMP_NUM_THREADS), NILT3(OMP_NUM_THREADS), NILT4(OMP_NUM_THREADS), NILT5(OMP_NUM_THREADS);
#endif
    
#ifdef ISFRTDPTT
    NILT NILT1(OMP_NUM_THREADS), NILT2(OMP_NUM_THREADS), NILT3(OMP_NUM_THREADS), NILT4(OMP_NUM_THREADS), NILT5(OMP_NUM_THREADS), NILT6(OMP_NUM_THREADS);
#endif
    
#ifdef ISFRTDPfix
    NILT NILT1(OMP_NUM_THREADS), NILT2(OMP_NUM_THREADS);
    
    const long double vbar=vbarGuess;
    const long double sigma=sigmaGuess;
    
    const long double vbsigma2=vbar/sigma/sigma;
    const long double vb2sigma2=vbsigma2*vbar;
    const long double logvbsigma2=log(vbsigma2);
    const long double logfactor=vb2sigma2*logvbsigma2-gsl_sf_lngamma(vb2sigma2);
    const long double cpsiz1=logvbsigma2-gsl_sf_psi(vb2sigma2);
    const long double vb2sigma3=vb2sigma2/sigma;
#endif
    
#ifdef ISFRTDPTTfix
    NILT NILT1(OMP_NUM_THREADS), NILT2(OMP_NUM_THREADS), NILT3(OMP_NUM_THREADS);
    
    const long double vbar=vbarGuess;
    const long double sigma=sigmaGuess;
    
    const long double vbsigma2=vbar/sigma/sigma;
    const long double vb2sigma2=vbsigma2*vbar;
    const long double logvbsigma2=log(vbsigma2);
    const long double logfactor=vb2sigma2*logvbsigma2-gsl_sf_lngamma(vb2sigma2);
    const long double cpsiz1=logvbsigma2-gsl_sf_psi(vb2sigma2);
    const long double vb2sigma3=vb2sigma2/sigma;
#endif
    
#pragma omp parallel for
    for (int iterq=0; iterq<cqsize; ++iterq)
    {
        //Data array which is going to present to the fitting algorithm
        double* datafit=new double[ctnum_fit];
        double* qList=new double[cnum_qCurve];
        double* time=new double[ctnum_fit];
        //Truncate the data, and put multiple curves into one array
        for (int iterqc=0; iterqc<cnum_qCurve; ++iterqc)
        {
            for (int iterf = 0; iterf < cnum_fit; ++iterf)
            {
                datafit[iterf+iterqc*cnum_fit]=(gsl_matrix_get(datag, iterq+qIncreList[iterqc], iterf));		//Fitting in log scale.
                time[iterf+iterqc*cnum_fit]=tau[iterf];
            }
            qList[iterqc]=qabs[iterq+qIncreList[iterqc]];
        }
        
        gsl_multifit_function_fdf fitfun;		//Pointer of function to fit.
        dataStruct sdata;		//GSL data structure
        
        //Data is passed to ISFfun by sdata
        sdata.data=datafit;
        sdata.tau=time;
        sdata.q=qList;
        sdata.num_fit=cnum_fit;
        sdata.num_qCurve=cnum_qCurve;
        
#ifdef ISFRTD
        sdata.ISFILT=&NILT1;
        sdata.dvISFILT=&NILT2;
        sdata.dDISFILT=&NILT3;
        sdata.dlambdaISFILT=&NILT4;
#endif
        
#ifdef ISFRTDP
        sdata.ISFILT=&NILT1;
        sdata.dvbarISFILT=&NILT2;
        sdata.dsigmaISFILT=&NILT3;
        sdata.dDISFILT=&NILT4;
        sdata.dlambdaISFILT=&NILT5;
#endif
        
#ifdef ISFRTDPTT
        sdata.ISFILT=&NILT1;
        sdata.dvbarISFILT=&NILT2;
        sdata.dsigmaISFILT=&NILT3;
        sdata.dDISFILT=&NILT4;
        sdata.dlambdaISFILT=&NILT5;
        sdata.dTTISFILT=&NILT6;
#endif
        
#ifdef ISFRTDPfix
        sdata.alpha=alphaGuess;
        sdata.D=DGuess;
        sdata.vbar=vbar;
        sdata.sigma=sigma;
        
        sdata.vbsigma2=vbsigma2;
        sdata.logfactor=logfactor;
        sdata.vb2sigma2=vb2sigma2;
        sdata.cpsiz1=cpsiz1;
        sdata.vb2sigma3=vb2sigma3;
        sdata.ISFILT=&NILT1;
        sdata.dlambdaISFILT=&NILT2;
#endif
        
#ifdef ISFRTDPTTfix
        sdata.alpha=alphaGuess;
        sdata.D=DGuess;
        sdata.vbar=vbar;
        sdata.sigma=sigma;
        
        sdata.vbsigma2=vbsigma2;
        sdata.logfactor=logfactor;
        sdata.vb2sigma2=vb2sigma2;
        sdata.cpsiz1=cpsiz1;
        sdata.vb2sigma3=vb2sigma3;
        sdata.ISFILT=&NILT1;
        sdata.dlambdaISFILT=&NILT2;
        sdata.dTTISFILT=&NILT3;
#endif
        
        //API
        fitfun.f=&ISFfun;
#ifdef NoJacobian
        fitfun.df=0;
        fitfun.fdf=0;
#else
        fitfun.df=&dISFfun;
        fitfun.fdf=&fdISFfun;
#endif
        fitfun.n=ctnum_fit;
        fitfun.p=cnumOfPara;
        fitfun.params=&sdata;
        
        //Initialization of the parameters
        double* localinipara=new double[cnumOfPara];
        for (int iterp=0; iterp<numOfPara; ++iterp)
        {
            localinipara[iterp]=inipara[iterp];
        }
        //Estimation of A(q) and B(q)
        for (int iterqc=0; iterqc<num_qCurve; ++iterqc)
        {
            localinipara[numOfPara+1+2*iterqc] = gsl_matrix_get(datag, iterq+qIncreList[iterqc], 0);
            localinipara[numOfPara+2*iterqc] = gsl_matrix_get(datag, iterq+qIncreList[iterqc], num_fit-1)-localinipara[numOfPara+1+2*iterqc];
        }
        //Initiallization of the solver
        gsl_vector_view para=gsl_vector_view_array(localinipara, cnumOfPara);
        gsl_multifit_fdfsolver* solver = gsl_multifit_fdfsolver_alloc(solverType, ctnum_fit, cnumOfPara);
        gsl_multifit_fdfsolver_set(solver, &fitfun, &para.vector);
        int iter=0;
        //gsl_vector* g=gsl_vector_alloc(numOfPara);
        
        //For debugging and monitering the iterations
//        cout << qList[0] << ' ' << qList[1] << '\n';
//        for (int iterpara=0; iterpara<cnumOfPara; ++iterpara)
//        {
//            cout << gsl_vector_get(solver->x, iterpara) << '\n';
//        }
//        cout << '\n';
        
        int cstatus=GSL_CONTINUE;   //Current status
        do
        {
            gsl_multifit_fdfsolver_iterate(solver);		//Iterate one step.
            cstatus = norm0_rel_test(solver->dx, solver->x, 1e-7, 1e-7);  //Test the exiting criteria
            
            //For debugging and monitering the iterations
//            for (int iterpara=0; iterpara<cnumOfPara; ++iterpara)
//            {
//                cout << gsl_vector_get(solver->x, iterpara) << '\n';
//            }
//            cout << '\n';
            
            //If to use other exiting criteria
            //gsl_multifit_gradient(solver->J,solver->f, g);
            //status[iterq-1]=gsl_multifit_test_gradient(g, 1e-5);
            //			status[iterq - 1] = covar_rel_test(solver->J, solver->x, 1e-4);
            
            ++iter;
            //Number of iterations exceed certain limitation
            if (iter>maxIter)
            {
                cstatus=GSL_EMAXITER;
            }
        } while (cstatus == GSL_CONTINUE);
        status[iterq]=cstatus;
        //gsl_vector_free(g);
        
        //Estimating the error.
        gsl_matrix* covar=gsl_matrix_alloc(cnumOfPara, cnumOfPara);
        gsl_multifit_covar(solver->J, 0.0, covar);
        for (int iterpara=0; iterpara<cnumOfPara; ++iterpara)	//Record result.
        {
            gsl_matrix_set(fittedPara, iterq, iterpara, gsl_vector_get(solver->x, iterpara) );
            gsl_matrix_set(fitErr, iterq, iterpara, sqrt(gsl_matrix_get(covar, iterpara, iterpara)) );    //Not presice in log scale
        }
        gsl_matrix_free(covar);
        gsl_multifit_fdfsolver_free(solver);
        
        //Output to standard I/O
        progress+=1;
        cout << "Fitted q=" << qabs[iterq] << " at iter=" << iter << ", " << 100.0*progress / qsize << "% completed from thread No." << omp_get_thread_num() << ", "<< gsl_strerror(status[iterq]) << "." << '\n';
        for (int iterpara=0; iterpara<cnumOfPara; ++iterpara)
        {
            cout << gsl_matrix_get(fittedPara, iterq, iterpara) << '\n';
        }
        cout << '\n';
        delete [] datafit;
        delete [] qList;
        delete [] localinipara;
        delete [] time;
    }
}
コード例 #27
0
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
ファイル: Fit.cpp プロジェクト: gitter-badger/AlphaPlot
double *Fit::fitGslMultifit(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_multifit_function_fdf f;
  f.f = d_f;
  f.df = d_df;
  f.fdf = d_fdf;
  f.n = d_n;
  f.p = d_p;
  f.params = &data;

  // initialize solver
  const gsl_multifit_fdfsolver_type *T;
  switch (d_solver) {
    case ScaledLevenbergMarquardt:
      T = gsl_multifit_fdfsolver_lmsder;
      break;
    case UnscaledLevenbergMarquardt:
      T = gsl_multifit_fdfsolver_lmder;
      break;
    default:
      break;
  }
  gsl_multifit_fdfsolver *s = gsl_multifit_fdfsolver_alloc(T, d_n, d_p);
  gsl_multifit_fdfsolver_set(s, &f, d_param_init);

  // iterate solver algorithm
  for (iterations = 0; iterations < d_max_iterations; iterations++) {
    status = gsl_multifit_fdfsolver_iterate(s);
    if (status) break;

    status = gsl_multifit_test_delta(s->dx, s->x, d_tolerance, d_tolerance);
    if (status != GSL_CONTINUE) break;
  }

  // grab results
  for (int i = 0; i < d_p; i++) result[i] = gsl_vector_get(s->x, i);
  gsl_blas_ddot(s->f, s->f, &chi_2);
#if GSL_MAJOR_VERSION < 2
  gsl_multifit_covar(s->J, 0.0, covar);
#else
  {
    gsl_matrix J;
    gsl_multifit_fdfsolver_jac(s, &J);
    gsl_multifit_covar(&J, 0.0, covar);
  }
#endif
  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, so that
    // s->f is properly normalized)
    gsl_matrix_scale(covar, chi_2 / (d_n - d_p));
  }

  // free memory allocated for fitting
  gsl_multifit_fdfsolver_free(s);

  return result;
}
コード例 #29
0
    GammaDistributionFitter::GammaDistributionFitResult GammaDistributionFitter::fit(vector<DPosition<2> > & input)
    {
      const gsl_multifit_fdfsolver_type * T = NULL;
      gsl_multifit_fdfsolver * s = NULL;

      int status = 0;
      size_t iter = 0;

      const size_t p = 2;

      gsl_multifit_function_fdf f;
      double x_init[2] = { init_param_.b, init_param_.p };
      gsl_vector_view x = gsl_vector_view_array(x_init, p);
      const gsl_rng_type * type = NULL;
      gsl_rng * r = NULL;

      gsl_rng_env_setup();

      type = gsl_rng_default;
      r = gsl_rng_alloc(type);

      f.f = &gammaDistributionFitterf_;
      f.df = &gammaDistributionFitterdf_;
      f.fdf = &gammaDistributionFitterfdf_;
      f.n = input.size();
      f.p = p;
      f.params = &input;

      T = gsl_multifit_fdfsolver_lmsder;
      s = gsl_multifit_fdfsolver_alloc(T, input.size(), p);
      gsl_multifit_fdfsolver_set(s, &f, &x.vector);

#ifdef GAMMA_DISTRIBUTION_FITTER_VERBOSE
      printState_(iter, s);
#endif

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

#ifdef GAMMA_DISTRIBUTION_FITTER_VERBOSE
        printf("status = %s\n", gsl_strerror(status));
        printState_(iter, s);
#endif

        if (status)
        {
          break;
        }

        status = gsl_multifit_test_delta(s->dx, s->x, 1e-4, 1e-4);
#ifdef GAMMA_DISTRIBUTION_FITTER_VERBOSE
        printf("Status = '%s'\n", gsl_strerror(status));
#endif
      }
      while (status == GSL_CONTINUE && iter < 1000);

#ifdef GAMMA_DISTRIBUTION_FITTER_VERBOSE
      printf("Final status = '%s'\n", gsl_strerror(status));
#endif

      if (status != GSL_SUCCESS)
      {
        gsl_rng_free(r);
        gsl_multifit_fdfsolver_free(s);

        throw Exception::UnableToFit(__FILE__, __LINE__, __PRETTY_FUNCTION__, "UnableToFit-GammaDistributionFitter", "Could not fit the gamma distribution to the data");
      }

      // write the result in a GammaDistributionFitResult struct
      GammaDistributionFitResult result;
      result.b = gsl_vector_get(s->x, 0);
      result.p = gsl_vector_get(s->x, 1);

      // build a formula with the fitted parameters for gnuplot
      stringstream formula;
      formula << "f(x)=" << "(" << result.b << " ** " << result.p << ") / gamma(" << result.p << ") * x ** (" << result.p << " - 1) * exp(- " << result.b << " * x)";
      gnuplot_formula_ = formula.str();

#ifdef GAMMA_DISTRIBUTION_FITTER_VERBOSE
      cout << gnuplot_formula_ << endl;
#endif

      gsl_rng_free(r);
      gsl_multifit_fdfsolver_free(s);

      return result;
    }
コード例 #30
0
ファイル: lm.c プロジェクト: ArtTucker/Systemic2
int K_minimize_lm(ok_kernel* k, int maxiter, double params[]) {
    double min_chi_par = 1e-4;
    K_calculate(k);
    double prev_chi2 = k->chi2;
    bool high_df = false;
    int max_iter_at_scale = 200;
    double initial_st = 1.;
    
    int max_kt = 1;
    for (int i = 0; i < k->ndata; i++)
        if (k->compiled[i][T_FLAG] == T_TIMING) {
            high_df = true;
            max_kt = 2;
            max_iter_at_scale = 500;
            break;
        }
    
    if (params != NULL) {
        int i = 0;
        while (true) {
            if (params[i] == DONE)
                break;
            if (params[i] == OPT_LM_MINCHI_PAR) 
                min_chi_par = params[i+1];
            else if (params[i] == OPT_LM_HIGH_DF) 
                high_df = !((int) params[i+1] == 0);
            else if (params[i] == OPT_LM_MAX_ITER_AT_SCALE) 
                max_iter_at_scale = (int) params[i+1];
            else if (params[i] == OPT_LM_INITIAL_SCALE)
                initial_st = params[i+1];
            i+=2;
        }
    }
    unsigned int npars = 0;
    
    // Count all the parameters to minimize on
    for (int i = 1; i < k->system->nplanets + 1; i++)
        for (int j = 0; j < ELEMENTS_SIZE; j++)
            npars += (MIGET(k->plFlags, i, j) & MINIMIZE ? 1 : 0);
    for (int i = 0; i < k->parFlags->size; i++)
        npars += (VIGET(k->parFlags, i) & MINIMIZE ? 1 : 0);

    if (npars == 0)
        return 0;
    
    // Create a pointer table (flat array -> matrices)
    double** pars = (double**) malloc(sizeof(double*) * npars);
    double prevpars[npars];
    
    double* steps = (double*) malloc(npars * sizeof(double));
    double* stepscale = (double*) malloc(npars * sizeof(double));
    int* parstype = (int*) malloc(npars * sizeof(int));
    
    gsl_vector* x = gsl_vector_alloc(npars);
    
    
    int idx = 0;
    for (int i = 1; i < k->system->nplanets + 1; i++)
        for (int j = 0; j < ELEMENTS_SIZE; j++)
            if (MIGET(k->plFlags, i, j) & MINIMIZE) {
                pars[idx] = gsl_matrix_ptr(k->system->elements, i, j);
                x->data[idx] = MGET(k->system->elements, i, j);
                prevpars[idx] = x->data[idx];
                steps[idx] = stepscale[idx] = MGET(k->plSteps, i, j);
                parstype[idx] = j;
                
                if (steps[idx] < 1e-10) {
                    printf("Warning: step for element %d of planet %d is <= 0\n", j, i);
                }
                
                idx++;
            }

    for (int i = 0; i < k->parFlags->size; i++)
        if (VIGET(k->parFlags, i) & MINIMIZE) {
            pars[idx] = gsl_vector_ptr(k->params, i);
            x->data[idx] = VGET(k->params, i);
            prevpars[idx] = x->data[idx];
            steps[idx] = stepscale[idx] = VGET(k->parSteps, i);
            parstype[idx] = PARTYPE_PAR;
            
            if (steps[idx] < 1e-10)
                printf("Warning: step for parameter %d is <= 0\n", i);
            
            idx++;
        }
        
    
    
    gsl_multifit_fdfsolver * s
        = gsl_multifit_fdfsolver_alloc (gsl_multifit_fdfsolver_lmsder, k->ndata, npars);
    
    
    
    
    ok_lm_params sp;
    sp.k = k;
    sp.pars = pars;
    sp.best = (double*) malloc(sizeof(double) * npars);
    sp.stepscale = stepscale;
    sp.compiled = k->compiled;
    sp.f0 = (double*) malloc(sizeof(double)*k->ndata);
    sp.f1 = (double*) malloc(sizeof(double)*k->ndata);
    sp.f2 = (double*) malloc(sizeof(double)*k->ndata);
    sp.f3 = (double*) malloc(sizeof(double)*k->ndata);
    sp.parstype = parstype;
    sp.ndata = k->ndata;
    sp.iterations = 0;
    sp.maxiterations = maxiter;
    sp.npars = npars;
    sp.every = (k->intMethod == KEPLER ? 10 : 1);
    sp.status = PROGRESS_CONTINUE;
    sp.high_df = high_df;
    sp.min_chi = k->chi2;
    sp.st = initial_st;
    
    for (int i = 0; i < npars; i++)
        sp.best[i] = *(pars[i]);
    
    gsl_multifit_function_fdf fdf;
    fdf.f = &K_lm_f;
    fdf.df = &K_lm_jac;
    fdf.fdf = &K_lm_fdf;
    fdf.n = k->ndata;
    fdf.p = npars;
    fdf.params = &sp;
    
    gsl_multifit_fdfsolver_set (s, &fdf, x);
    
    bool improved = true;
    int status = 0;
    int kt = 0;
    int tot_iter = 0;
    int iter_at_scale = 0;
    
    
    bool last_ditch = false;
    while (improved || last_ditch) {
        k->flags |= NEEDS_SETUP;
        iter_at_scale = 0;
        
        while (true) {
            double chi2 = sp.min_chi;
            int status = gsl_multifit_fdfsolver_iterate (s);

            iter_at_scale++;
            tot_iter++;
            if (chi2 - sp.min_chi > min_chi_par)
                iter_at_scale = 0;
            
            if (status || iter_at_scale > max_iter_at_scale) {
                break;
            }
        }
        
        gsl_multifit_fdfsolver_set (s, &fdf, x);
        
        
        for (int i = 0; i < npars; i++) {
            *(pars[i]) = sp.best[i];
            x->data[i] = sp.best[i];
        }
        
        k->flags |= NEEDS_SETUP;
        K_calculate(k);
        
        if (fabs(prev_chi2 - sp.min_chi)/fabs(sp.min_chi) > 1e-2 && iter_at_scale > 1) {
            kt = 0;
            last_ditch = false;
        } else {
            sp.st *= 0.1;
        }
        
        improved = (kt < max_kt || fabs(sp.min_chi - prev_chi2)/fabs(sp.min_chi) > 1e-2);
        
        if (last_ditch)
            break;
        
        if (! improved && kt <= 3) {
            last_ditch = true;
            sp.st *= 0.1;
        }
        
        kt++;
        //printf("-> %d %d %d %e %e, last_ditch=%d\n", iter_at_scale, kt, improved, sp.st, sp.min_chi, last_ditch);
        prev_chi2 = k->chi2;
        
        for (int idx = 0; idx < npars; idx++)
            stepscale[idx] = steps[idx] * sp.st;
        
        if (sp.iterations > maxiter || sp.st < 1e-12)
            break;
    }
    
    for (int i = 0; i < npars; i++) {
        *(pars[i]) = sp.best[i];
        x->data[i] = sp.best[i];
    }

    k->flags |= NEEDS_SETUP;
    K_calculate(k);

    
    free(sp.stepscale);
    free(sp.f0);
    free(sp.f1);
    free(sp.f2);
    free(sp.f3);
    free(sp.pars);
    free(sp.parstype);
    free(sp.best);
    
    if (sp.status == PROGRESS_STOP)
        return PROGRESS_STOP;
    else 
        return status;
   
}