Esempio n. 1
0
int main(void)
{
	long idum=(-911);
	int i,j,mfit=MA,*ia;
	float chisq,*beta,*x,*y,*sig,**covar,**alpha;
	static float a[MA+1]=
		{0.0,5.0,2.0,3.0,2.0,5.0,3.0};
	static float gues[MA+1]=
		{0.0,4.9,2.1,2.9,2.1,4.9,3.1};

	ia=ivector(1,MA);
	beta=vector(1,MA);
	x=vector(1,NPT);
	y=vector(1,NPT);
	sig=vector(1,NPT);
	covar=matrix(1,MA,1,MA);
	alpha=matrix(1,MA,1,MA);
	/* First try sum of two gaussians */
	for (i=1;i<=NPT;i++) {
		x[i]=0.1*i;
		y[i]=0.0;
		y[i] += a[1]*exp(-SQR((x[i]-a[2])/a[3]));
		y[i] += a[4]*exp(-SQR((x[i]-a[5])/a[6]));
		y[i] *= (1.0+SPREAD*gasdev(&idum));
		sig[i]=SPREAD*y[i];
	}
	for (i=1;i<=mfit;i++) ia[i]=1;
	for (i=1;i<=mfit;i++) a[i]=gues[i];
	mrqcof(x,y,sig,NPT,a,ia,MA,alpha,beta,&chisq,fgauss);
	printf("\nmatrix alpha\n");
	for (i=1;i<=MA;i++) {
		for (j=1;j<=MA;j++) printf("%12.4f",alpha[i][j]);
		printf("\n");
	}
	printf("vector beta\n");
	for (i=1;i<=MA;i++) printf("%12.4f",beta[i]);
	printf("\nchi-squared: %12.4f\n\n",chisq);
	/* Next fix one line and improve the other */
	mfit=3;
	for (i=1;i<=mfit;i++) ia[i]=0;
	for (i=1;i<=MA;i++) a[i]=gues[i];
	mrqcof(x,y,sig,NPT,a,ia,MA,alpha,beta,&chisq,fgauss);
	printf("matrix alpha\n");
	for (i=1;i<=mfit;i++) {
		for (j=1;j<=mfit;j++) printf("%12.4f",alpha[i][j]);
		printf("\n");
	}
	printf("vector beta\n");
	for (i=1;i<=mfit;i++) printf("%12.4f",beta[i]);
	printf("\nchi-squared: %12.4f\n\n",chisq);
	free_matrix(alpha,1,MA,1,MA);
	free_matrix(covar,1,MA,1,MA);
	free_vector(sig,1,NPT);
	free_vector(y,1,NPT);
	free_vector(x,1,NPT);
	free_vector(beta,1,MA);
	free_ivector(ia,1,MA);
	return 0;
}
Esempio n. 2
0
void mrqminbd(double	x[],		// x values of dataset
			  double	y[],		// y values of dataset
			  double	sig[],		// individual std. deviations
			  int		npts,		// number of data points
			  double	p[],		// function parameters p
			  double	lb[],		// lower bounds on function parameters
			  double	ub[],		// upper bounds on function parameters
			  int		npar,		// number of function parameters
			  int		ip[],		// indices of parameters to fit
			  int		nfit,		// number of parameters to fit
			  double	**covar,	// returned covariance matrix
			  double	**alpha,	// returned curvature matrix
			  double	beta[],		// returned chi^2 partials matrix
			  double	*chisq,		// returned chi^2 value
			  double	(*funcs)(double,	// function x value, returns f(p, x)
								 double [],	// function parameters p
								 double [],	// returned df/dp values
								 int),		// number of parameters
			  double	*lambda) {	// returned curvature diagonal scaling factor

	// declare variables
	// some are static because of repeated calls

	static double	ochisq;		// old chi^2
	static double	*ptry;		// function parameters to test
	static double	*dp;		// parameter increments
	int				inverr;		// matrix inversion error
	int				j, k;		// loop counters

	// first call has scaling < 0 for initialization

	if (*lambda < 0.0) {
		ptry = (double *) mxCalloc(npar, sizeof(double));
		dp = (double *) mxCalloc(npar, sizeof(double));

		// assign initial parameters

		for (j = 0; j < npar; j++) {
			ptry[j] = p[j];
		}

		// return initial chi^2, curvature & chi^2 partial derivatives

		*lambda = FIRST_ALAMBDA;
		mrqcof(x, y, sig, npts, ptry, npar, ip, nfit, alpha, beta, chisq, funcs);
		ochisq = (*chisq);
		return;
	}

	// augment diagonal curvature values with lambda

	for (j = 0; j < nfit; j++) {
		for (k = 0; k < nfit; k++) {
			covar[j][k] = alpha[j][k];
		}
		covar[j][j] *= 1.0 + (*lambda);
		dp[j] = beta[j];
	}

	// solve for covariance & parameter increments
	// trial is unsuccessful if matrix inversion error

	inverr = gaussj(covar, dp, nfit);
	if (inverr < 0) {
		*lambda *= INC_ALAMBDA;
		return;
	}

	// last call has lambda = 0
	// rearrange matrices & free allocated space

	if (*lambda == 0.0) {
		if (nfit < npar) {
			ArrangeFixed(alpha, beta, npar, ip, nfit, SORT_BKWD);
			ArrangeFixed(covar, dp, npar, ip, nfit, SORT_BKWD);
		}
		mxFree((void *) dp);
		mxFree((void *) ptry);
		return;
	}

	// increment parameters to see if trial succeeded
	// trial is unsuccessful if bounds are exceeded

	for (j = 0; j < nfit; j++) {
		ptry[ip[j]] = p[ip[j]] + dp[j];
		if (mxIsFinite(lb[ip[j]]) && (ptry[ip[j]] <= lb[ip[j]])) {
			*lambda *= INC_ALAMBDA;
			return;
		}
		else if (mxIsFinite(ub[ip[j]]) && (ptry[ip[j]] >= ub[ip[j]])) {
			*lambda *= INC_ALAMBDA;
			return;
		}
	}

	// obtain updated chi^2, curvature & chi^2 partial derivatives
	// note that covar & dp are used to preserve alpha & beta if step fails

	mrqcof(x, y, sig, npts, ptry, npar, ip, nfit, covar, dp, chisq, funcs);

	// if successful, accept new parameters
	// decrease lambda

	if (*chisq < ochisq) {
		*lambda *= DEC_ALAMBDA;
		ochisq = (*chisq);
		for (j = 0; j < nfit; j++) {
			for (k = 0; k < nfit; k++) {
				alpha[j][k] = covar[j][k];
			}
			beta[j] = dp[j];
			p[ip[j]] = ptry[ip[j]];
		}
	}

	// otherwise reject new parameters
	// increase lambda

	else {
		*lambda *= INC_ALAMBDA;
		*chisq = ochisq;
	}
}
Esempio n. 3
0
void mrqmin( double x[], double y[], double sig[], int ndata, CVector a,   
        int ia[], int ma, CMatrix covar, CMatrix alpha, double *chisq,   
        void (*funcs)(double, double [], double *, double [], int),   
        double *alamda)   
{   
  int j,k,l,m;   
  static int mfit;   
  static double ochisq;   
  CMatrix oneda;   
  CVector atry,beta,da;   
   
  if (*alamda < 0.0) {   
    atry=CVector(1,ma);   
    beta=CVector(1,ma);   
    da=CVector(1,ma);   
    for (mfit=0,j=1;j<=ma;j++)   
      if (ia[j]) mfit++;   
    oneda=CMatrix(1,mfit);   
    *alamda=0.001;   
    mrqcof(x,y,sig,ndata,a,ia,ma,alpha,beta,chisq,funcs);   
    ochisq=(*chisq);   
    for (j=1;j<=ma;j++) atry[j]=a[j];   
  }   
  for (j=0,l=1;l<=ma;l++) {   
    if (ia[l]) {   
      for (j++,k=0,m=1;m<=ma;m++) {   
    if (ia[m]) {   
      k++;   
      covar[j][k]=alpha[j][k];   
    }   
      }   
      covar[j][j]=alpha[j][j]*(1.0+(*alamda));   
      oneda[j][1]=beta[j];   
    }   
  }   
  covar.ColMax();   
  for (j=1;j<=mfit;j++) da[j]=oneda[j][1];   
  if (*alamda == 0.0) {   
    covsrt(covar,ma,ia,mfit);   
    return;   
  }   
  for (j=0,l=1;l<=ma;l++)   
    if (ia[l]) atry[l]=a[l]+da[++j];   
  mrqcof(x,y,sig,ndata,atry,ia,ma,covar,da,chisq,funcs);   
  if (*chisq < ochisq) {   
    *alamda *= 0.1;   
    ochisq=(*chisq);   
    for (j=0,l=1;l<=ma;l++) {   
      if (ia[l]) {   
    for (j++,k=0,m=1;m<=ma;m++) {   
      if (ia[m]) {   
        k++;   
        alpha[j][k]=covar[j][k];   
      }   
    }   
    beta[j]=da[j];   
    a[l]=atry[l];   
      }   
    }   
  } else {   
    *alamda *= 10.0;   
    *chisq=ochisq;   
  }   
}   
Esempio n. 4
0
void mrqmin( m_elem x[], m_elem y[], m_elem sig[], int ndata, m_elem a[],
        int ia[], int ma, m_elem **covar, m_elem **alpha, m_elem *chisq,
        void (*funcs)(m_elem, m_elem [], m_elem *, m_elem [], int),
        m_elem *alamda)
{
  int j,k,l,m;
  static int mfit;
  static m_elem ochisq,*atry,*beta,*da,**oneda;

  if (*alamda < 0.0) {
    atry=vector(1,ma);
    beta=vector(1,ma);
    da=vector(1,ma);
    for (mfit=0,j=1;j<=ma;j++)
      if (ia[j]) mfit++;
    oneda=matrix(1,mfit,1,1);
    *alamda=0.001;
    mrqcof(x,y,sig,ndata,a,ia,ma,alpha,beta,chisq,funcs);
    ochisq=(*chisq);
    for (j=1;j<=ma;j++) atry[j]=a[j];
  }
  for (j=0,l=1;l<=ma;l++) {
    if (ia[l]) {
      for (j++,k=0,m=1;m<=ma;m++) {
    if (ia[m]) {
      k++;
      covar[j][k]=alpha[j][k];
    }
      }
      covar[j][j]=alpha[j][j]*(1.0+(*alamda));
      oneda[j][1]=beta[j];
    }
  }
  gaussj(covar,mfit,oneda,1);
  for (j=1;j<=mfit;j++) da[j]=oneda[j][1];
  if (*alamda == 0.0) {
    covsrt(covar,ma,ia,mfit);
    free_matrix(oneda,1,mfit,1,1);
    free_vector(da,1,ma);
    free_vector(beta,1,ma);
    free_vector(atry,1,ma);
    return;
  }
  for (j=0,l=1;l<=ma;l++)
    if (ia[l]) atry[l]=a[l]+da[++j];
  mrqcof(x,y,sig,ndata,atry,ia,ma,covar,da,chisq,funcs);
  if (*chisq < ochisq) {
    *alamda *= 0.1;
    ochisq=(*chisq);
    for (j=0,l=1;l<=ma;l++) {
      if (ia[l]) {
    for (j++,k=0,m=1;m<=ma;m++) {
      if (ia[m]) {
        k++;
        alpha[j][k]=covar[j][k];
      }
    }
    beta[j]=da[j];
    a[l]=atry[l];
      }
    }
  } else {
    *alamda *= 10.0;
    *chisq=ochisq;
  }
}
Esempio n. 5
0
gmx_bool mrqmin(real x[], real y[], real sig[], int ndata, real a[], 
	    int ma, int lista[], int mfit, 
	    real **covar, real **alpha, real *chisq,
	    void (*funcs)(real,real *,real *,real *),
	    real *alamda) 
{
  int k,kk,j,ihit;
  static real *da,*atry,**oneda,*beta,ochisq;
  
  if (*alamda < 0.0) {
    oneda=matrix1(1,mfit,1,1);
    atry=rvector(1,ma);
    da=rvector(1,ma);
    beta=rvector(1,ma);
    kk=mfit+1;
    for (j=1;j<=ma;j++) {
      ihit=0;
      for (k=1;k<=mfit;k++)
	if (lista[k] == j) ihit++;
      if (ihit == 0)
	lista[kk++]=j;
      else if (ihit > 1) {
	nrerror("Bad LISTA permutation in MRQMIN-1", FALSE);
	return FALSE;
      }
    }
    if (kk != ma+1) {
      nrerror("Bad LISTA permutation in MRQMIN-2", FALSE);
      return FALSE;
    }
    *alamda=0.001;
    mrqcof(x,y,sig,ndata,a,ma,lista,mfit,alpha,beta,chisq,funcs);
    ochisq=(*chisq);
  }
  for (j=1;j<=mfit;j++) {
    for (k=1;k<=mfit;k++) covar[j][k]=alpha[j][k];
    covar[j][j]=alpha[j][j]*(1.0+(*alamda));
    oneda[j][1]=beta[j];
  }
  if (!gaussj(covar,mfit,oneda,1))
    return FALSE;
  for (j=1;j<=mfit;j++)
    da[j]=oneda[j][1];
  if (*alamda == 0.0) {
    covsrt(covar,ma,lista,mfit);
    free_vector(beta,1);
    free_vector(da,1);
    free_vector(atry,1);
    free_matrix(oneda,1,mfit,1);
    return TRUE;
  }
  for (j=1;j<=ma;j++) atry[j]=a[j];
  for (j=1;j<=mfit;j++)
    atry[lista[j]] = a[lista[j]]+da[j];
  mrqcof(x,y,sig,ndata,atry,ma,lista,mfit,covar,da,chisq,funcs);
  if (*chisq < ochisq) {
    *alamda *= 0.1;
    ochisq=(*chisq);
    for (j=1;j<=mfit;j++) {
      for (k=1;k<=mfit;k++) alpha[j][k]=covar[j][k];
      beta[j]=da[j];
      a[lista[j]]=atry[lista[j]];
    }
  } else {
    *alamda *= 10.0;
    *chisq=ochisq;
  }
  return TRUE;
}
Esempio n. 6
0
void mrqmin(double *x, double *y, double *sig, int ndata, double *a, int *ia, int ma, double **covar, double **alpha, double *chisq, double *alamda, void (*funcs)(double *, double *, double *, double **, int, int, int, double *, double **, double *, double *, int *, void *), int Nlin_coeff, double **Design_Matrix, double *lin_coeffs, int *varylin_coeffs,
#ifdef PARALLEL
	    int mfit, double *ochisq, double *atry, double *beta, double *da, double **oneda,
#endif
	    void *userparams)
{
  /*This function is taken from Press et al., 1992 -
    Levenberg-Marquardt method, attempting to reduce the value of chi^2 of a fit between a set of data points x[0....ndata-1], y[0.....ndata-1] with individual standard deviations sig[0.....ndata-1], and a nonlinear function dependent on ma coefficients a[0...ma-1]. The input array ia[0....ma-1] indicates by nonzero entries those components of a that should be fitted for, and by zero entries, those components that should be held fixed at their input values. The program returns current best-fit values for the parameters a[0...ma-1], and chi^2. The arrays covar[0...ma-1][0...ma-1], alpha[0....ma-1][0....ma-1] are used as working space during most iterations. Supply a routine funcs(x,a,yfit,dyda,ma) that evaluates the fitting fuction yfit, and its derivatives dyda[0....ma-1] with respect to the fitting parameters a at x. On the first call provide an initial guess for the parameters a, and set alamda<0 for initialization (which then sets alamda=0.001). If a step succeeds chisq becomes smaller and alamda decreases by a factor of 10. If a step fails alamda grows by a factor of 10. You must call this routine repeatedly until convergence is achieved. Then make one final call with alamda=0, so that covar[0....ma-1][0....ma-1] returns the covariance matrix, and alpha the curvature matrix. (Parameters help fixed will return zero covariances). */
  void covsrt(double **covar, int ma, int *ia, int mfit);
  int gaussj(double **a, int n, double **b, int m);
  void mrqcof(double *x, double *y, double *sig, int ndata, double *a, int *ia, int ma, double **alpha, double *beta, double *chisq, void (*funcs)(double *, double *, double *, double **, int, int, int, double *, double **, double *, double *, int *, void *), int, double **, double *, int *, void *);
  int j, k, l;
#ifndef PARALLEL
  static int mfit;
  static double ochisq[1], *atry, *beta, *da, **oneda;
#endif

  if(*alamda < 0.0) {
#ifndef PARALLEL
    if((atry = (double *) malloc(ma * sizeof(double))) == NULL ||
       (beta = (double *) malloc(ma * sizeof(double))) == NULL ||
       (da = (double *) malloc(ma * sizeof(double))) == NULL)
      error(ERR_MEMALLOC);
    for(mfit=0,j=0;j<ma;j++)
      if(ia[j]) mfit++;
    if((oneda = (double **) malloc(mfit * sizeof(double *))) == NULL)
      error(ERR_MEMALLOC);
    for(j=0;j<mfit;j++)
      if((oneda[j] = (double *) malloc(sizeof(double))) == NULL)
	error(ERR_MEMALLOC);
#endif
    *alamda = 0.001;
    mrqcof(x,y,sig,ndata,a,ia,ma,alpha,beta,chisq,funcs, Nlin_coeff, Design_Matrix, lin_coeffs, varylin_coeffs, userparams);
    ochisq[0]=(*chisq);
    for(j=0;j<ma;j++)
      atry[j] = a[j];
  }
  for(j=0;j<mfit;j++) {
    for(k=0;k<mfit;k++) covar[j][k] = alpha[j][k];
    covar[j][j]=alpha[j][j]*(1.0+(*alamda));
    oneda[j][0] = beta[j];
  }
  if(gaussj(covar,mfit,oneda,1))
    {
      *alamda = 0;
    }
  for(j=0;j<mfit;j++) da[j] = oneda[j][0];
  if (*alamda == 0.0) {
    covsrt(covar,ma,ia,mfit);
    covsrt(alpha,ma,ia,mfit);
#ifndef PARALLEL
    for(j=0;j<mfit;j++)
      free(oneda[j]);
    free(oneda);
    free(da);
    free(beta);
    free(atry);
#endif
    return;
  }
  for(j=0,l=0;l<ma;l++)
    if(ia[l]) atry[l]=a[l]+da[j++];
  mrqcof(x,y,sig,ndata,atry,ia,ma,covar,da,chisq,funcs,Nlin_coeff,Design_Matrix,lin_coeffs,varylin_coeffs, userparams);
  if (*chisq < ochisq[0]) {
    *alamda *= 0.1;
    ochisq[0] = (*chisq);
    for (j=0;j<mfit;j++) {
      for(k=0;k<mfit;k++) alpha[j][k] = covar[j][k];
      beta[j] = da[j];
    }
    for(l=0;l<ma;l++) a[l]=atry[l];
  } else {
    *alamda *= 10.0;
    *chisq=ochisq[0];
  }
}
Esempio n. 7
0
//-----------------------------------------------------------------------
void TLMFit::mrqmin()
{
	static vector < double> atry, beta, da;
	int j, k, l;
	static int mfit;
	static double ochisq;
	static vector< vector < double> > oneda;
	
	if (alamda < 0.0)
	{
		atry.resize(nparam);
		beta.resize(nparam);
		da.resize(nparam);
		
		for (mfit = 0, j = 0; j < nparam; j++)
			if (ia[j])
				mfit++;
			oneda.resize(mfit);
			for (unsigned int i = 0; i < oneda.size(); i++)
				oneda[i].resize(1);
			alamda = 0.001;
			mrqcof(a, alpha, beta);
			ochisq = (chisq);
			for (j = 0; j < nparam; j++)
				atry[j] =(a[j]);
	}
	for (j = 0; j < mfit; j++)
	{
		for (k = 0; k < mfit; k++)
			covar[j][k] = alpha[j][k];
		covar[j][j] = alpha[j][j]*(1.0 + (alamda));
		oneda[j][0] = beta[j];
	}
	try {gaussj(covar, mfit, oneda, 1);}
	catch (ESingularMatrix &E)
	{
		throw;
	}
	for (j = 0; j < mfit; j++)
	{
		da[j] = oneda[j][0];
	}
	if (alamda == 0.0)
	{
		covsrt(mfit);
		return;
	}
	for (j = 0, l = 0; l < nparam; l++)
		if (ia[l])
			atry[l] = a[l] + da[j++];
		mrqcof(atry, covar, da);
		if (chisq < ochisq)
		{
			alamda *= 0.1;
			ochisq = (chisq);
			for (j = 0; j < mfit; j++)
			{
				for (k = 0; k < mfit; k++)
					alpha[j][k] = covar[j][k];
				beta[j] = da[j];
			}
			for (j = 0; j < nparam; j++)             // Achtung!! in aelteren Versionen war hier ein Fehler
				a[j] = atry[j];
		} else 
		{
			alamda *= 10.0;
			chisq = ochisq;
		}
}
Esempio n. 8
0
int mrqmin(float **y, float **sig, struct image *psf, int ma, double **covar, 
    double **alpha, double *chisq, void (*funcs)(int, int, float *, float [], 
    int [], int, struct fitpars *), float *alamda, struct fitpars *fpar, 
    struct cons *constr, struct convpars *cpar, double *sigma)
{
        void errcalc (double *sigma, double **alpha, int ma, int *ia, int mfit);

	int j,k,l;
	static int mfit;
	static double *da,**oneda,*beta,ochisq;
        static float *atry, *aorig;
	float *a;
	int *ia;

        /* Kludge -- copy from fpar->a to a */
        a = vector (1, ma);
        ia = ivector (1, ma);
        copy_pars (a, ia, fpar, FROM);

	if (*alamda < 0.0) {
		aorig=vector(1,ma);
 		copy_pars (aorig, ia, fpar, FROM);
		atry=vector(1,ma);
		beta=dvector(1,ma);
		da=dvector(1,ma);
		for (mfit=0,j=1;j<=ma;j++)
			if (ia[j]==1)
				mfit++;
		oneda=dmatrix(1,mfit,1,1);
		*alamda=0.01;
		mrqcof(y,sig,psf,a,ia,ma,alpha,beta,chisq,funcs,fpar,cpar);
		ochisq=(*chisq);
		for (j=1;j<=ma;j++) atry[j]=a[j];
	}

	for (j=1;j<=mfit;j++) {
		for (k=1;k<=mfit;k++) covar[j][k]=alpha[j][k];
		covar[j][j]=alpha[j][j]*(1.0+(*alamda));
		oneda[j][1]=beta[j];
	}

	gaussj(covar,mfit,oneda,1);

	for (j=1;j<=mfit;j++) da[j]=oneda[j][1];
	if (*alamda == 0.0) {				/* Convergence!      */
                errcalc (sigma, alpha, ma, ia, mfit);   /* calculate uncert. */
		covsrt(covar,ma,ia,mfit);
		covsrt(alpha,ma,ia,mfit);
		free_dmatrix(oneda,1,mfit,1,1);
		free_dvector(da,1,ma);
		free_dvector(beta,1,ma);
		free_vector(atry,1,ma);
		free_vector (a, 1, ma);
		free_ivector (ia, 1, ma);
		return;
	}

        par_monitor (ma, a, ia, atry, da, fpar);

	constraints (ma, mfit, atry, a, ia, constr, da, aorig);

        copy_pars (atry, ia, fpar, TO);

	mrqcof(y,sig,psf,atry,ia,ma,covar,da,chisq,funcs,fpar,cpar);

	if (*chisq < ochisq) {
		*alamda *= 0.1;
		ochisq=(*chisq);
		for (j=1;j<=mfit;j++) {
			for (k=1;k<=mfit;k++) alpha[j][k]=covar[j][k];
			beta[j]=da[j];
		}
		for (l=1;l<=ma;l++)
			a[l]=atry[l];

	} else {
		*alamda *= 10.0;
		*chisq=ochisq;
	}
        copy_pars (a, ia, fpar, TO);
	free_vector (a, 1, ma);
	free_ivector (ia, 1, ma);

	return (0);
}