示例#1
0
/*
 * 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);
}
/*******************************************************************************
 * 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;
}
示例#3
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;
   
}
示例#4
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;
}
示例#5
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);
}
f_all_sol do_fit_duplex(f_info *f, int n, real *t_min, real *t_max, bool bVerbose, bool bUpdate)
{
	int i,j,k;
	int iter=0;
	int tot_points=0;
	int status;
	int tot_abs=0;
	int tot_inv_t=0;
	real inv_t=0;
	real tss_inv=0;
	real mean_inv_t=0;
	real abs_t=0;
	real mean_abs_t=0;
	real tss_abs=0;
	real tss_tot=0;
	f_all_sol fit;
	f_info *local_f;

	snew(local_f,n);

	// count points within boundaries, allocate 
	// and copy to new array. Only copy the xp (derivative)
	// as is the one that matters for the fitting
	for(i=0; i<n; i++){
		for(j=0; j<f[i].nts; j++){
			if( f[i].xp[0][j] >= t_min[i] && f[i].xp[0][j] <= t_max[i] ) { local_f[i].nts++ ; }
		}
		snew(local_f[i].xp[0],local_f[i].nts); 
		snew(local_f[i].xp[1],local_f[i].nts); 
	}
	// now copy the data
	// not only the derivatives of the absorbance, also the conc
	k=0;
	for(i=0; i<n; i++){
		local_f[i].conc = f[i].conc ;
		for(j=0; j<f[i].nts; j++){
			if( f[i].xp[0][j] >= t_min[i] && f[i].xp[0][j] <= t_max[i] ) { 
				local_f[i].xp[0][k] = f[i].xp[0][j] ;
				local_f[i].xp[1][k] = f[i].xp[1][j] ;
				// we use this loop to compute the TSS, the total sum of squares of the
				// "y" data, to be used for r_squared after we know chi_sq
				abs_t += local_f[i].xp[1][k] ;
				tot_abs++;
				k++;
			}
		}
		k=0;
	}

	// Total number of points to fit
	size_t pp = 4;
    const gsl_multifit_fdfsolver_type *T;
    T = gsl_multifit_fdfsolver_lmsder;
    gsl_multifit_fdfsolver *s;
    // do a fit for each triplex curve
    for (i=0; i<n; i++){
        // Total number of points to fit
        if (bVerbose){printf("Working on curve n %d\n",i);}
        struct fit_data d = { n,i, local_f};
        tot_points = local_f[i].nts ;
        gsl_matrix *covar = gsl_matrix_alloc (pp, pp);
        gsl_multifit_function_fdf ff;
        gsl_vector *x;
        x = gsl_vector_alloc(pp);
        gsl_vector_set(x,0,f[i].tm2);
        gsl_vector_set(x,1,f[i].c);
        gsl_vector_set(x,2,-70);
        gsl_vector_set(x,3,-0.1);
        s = gsl_multifit_fdfsolver_alloc (T, tot_points, pp);
        // copy data to function
        ff.f = &eq_fit;
        ff.df = NULL;
        ff.fdf = NULL;
        ff.p = pp;
        // total number of points is total of points
        // in the curve plus the number of points for the inv. fit
        ff.n = tot_points;
        ff.params = &d;
        gsl_multifit_fdfsolver_set (s, &ff, x);

        iter=0;
        do
        {
            iter++;
            status = gsl_multifit_fdfsolver_iterate (s);
            if(bVerbose){
                printf ("iter: %3u x = % 15.8f % 15.8f %15.8f "
                        "|f(x)| = %g\n",iter,
                        gsl_vector_get (s->x, 0),
                        gsl_vector_get (s->x, 1),
                        gsl_vector_get (s->x, 2),
                        gsl_blas_dnrm2 (s->f));
            }

            if (status)
                break;
            status = gsl_multifit_test_delta (s->dx, s->x,
                    1e-8, 1e-8);
        }
        while (status == GSL_CONTINUE && iter < 500);
        gsl_multifit_covar (s->J, 0.0, covar);
        gsl_matrix_free (covar);
        gsl_vector_free(x);
    // copy tm2 data adjusted from each curve
        local_f[i].tm2 = gsl_vector_get(s->x, 0);
    }

    //free first solver
    gsl_multifit_fdfsolver_free (s);

    // do the 1/tm vs ln(ct) fitting
    const gsl_multifit_fdfsolver_type *Tl;
    gsl_multifit_fdfsolver *sl;
    // fit params in the straight line
    int ppl = 2;
    gsl_matrix *covarl = gsl_matrix_alloc (ppl, ppl);
    struct fit_data dl = { n,i, local_f};
    gsl_multifit_function_fdf ffl;
    gsl_vector *xl;
    xl = gsl_vector_alloc(ppl);
    // DH and DS
    gsl_vector_set(xl,0,-70);
    gsl_vector_set(xl,1,-0.1);
    Tl = gsl_multifit_fdfsolver_lmsder;
    sl = gsl_multifit_fdfsolver_alloc (Tl, n, ppl);
    // copy data to function
    ffl.f=&eq_fit_straight;
    ffl.df = NULL;
    ffl.fdf = NULL;
    ffl.p = ppl;
    // total number of points the number of curves
    ffl.n = n;
    ffl.params = &dl;
    gsl_multifit_fdfsolver_set (sl, &ffl, xl);

    iter=0;
    do
    {
        iter++;
        status = gsl_multifit_fdfsolver_iterate (sl);
        if(bVerbose){
            printf ("iter: %3u x = % 15.8f % 15.8f "
                    "|f(x)| = %g\n",iter,
                    gsl_vector_get (sl->x, 0),
                    gsl_vector_get (sl->x, 1),
                    gsl_blas_dnrm2 (sl->f));
        }

        if (status)
            break;
        status = gsl_multifit_test_delta (sl->dx, sl->x,
                1e-8, 1e-8);
    }
    while (status == GSL_CONTINUE && iter < 500);
    gsl_multifit_covar (sl->J, 0.0, covarl);

    #define FIT(i) gsl_vector_get(sl->x, i)
    #define ERR(i) sqrt(gsl_matrix_get(covarl,i,i))

    // compute contribution of inverse temperature to TSS
    for(i=0;i<n;i++){
        inv_t += ((real)1.0/(real)local_f[i].tm2);
        tot_inv_t++;
    }
    mean_inv_t = inv_t / (real)tot_inv_t;
    for(i=0;i<n;i++){
        tss_inv += (1.0/(real)local_f[i].tm2 - mean_inv_t ) * (1.0/(real)local_f[i].tm2 - mean_inv_t);
    }

    if (bUpdate){
        fit.dh2 = gsl_vector_get(sl->x, 0);
        fit.ds2 = gsl_vector_get(sl->x, 1);
        fit.dg2   = fit.dh2 - 298.15*fit.ds2;
        for(i=0; i<n; i++){
            f[i].tm2 = local_f[i].tm2 ;
        }
    }

    tss_tot = tss_inv ;

    double chi = gsl_blas_dnrm2(sl->f);
    fit.r2 = 1.0 - ( chi*chi / tss_tot ) ;
    double dof = n - ppl;
    double c = GSL_MAX_DBL(1, chi / sqrt(dof));

    if(bVerbose)
    {
        printf ("chisq/dof = %g\n",  pow(chi, 2.0) / dof);
        printf ("r2      = %g\n",  fit.r2);
        printf ("DH3    = %.5f +/- %.5f\n", FIT(0), c*ERR(0));
        printf ("DS3    = %.5f +/- %.5f\n", FIT(1), c*ERR(1));
        printf ("DG3    = %.5f +/- %.5f\n", FIT(0)-298*FIT(1),c*ERR(1)+c*298*ERR(0));
        printf ("status = %s\n", gsl_strerror (status));
    }

    gsl_multifit_fdfsolver_free (sl);
    gsl_matrix_free (covarl);
    gsl_vector_free(xl);

    return fit;
}
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 */
}
示例#8
0
int kstfit_general_levenberg_marquardt(const double *const inArrays[], const int inArrayLens[],
              const double inScalars[], double *outArrays[], int outArrayLens[],
              double outScalars[], const char* inStrings[], char *outStrings[])
{
  KST_UNUSED(outStrings);

  int iReturn = -1;

  if (inArrayLens[X] >= 2 && inArrayLens[Y] >= 2) {
    mu::Parser parser;
    double* pResult[4];
    double* pDelete = 0L;
    double* pInputX;
    double* pInputY;
    double *parameters;
    double tolerance = inScalars[0];
    double xvar;
    char *token;
    char *toSplit;
    char *endPtr;
    int maxIterations = (int)inScalars[1];
    int n = inArrayLens[0];
    int paramsNumber = 2;
    int startsNumber = 0;
    int iLengthData;
    int i;
    int j;

    iLengthData = inArrayLens[X];
    if( inArrayLens[Y] > iLengthData ) {
      iLengthData = inArrayLens[Y];
    }

    if (inArrayLens[X] == iLengthData) {
      pInputX = (double*)inArrays[X];
    } else {
      pDelete = (double*)malloc(iLengthData * sizeof( double ));
      pInputX = pDelete;
      for( i=0; i<iLengthData; i++) {
        pInputX[i] = interpolate( i, iLengthData, inArrays[X], inArrayLens[X] );
      }
    }

    if (inArrayLens[Y] == iLengthData) {
      pInputY = (double*)inArrays[Y];
    } else {
      pDelete = (double*)malloc(iLengthData * sizeof( double ));
      pInputY = pDelete;
      for( i=0; i<iLengthData; i++) {
        pInputY[i] = interpolate( i, iLengthData, inArrays[Y], inArrayLens[Y] );
      }
    }

    //
    // count the number of parameter names
    //
    toSplit = strdup(inStrings[1]);
    token = strtok( toSplit, ",;:" );
    while( token != NULL ) {
      paramsNumber++;
      token = strtok( NULL, ",;:" );
    }
    free(toSplit);

    if( iLengthData > paramsNumber ) {
      if( outArrayLens[0] != iLengthData ) {
        pResult[0] = (double*)realloc( outArrays[0], iLengthData * sizeof( double ) );
      } else {
        pResult[0] = outArrays[0];
      }

      if( outArrayLens[1] != iLengthData ) {
        pResult[1] = (double*)realloc( outArrays[1], iLengthData * sizeof( double ) );
      } else {
        pResult[1] = outArrays[1];
      }

      if( outArrayLens[2] != paramsNumber ) {
        pResult[2] = (double*)realloc( outArrays[2], paramsNumber * sizeof( double ) );
      } else {
        pResult[2] = outArrays[2];
      }

      if( outArrayLens[3] != paramsNumber * paramsNumber ) {
        pResult[3] = (double*)realloc( outArrays[3], paramsNumber * paramsNumber * sizeof( double ) );
      } else {
        pResult[3] = outArrays[3];
      }

      if( pResult[0] != NULL &&
          pResult[1] != NULL &&
          pResult[2] != NULL &&
          pResult[3] != NULL ) {
        outArrays[0] = pResult[0];
        outArrayLens[0] = iLengthData;
        outArrays[1] = pResult[1];
        outArrayLens[1] = iLengthData;
        outArrays[2] = pResult[2];
        outArrayLens[2] = paramsNumber;
        outArrays[3] = pResult[3];
        outArrayLens[3] = paramsNumber * paramsNumber;

        parameters = new double[paramsNumber];
        for (i=0; i<paramsNumber; i++) {
          parameters[i] = 0.0;
        }
        paramsNumber = 0;

        //
        // set the parameter names
        //
        toSplit = strdup(inStrings[1]);
        token = strtok( toSplit, ",;:" );
        while( token != NULL ) {
          char *paramName = strdup(token);
          char *paramPointer = paramName;

          while (paramPointer[0] == ' ') {
            paramPointer++;
          }
          while (paramPointer[strlen(paramPointer)] == ' ') {
            paramPointer[strlen(paramPointer)] = '\0';
          }

          try {
            parser.DefineVar(paramPointer, &parameters[paramsNumber]);
          } catch (mu::Parser::exception_type &e) {
          }

          paramsNumber++;
          token = strtok( NULL, ",;:" );
          free( paramName );
        }
        free(toSplit);

        //
        // set parameter initial guesses
        //
        double pInit[paramsNumber];
        toSplit = strdup(inStrings[2]);
        token = strtok( toSplit, ",;:" );
        while( token != NULL ) {
          pInit[startsNumber] = strtod(token, &endPtr);
          startsNumber++;
          token = strtok( NULL, ",;:" );
        }
        free(toSplit);

        for (i=startsNumber; i<paramsNumber; i++) {
          pInit[i] = 0.0;
        }

        if (strstr(inStrings[0], "pi") != 0L) {
          parser.DefineConst("pi", M_PI);
        }
        if (strstr(inStrings[0], "Pi") != 0L) {
          parser.DefineConst("Pi", M_PI);
        }
        if (strstr(inStrings[0], "PI") != 0L) {
          parser.DefineConst("PI", M_PI);
        }
        parser.DefineVar("x", &xvar);
        parser.SetExpr(inStrings[0]);

        gsl_vector_view x = gsl_vector_view_array(pInit, paramsNumber);

        struct fit d = { n, inArrays[0], inArrays[1], outArrays[0], &xvar, parameters, paramsNumber, &parser };

        const gsl_multifit_fdfsolver_type *T = gsl_multifit_fdfsolver_lmsder;

        gsl_multifit_fdfsolver *s = gsl_multifit_fdfsolver_alloc(T, n, paramsNumber);
        if (s != 0L) {
          gsl_multifit_function_fdf f;
          gsl_matrix *covar = gsl_matrix_alloc(paramsNumber, paramsNumber);
          if (covar != 0L) {
            f.f = &function_f;
            f.df = &function_df;
            f.fdf = &function_fdf;
            f.n = n;
            f.p = paramsNumber;
            f.params = &d;

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

            int status;
            int iteration = 0;

            do {
              iteration++;
              status = gsl_multifit_fdfsolver_iterate(s);
              if (status) {
                break;
              }
              status = gsl_multifit_test_delta(s->dx, s->x, tolerance, tolerance);
            } while (status == GSL_CONTINUE && iteration < maxIterations);

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

            for( i=0; i<n; i++ ) {
              xvar = inArrays[0][i];

              try {
                outArrays[0][i] = parser.Eval();
                outArrays[1][i] = inArrays[1][i] - outArrays[0][i];
              } catch (mu::Parser::exception_type &e) {
                outArrays[0][i] = 0.0;
                outArrays[1][i] = 0.0;
              }
            }

            for (i=0; i<paramsNumber; i++) {
              outArrays[2][i] = parameters[i];
              for (j=0; j<paramsNumber; j++) {
                outArrays[3][(i*paramsNumber)+j] = gsl_matrix_get( covar, i, j );
              }
            }

            //
            // determine the value of chi^2/nu
            //
            outScalars[0] = gsl_blas_dnrm2( s->f );

            iReturn = 0;

            gsl_matrix_free(covar);
          }

          gsl_multifit_fdfsolver_free(s);
        }
      }
    }

    if( pDelete )
    {
      free( pDelete );
    }
  }

  return iReturn;
}
示例#9
0
static void
test_fdf(const gsl_multifit_fdfsolver_type * T, const double xtol,
         const double gtol, const double ftol,
         const double epsrel, const double x0_scale,
         test_fdf_problem *problem,
         const double *wts)
{
  gsl_multifit_function_fdf *fdf = problem->fdf;
  const size_t n = fdf->n;
  const size_t p = fdf->p;
  const size_t max_iter = 1500;
  gsl_vector *x0 = gsl_vector_alloc(p);
  gsl_vector_view x0v = gsl_vector_view_array(problem->x0, p);
  gsl_multifit_fdfsolver *s = gsl_multifit_fdfsolver_alloc (T, n, p);
  const char *pname = problem->name;
  char sname[2048];
  int status, info;

  sprintf(sname, "%s/scale=%g%s",
    gsl_multifit_fdfsolver_name(s), x0_scale,
    problem->fdf->df ? "" : "/fdiff");

  /* scale starting point x0 */
  gsl_vector_memcpy(x0, &x0v.vector);
  test_scale_x0(x0, x0_scale);

  if (wts)
    {
      gsl_vector_const_view wv = gsl_vector_const_view_array(wts, n);
      gsl_multifit_fdfsolver_wset(s, fdf, x0, &wv.vector);
    }
  else
    gsl_multifit_fdfsolver_set(s, fdf, x0);

  status = gsl_multifit_fdfsolver_driver(s, max_iter, xtol, gtol,
                                         ftol, &info);
  gsl_test(status, "%s/%s did not converge, status=%s",
           sname, pname, gsl_strerror(status));

  /* check solution */
  test_fdf_checksol(sname, pname, epsrel, s, problem);

  if (wts == NULL)
    {
      /* test again with weighting matrix W = I */
      gsl_vector *wv = gsl_vector_alloc(n);

      sprintf(sname, "%s/scale=%g%s/weights",
        gsl_multifit_fdfsolver_name(s), x0_scale,
        problem->fdf->df ? "" : "/fdiff");

      gsl_vector_memcpy(x0, &x0v.vector);
      test_scale_x0(x0, x0_scale);

      gsl_vector_set_all(wv, 1.0);
      gsl_multifit_fdfsolver_wset(s, fdf, x0, wv);
  
      status = gsl_multifit_fdfsolver_driver(s, max_iter, xtol, gtol,
                                             ftol, &info);
      gsl_test(status, "%s/%s did not converge, status=%s",
               sname, pname, gsl_strerror(status));

      test_fdf_checksol(sname, pname, epsrel, s, problem);

      gsl_vector_free(wv);
    }

  gsl_multifit_fdfsolver_free(s);
  gsl_vector_free(x0);
}
示例#10
0
gsl_vector* least_square_nl_fit(struct data dat, struct parameters par, gsl_multifit_function_fdf f)
{
	size_t n, p;
	int status, i, iter = 0; 
	double *x_init;
	const gsl_rng_type * type;
	const gsl_multifit_fdfsolver_type *T;
	gsl_multifit_fdfsolver *s;
	
	n = dat.n;
	p = par.n;
		
	gsl_matrix *covar = gsl_matrix_alloc(p,p);

	x_init = (double *) calloc(par.n, sizeof(double));

		for(i=0; i<par.n; i++) 
			x_init[i] = par.guess_p[i];
		

		gsl_vector_view x = gsl_vector_view_array (x_init, p);
		gsl_rng * r;
		gsl_rng_env_setup();
     
    	   	type = gsl_rng_default;
    	   	r = gsl_rng_alloc (type);

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

#ifdef PRINT_INFO
	       print_state (iter, s);
#endif

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

#ifdef PRINT_INFO
	       print_state (iter, s);
#endif

           if (status)
             break;
     
           status = gsl_multifit_test_delta (s->dx, s->x,
                                             1e-6, 1e-6);
         }
       while (status == GSL_CONTINUE && iter < 500);
     
#ifdef PRINT_INFO
	       print_state (iter, s);
#endif

       gsl_multifit_covar (s->J, 0.0, covar);
     
       { 
       gsl_matrix_free (covar);
       gsl_rng_free (r);
     }

	return s->x;
       gsl_multifit_fdfsolver_free (s);
}
示例#11
0
文件: gsl_fit.c 项目: annube/hadron
SEXP multifit_cor(SEXP par, SEXP Thalf, SEXP x, SEXP y, SEXP err, SEXP tr, 
		  SEXP prec, SEXP N, SEXP max_iter, SEXP no_masses)
{
  int npar, nx, ny, i, iter_max;
  double p1, p2, m;
  double *yp, *errp, *parp, *precp, *statep;
  double chi_square, red_chi_square;
  int dof;
  int * xp, *Thalfp, *trp, *Np, *mip, *nmp;
  SEXP state;
  const gsl_multifit_fdfsolver_type *solver_type =
    gsl_multifit_fdfsolver_lmsder;
  /*  Allocate the solver. */
  gsl_multifit_fdfsolver *solver;
  /*  Initialize the data structure. */
  struct data data_struct;
  gsl_multifit_function_fdf function_fdf;
  gsl_matrix *covar;
  double * para_initial, c=1.;
  gsl_vector_view para_initial_;
  int status, iter=0, no_points=0;

  PROTECT(par = AS_NUMERIC(par));
  PROTECT(Thalf = AS_INTEGER(Thalf));
  PROTECT(x = AS_INTEGER(x));
  PROTECT(y = AS_NUMERIC(y));
  PROTECT(err = AS_NUMERIC(err));
  PROTECT(tr = AS_INTEGER(tr));
  PROTECT(prec = AS_NUMERIC(prec));
  PROTECT(N = AS_INTEGER(N));
  PROTECT(max_iter = AS_INTEGER(max_iter));
  PROTECT(no_masses = AS_INTEGER(no_masses));

  xp = INTEGER_POINTER(x);
  Thalfp = INTEGER_POINTER(Thalf);
  trp = INTEGER_POINTER(tr);
  Np = INTEGER_POINTER(N);
  yp = NUMERIC_POINTER(y);
  errp = NUMERIC_POINTER(err);
  parp = NUMERIC_POINTER(par);
  precp = NUMERIC_POINTER(prec);
  mip = INTEGER_POINTER(max_iter);
  nmp = INTEGER_POINTER(no_masses);
  iter_max = mip[0];

  npar = LENGTH(par);
  nx = LENGTH(x);
  ny = LENGTH(y);

  assert(npar == nmp[0]*(Np[0]+1));
  PROTECT(state = NEW_NUMERIC(5+npar));
  statep = NUMERIC_POINTER(state);

/*   PROTECT(gradient = allocMatrix(REALSXP, npar, npar)); */
  
  if(Np[0] == 2) no_points = 3*trp[0];
  if(Np[0] == 4) no_points = 10*trp[0];
  if(Np[0] == 6) no_points = 21*trp[0];

  solver = gsl_multifit_fdfsolver_alloc(solver_type, ny, npar);

  data_struct.x = (double*) malloc(nx*sizeof(double));
  data_struct.y = (double*) malloc(ny*sizeof(double));
  data_struct.err = (double*) malloc(ny*sizeof(double));
  para_initial = (double*) malloc(npar*sizeof(double));
  for(i = 0; i < nx; i++) {
    data_struct.x[i] = (double)xp[i];
  }

  for(i = 0; i < ny; i++) {
    data_struct.y[i] = yp[i];
    data_struct.err[i] = errp[i];
  }

  data_struct.Thalf = Thalfp[0];
  data_struct.tr = trp[0];
  data_struct.N = Np[0];
  data_struct.no_masses = nmp[0];

  // The ansatz.
  function_fdf.f = &exp_f;
  function_fdf.df = &exp_df;
  function_fdf.fdf = &exp_fdf;
  function_fdf.n = ny;
  function_fdf.p = npar;
  function_fdf.params = &data_struct;

  for(i = 0; i < npar; i++) {
    para_initial[i] = parp[i];
  }

  para_initial_ = gsl_vector_view_array(para_initial, npar);

  gsl_multifit_fdfsolver_set(solver, &function_fdf, &para_initial_.vector);

  // Perform the fit.
  // Print the initial state.
#ifdef _DEBUG
  Print_State_Mass_Fit_Helper_1(iter, solver);
#endif

  do {
    iter++;
    
    /*  Do a solver iteration. */
    status = gsl_multifit_fdfsolver_iterate(solver);
#ifdef _DEBUG
    fprintf(stderr, "status = %s.\n", gsl_strerror(status));
    Print_State_Mass_Fit_Helper_1(iter, solver);
#endif
    
    if(status) {
      break;
    }

    status = gsl_multifit_test_delta(solver->dx, solver->x,
				     precp[0], precp[1]);

  }
  while(status == GSL_CONTINUE && iter < iter_max);
#ifdef _DEBUG
  fprintf(stderr, "\n");
#endif
  
  // *****
  
  
  // Compute the covariance matrix.

  covar = gsl_matrix_alloc(npar, npar);
  gsl_multifit_covar(solver->J, 0.0, covar);

  // Output.

  chi_square = pow(gsl_blas_dnrm2(solver->f), 2.0);
#ifdef _DEBUG
  fprintf(stderr, "chi_square = %13.6lf.\n", chi_square);
#endif
  dof = no_points - npar;
#ifdef _DEBUG
  fprintf(stderr, "dof = %d\n", dof);
#endif
  red_chi_square = chi_square / (double)dof;
#ifdef _DEBUG
  fprintf(stderr, "red_chi_square = %13.6lf.\n", red_chi_square);
  fprintf(stderr, "\n");
#endif
  p1 = gsl_vector_get(solver->x, 0);
  p2 = gsl_vector_get(solver->x, 1);
  m = gsl_vector_get(solver->x, npar-1);

  if(red_chi_square > 1.0)
    c = sqrt(red_chi_square);
#ifdef _DEBUG
  fprintf(stderr, "p1 = %+9.6lf +/- %9.6lf.\n",
      p1, c * sqrt(gsl_matrix_get(covar, 0, 0)));
  fprintf(stderr, "p2 = %+9.6lf +/- %9.6lf.\n",
      p2, c * sqrt(gsl_matrix_get(covar, 1, 1)));
  fprintf(stderr, "m = %+9.6lf +/- %9.6lf.\n",
      m, c * sqrt(gsl_matrix_get(covar, npar-1, npar-1)));
  fprintf(stderr, "\n");
  fprintf(stderr, "status = %s.\n", gsl_strerror(status));
  fprintf(stderr, "\n");
#endif

  for(i = 0; i < npar; i++) {
    statep[5+i] =  gsl_vector_get(solver->x, i);
  }

  statep[0] = chi_square;
  statep[1] = gsl_blas_dnrm2(solver->f);
  statep[2] = (double)iter;
  statep[3] = (double)dof;
  statep[4] = (double)status;

  
  gsl_multifit_fdfsolver_free(solver);
#ifdef _DEBUG
  gsl_matrix_free(covar);
#endif

  free(data_struct.x);
  free(data_struct.y);
  free(data_struct.err);
  free(para_initial);

  UNPROTECT(11);
  return(state);
}
示例#12
0
/** Executes the algorithm
 *
 *  @throw runtime_error Thrown if algorithm cannot execute
 */
void Fit1D::exec()
{

  // Custom initialization
  prepare();

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

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

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

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

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

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

  int m_minX;
  int m_maxX;

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

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

  afterDataRangedDetermined(m_minX, m_maxX);

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

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

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

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

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

  l_data.Y = &YValues[m_minX];

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


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

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


  // set-up initial guess for fit parameters

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

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


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

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


  // set-up GSL least squares container

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

  // set-up remaining GSL machinery for least squared

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

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

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

  // finally do the fitting

  int iter = 0;
  int status;
  double size; // for simplex algorithm
  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;

      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;
}
示例#13
0
int main(){
    const int max_mu_size=601;
    const int zero_pad_size=pow(2,15);
    FILE *in;
    in= fopen("mean.chi", "r");
    gsl_matrix *e = gsl_matrix_alloc(max_mu_size, 4);
    gsl_vector * kvar=gsl_vector_alloc(max_mu_size);
    gsl_vector * muvar=gsl_vector_alloc(max_mu_size);
    gsl_vector * mu_0pad=gsl_vector_alloc(zero_pad_size);
    gsl_vector * r_0pad=gsl_vector_alloc(zero_pad_size/2); //half of lenght 
    gsl_vector * kvar_0pad=gsl_vector_alloc(zero_pad_size);

    gsl_matrix_fscanf(in, e);
    fclose(in);

    gsl_matrix_get_col(kvar,e,0);
    gsl_matrix_get_col(muvar,e,1);
    gsl_vector_set_zero(mu_0pad);
    gsl_matrix_free(e);


    double dk=gsl_vector_get (kvar, 1)-gsl_vector_get (kvar, 0);
    double dr=M_PI/float(zero_pad_size-1)/dk;

    for (int i = 0; i < zero_pad_size; i++)
    {
      gsl_vector_set (kvar_0pad, i, dk*i);
    }
    for (int i = 0; i < zero_pad_size/2; i++)
    {
      gsl_vector_set (r_0pad, i, dr*i);
    }
    for (int i = 0; i < max_mu_size; i++)
    {
      gsl_vector_set (mu_0pad, i, gsl_vector_get (muvar, i));
    }

    gsl_vector *mu_widowed=gsl_vector_alloc(zero_pad_size);
    gsl_vector_memcpy (mu_widowed, mu_0pad);
    double kmin=4.0, kmax=17.0, dwk=0.8;
    hanning(mu_widowed, kvar_0pad, kmin, kmax, dwk);


    //FFT transform
    double *data = (double *) malloc(zero_pad_size*sizeof(double)); 
    //new double [zero_pad_size] ;
    memcpy(data, mu_widowed->data, zero_pad_size*sizeof(double));
    gsl_fft_real_radix2_transform(data, 1, zero_pad_size);

    //Unpack complex vector
    gsl_vector_complex *fourier_data = gsl_vector_complex_alloc (zero_pad_size);
    gsl_fft_halfcomplex_radix2_unpack(data, fourier_data->data, 1, zero_pad_size);
    gsl_vector *fftR_real = gsl_vector_alloc(fourier_data->size/2);
    gsl_vector *fftR_imag = gsl_vector_alloc(fourier_data->size/2);
    gsl_vector *fftR_abs  = gsl_vector_alloc(fourier_data->size/2);
    complex_vector_parts(fourier_data, fftR_real, fftR_imag);
    complex_vector_abs(fftR_abs, fftR_real, fftR_imag);
    
    gsl_vector *first_shell=gsl_vector_alloc(fftR_abs->size);
    gsl_vector_memcpy (first_shell, fftR_abs);
    double rmin=0.2, rmax=3.0, dwr=0.1;
    hanning(first_shell, r_0pad, rmin, rmax, dwr);


    //feff0001.dat
    const int path_lines=68; 
    e = gsl_matrix_alloc(path_lines, 7); 
    gsl_vector * k_p  =gsl_vector_alloc(path_lines);
    gsl_vector * phc_p=gsl_vector_alloc(path_lines);
    gsl_vector * mag_p=gsl_vector_alloc(path_lines);
    gsl_vector * pha_p=gsl_vector_alloc(path_lines);
    gsl_vector * lam_p=gsl_vector_alloc(path_lines);
    
    in= fopen("feff0001.dat", "r");
    gsl_matrix_fscanf(in, e);
    fclose(in);
    
    gsl_matrix_get_col(k_p  ,e,0);
    gsl_matrix_get_col(phc_p,e,1);
    gsl_matrix_get_col(mag_p,e,2);
    gsl_matrix_get_col(pha_p,e,3);
    gsl_matrix_get_col(lam_p,e,5);
    gsl_matrix_free(e);

    gsl_interp_accel *acc = gsl_interp_accel_alloc ();
    gsl_spline *k_spline   = gsl_spline_alloc (gsl_interp_cspline, path_lines);
    gsl_spline *phc_spline = gsl_spline_alloc (gsl_interp_cspline, path_lines);
    gsl_spline *mag_spline = gsl_spline_alloc (gsl_interp_cspline, path_lines);
    gsl_spline *pha_spline = gsl_spline_alloc (gsl_interp_cspline, path_lines);
    gsl_spline *lam_spline = gsl_spline_alloc (gsl_interp_cspline, path_lines);

    gsl_spline_init (k_spline  , k_p->data, k_p->data  , path_lines);
    gsl_spline_init (phc_spline, k_p->data, phc_p->data, path_lines);
    gsl_spline_init (mag_spline, k_p->data, mag_p->data, path_lines);
    gsl_spline_init (pha_spline, k_p->data, pha_p->data, path_lines);
    gsl_spline_init (lam_spline, k_p->data, lam_p->data, path_lines);


    gsl_vector * mu_p  =gsl_vector_alloc(path_lines);

    //struct fit_params { student_params t; double kshift; double S02; double N; inter_path splines; };
    //student_params t   = {2.45681867, 0.02776907, -21.28920008, 9.44741797, 0.0, 0.0, 0.0};

    splines.acc=acc; splines.phc_spline=phc_spline; splines.mag_spline=mag_spline;
    splines.pha_spline=pha_spline; splines.lam_spline=lam_spline;
    
    
    fit_params fp = { 2.45681867, 0.02776907, -21.28920008, 9.44741797, 1.0, 0.0};
    compute_itegral(k_p, &fp, mu_p);

    //mu_data_fit params = { k_p, mu_p};
    mu_data.k  = kvar_0pad;
    mu_data.mu = mu_0pad;
    mu_data.mu_ft = first_shell;
    mu_data.r = r_0pad;
    mu_data.kmin = kmin;
    mu_data.kmax = kmax;
    mu_data.rmin = rmin;
    mu_data.rmax = rmax;
    mu_data.dwk = dwk;
    mu_data.dwr = dwr;


    // initialize the solver
    size_t Nparams=6;
    gsl_vector *guess0 = gsl_vector_alloc(Nparams);

    gsl_vector_set(guess0, 0, 2.4307);
    gsl_vector_set(guess0, 1, 0.040969);
    gsl_vector_set(guess0, 2, 0.001314);
    gsl_vector_set(guess0, 3, 7835);
    gsl_vector_set(guess0, 4,  1.0);
    gsl_vector_set(guess0, 5,  0.0);


    gsl_vector *fit_r = gsl_vector_alloc(r_0pad->size);

    
    compute_itegral_r(&mu_data, fp, fit_r);
    gsl_matrix *plotting = gsl_matrix_calloc(r_0pad->size, 3);
    gsl_matrix_set_col (plotting, 0,  r_0pad);
    gsl_matrix_set_col (plotting, 1,  first_shell);
    gsl_matrix_set_col (plotting, 2,  fit_r);
    plot_matplotlib(plotting);
    gsl_matrix_free (plotting);
    


    gsl_multifit_function_fdf fit_mu_k;
    fit_mu_k.f = &resudial_itegral_r;
    fit_mu_k.n = MAX_FIT_POINTS;
    fit_mu_k.p = Nparams;
    fit_mu_k.params = &mu_data;
    fit_mu_k.df = NULL;
    fit_mu_k.fdf = NULL;




    gsl_multifit_fdfsolver *solver = gsl_multifit_fdfsolver_alloc(gsl_multifit_fdfsolver_lmsder, MAX_FIT_POINTS, Nparams);
    gsl_multifit_fdfsolver_set(solver, &fit_mu_k, guess0);

    size_t iter=0, status;
    do{
        iter++;
        //cout << solver->x->data[0] << " " << solver->x->data[1] <<endl;
        status = gsl_multifit_fdfsolver_iterate (solver);
        //printf("%12.4f %12.4f %12.4f\n", solver->J->data[0,0], solver->J->data[1,1], solver->J->data[2,2] );
        //gsl_multifit_fdfsolver_dif_df  (k_p, &fit_mu_k, mu_p, solver->J);
        //gsl_multifit_fdfsolver_dif_fdf (k_p, &fit_mu_k, mu_p, solver->J);
        for (int i =0; i< solver->x->size; i++){
            printf("%14.5f", gsl_vector_get (solver->x, i)) ;
        }
        printf("\n") ;

        if (status) break;
        status = gsl_multifit_test_delta (solver->dx, solver->x, 1e-4, 1e-4);
    }while (status == GSL_CONTINUE && iter < 100);

    gsl_vector * mu_fit  =gsl_vector_alloc(path_lines);
    fit_params fitp = { solver->x->data[0], solver->x->data[1],\
                        solver->x->data[2], solver->x->data[3],\
                        solver->x->data[4], solver->x->data[5]};
    compute_itegral(k_p, &fitp, mu_fit);



        fp.mu=gsl_vector_get (solver->x, 0);
        fp.sig=gsl_vector_get (solver->x, 1);
        fp.skew=gsl_vector_get (solver->x, 2);
        fp.nu=gsl_vector_get (solver->x, 3);
        fp.S02=gsl_vector_get (solver->x, 4);
        fp.kshift=gsl_vector_get (solver->x, 5);
        
        compute_itegral_r(&mu_data, fp, fit_r);
        //gsl_matrix *plotting = gsl_matrix_calloc(r_0pad->size, 3);
        gsl_matrix_set_col (plotting, 0,  r_0pad);
        gsl_matrix_set_col (plotting, 1,  first_shell);
        gsl_matrix_set_col (plotting, 2,  fit_r);
        int min_r=search_max(r_0pad, 0.);
        int max_r=search_max(r_0pad, 4.);
        gsl_matrix_view plotting_lim = gsl_matrix_submatrix (plotting, min_r, 0, max_r-min_r, plotting->size2);
        plot_matplotlib(&plotting_lim.matrix);
        gsl_matrix_free (plotting);


    //cout << gsl_spline_eval (k_spline, 1.333, acc) << endl;
    //cout << gsl_spline_eval (phc_spline, 1.333, acc) << endl;


    //cout << data[0] << "\t" << data[1] << "\t" << data[2] << "\t" << endl;
    //cout << fourier_data->data[0] << "\t" << fourier_data->data[1] << "\t" << fourier_data->data[2] << "\t" << endl;

   
    //Plotting
    /*
    gsl_matrix *plotting = gsl_matrix_calloc(zero_pad_size, 3);
    gsl_matrix_set_col (plotting, 0, kvar_0pad);
    gsl_matrix_set_col (plotting, 1, mu_0pad);
    gsl_matrix_set_col (plotting, 2, mu_widowed);
    int max_k=search_max(kvar_0pad, 35.);
    int min_k=search_max(kvar_0pad, 1.0);
    gsl_matrix_view plotting_lim = gsl_matrix_submatrix (plotting, min_k, 0, max_k-min_k, 3);
    plot_matplotlib(&plotting_lim.matrix);
    gsl_matrix_free (plotting);
    */

    /*
    gsl_matrix *plotting = gsl_matrix_calloc(zero_pad_size, 2);
    gsl_matrix_set_col (plotting, 0, r_0pad);
    gsl_matrix_set_col (plotting, 1, mu_0pad);
    int max_k=search_max(kvar_0pad, 35.);
    int min_k=search_max(kvar_0pad, 1.0);
    gsl_matrix_view plotting_lim = gsl_matrix_submatrix (plotting, min_k, 0, max_k-min_k, 3);
    plot_matplotlib(&plotting_lim.matrix);
    gsl_matrix_free (plotting);
    */
    /*  
    gsl_matrix *plotting = gsl_matrix_calloc(r_0pad->size, 5);
    gsl_matrix_set_col (plotting, 0,  r_0pad);
    gsl_matrix_set_col (plotting, 1,  fftR_abs);
    gsl_matrix_set_col (plotting, 2,  fftR_real);
    gsl_matrix_set_col (plotting, 3,  fftR_imag);
    gsl_matrix_set_col (plotting, 4,  first_shell);
    
    int min_r=search_max(r_0pad, 0.);
    int max_r=search_max(r_0pad, 5.);
    gsl_matrix_view plotting_lim = gsl_matrix_submatrix (plotting, min_r, 0, max_r-min_r, plotting->size2);
    plot_matplotlib(&plotting_lim.matrix);
    //plot_matplotlib(plotting);
    gsl_matrix_free (plotting);
    */






    //cout << "Done" << endl;
    //cout << data[1] <<"\t" << data[2] << endl;
    
    //for (int i = 0; i < kvar->size; i++)
    //{
    //    cout << gsl_vector_get (kvar, i) <<"\t" << gsl_vector_get (muvar, i) << endl;
    //}

}
    int Cornea::computeCentre(const std::vector<Eigen::Vector3d, Eigen::aligned_allocator<Eigen::Vector3d> > &led_pos, // LED locations
                              const std::vector<Eigen::Vector3d, Eigen::aligned_allocator<Eigen::Vector3d> > &glint_pos,
                              std::vector<double> &gx_guesses,
                              Eigen::Vector3d &centre,
                              double &err) {

        // initialise the cornea tracker
        create(led_pos, glint_pos);

        /*
         * Check out usage and more info about GSL:
         * http://www.csse.uwa.edu.au/programming/gsl-1.0/gsl-ref_35.html
         */

        const size_t n = 3 * pairsOfTwo(data.size());	// number of functions
        const size_t p = gx_guesses.size();				// number of parameters

        // initial guesses
        gsl_vector_const_view x = gsl_vector_const_view_array(gx_guesses.data(), p);

        gsl_multifit_function_fdf f;
        f.f			= &my_f;	// function
        f.df		= &my_df;	// derivative
        f.fdf		= &my_fdf;	// both
        f.n			= n;		// number of functions
        f.p			= p;		// number of parameters
        f.params	= this;		// additional parameter

        const gsl_multifit_fdfsolver_type *T = gsl_multifit_fdfsolver_lmsder;
        gsl_multifit_fdfsolver *solver = gsl_multifit_fdfsolver_alloc(T, n, p);
        gsl_multifit_fdfsolver_set(solver, &f, &x.vector);


        int status;
        unsigned int iter = 0;

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

            if(status) {
                break;
            }

            status = gsl_multifit_test_delta(solver->dx, solver->x, PRECISION, PRECISION);

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

        if(iter == MAX_ITER) {
            printf("Cornea::computeCentre(): iter = MAX_ITER\n");
        }


        gsl_matrix *covar = gsl_matrix_alloc(p, p);
        gsl_multifit_covar(solver->J, 0.0, covar);

        // for(int row = 0; row < p; ++row) {
        //     for(int col = 0; col < p; ++col) {
        //         printf("%.2f ", covar->data[row * p + col]);
        //     }
        //     printf("\n");
        // }
        // printf("*****************************\n");

        /***********************************************************************
         * Compute the fit error
         **********************************************************************/

        err = 0;
        for(size_t i = 0; i < p; i++) {
            err += gsl_matrix_get(covar, i, i);
        }
        err = std::sqrt(err);


        Eigen::Vector3d cw(0.0, 0.0, 0.0);

        // cornea sphere radius
        const double RHO = trackerSettings.RHO;

        // remove this
        double dMaxX = -10.0;

        for(size_t i = 0; i < data.size(); ++i) {

            const DATA_FOR_CORNEA_COMPUTATION &cur_data = data[i];

            const double gx_guess = gsl_vector_get(solver->x, i);

            const double B_aux = atan2(gx_guess * tan(cur_data.alpha_aux), (cur_data.l_aux - gx_guess));

            // calculate the corneal sphere centers in the auxiliary coordinate systems
            const Eigen::Vector3d c_aux(gx_guess - RHO * sin((cur_data.alpha_aux - B_aux) / 2.),
                                        0.,
                                        gx_guess * tan(cur_data.alpha_aux) + RHO * cos((cur_data.alpha_aux - B_aux) / 2.));

            const Eigen::Vector3d tmp = cur_data.R * c_aux;

            cw(0) += tmp(0);
            cw(1) += tmp(1);
            cw(2) += tmp(2);

            if(tmp(0) > dMaxX) {
                dMaxX = tmp(0);
            }

            //        printf("%i: centre (mm): %.2f %.2f %.2f\n", (int)i, 1000.0*tmp(0), 1000.0*tmp(1), 1000.0*tmp(2));

        }

        const double nof_samples = (double)data.size();
        centre << cw(0) / nof_samples, cw(1) / nof_samples, cw(2) / nof_samples;


        // printf("Avg: %.2f %.2f %.2f\n", 1000.0*centre(0), 1000.0*centre(1), 1000.0*centre(2));
        // printf("*********************************\n");

        gsl_multifit_fdfsolver_free(solver);
        gsl_matrix_free(covar);

        return (int)iter;

    }