/* @(#)mo_mrqmin.c 17.1.1.1 (ESO-SDAG) 01/25/02 17:49:06 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ void MO_MRQMIN(x,y,sig,ndata,a,ma,lista,mfit,covar,alpha,chisq,funcs,alamda) float x[],y[],sig[],a[],**covar,**alpha,*chisq,*alamda; int ndata,ma,lista[],mfit; void (*funcs)(); { int k,kk,j,ihit; static float *da,*atry,**oneda,*beta,ochisq; float *vector(),**matrix(); void free_matrix(),free_vector(); if (*alamda < 0.0) { oneda = matrix(1,mfit,1,1); atry = vector(1,ma); da = vector(1,ma); beta = vector(1,ma); /* atry = (float *) osmmget( ma * sizeof(float)); da = (float *) osmmget( ma * sizeof(float)); beta = (float *) osmmget( ma * sizeof(float)); */ 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) SCETER(2, "FATAL: Bad LISTA permutation in MRQMIN-1"); } if (kk != ma+1) SCETER(2, "FATAL: Bad LISTA permutation in MRQMIN-2"); *alamda=0.001; MO_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]; } MO_GAUSSJ(covar,mfit,oneda,1); for (j=1;j<=mfit;j++) da[j]=oneda[j][1]; if (*alamda == 0.0) { MO_COVSRT(covar,ma,lista,mfit); free_vector(beta,1,ma); free_vector(da,1,ma); free_vector(atry,1,ma); free_matrix(oneda,1,mfit,1,1); /* osmmfree((char *) beta); osmmfree((char *) da); osmmfree((char *) atry); */ return; } for (j=1;j<=ma;j++) atry[j]=a[j]; for (j=1;j<=mfit;j++) atry[lista[j]] = a[lista[j]]+da[j]; MO_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; }