DEFINITION MODULE NonLin; (* EXPORT QUALIFIED FGauss, MrqMin; *) FROM NRVect IMPORT Vector; FROM NRIVect IMPORT IVector; FROM NRMatr IMPORT Matrix; TYPE MrqFunc = PROCEDURE (REAL, Vector, VAR REAL, Vector); PROCEDURE FGauss(x: REAL; A: Vector; VAR y: REAL; DYDA: Vector); (* y(x;a) is the sum of MA/3 Gaussians (14.4.16). The amplitude, center, and width of the Gaussians are stored in consecutive locations of A: A[I]=Bk, A[I+1]=Ek, A[I+2]=Gk, k=1,...,MA/3. The dimensions of the arrays are A[0, ma-1], DYDA[0, ma-1] *) PROCEDURE MrqMin( X, Y, SIG: Vector; nData: INTEGER; A: Vector; ma: INTEGER; LISTA: IVector; mfit: INTEGER; COVAR, ALPHA: Matrix; func: MrqFunc; MrqMinBeta: Vector; VAR chisq, alamda: REAL); (* Levenberg-Marquardt method, attempting to reduce the value chi^2 of a fit between a set of points X[0, ndata-1], Y[0, ndata-1] with individual standard deviations SIG[0, ndata-1], and a nonlinear function dependen on coefficients A[0, ma-1]. The array LISTA[0, ma-1] numbers the parameters A such that the first mfit elements correspond to values actually being adjusted; the remaining ma-mfit parameters are held fixed at their input value. The program returns current best-fit values for the ma fit parameters A, and chi^2= chisq. During most interations the [mfit, mfit] elements of the array COVAR[ma, ma] and the array ALPHA[ma, ma] are used as working space. The program must be supplied with a routine FUNCS(x, A, yfit, DYDA, ma) that evaluates the fitting function 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.0 for initialization (which then sets alamda=.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.0, so that COVAR returns the covariance matrix, and ALPHA the curvature matrix. *) END NonLin.