Пример #1
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];
  }
}
Пример #2
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;
		}
}
Пример #3
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;
}
Пример #4
0
void mrqmin(float x[], float y[], float sig[], int ndata, float a[], int ia[],
	int ma, float **covar, float **alpha, float *chisq,
	void (*funcs)(float, float [], float *, float [], int), float *alamda)
{
	void covsrt(float **covar, int ma, int ia[], int mfit);
	void gaussj(float **a, int n, float **b, int m);
	void mrqcof(float x[], float y[], float sig[], int ndata, float a[],
		int ia[], int ma, float **alpha, float beta[], float *chisq,
		void (*funcs)(float, float [], float *, float [], int));
	int j,k,l,m;
	static int mfit;
	static float 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;
	}
}
Пример #5
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);
}