7 #include "AliL3FitUtilities.h"
13 void f2gauss5(double x,double a[],double *y,double dyda[],int na)
15 /*Function describing a sum of 2D gaussians with 5 parameters.
16 There number of gaussians is na/5. */
19 double fac,fac1,fac2,ex,ex1,ex2,arg1,arg2,u,v;
21 /*printf("fitting na %d, with pad %f time %f amplitude %f padwidth %f timewidth %f\n",na,a[2],a[4],a[1],a[3],a[5]);*/
23 if( index < 0 || index >=FIT_PTS )
25 fprintf( stderr, "ff2gauss: wrong index %d\n", index );
30 /*printf("u %f v %f\n",u,v);*/
32 for (i=1;i<=na-1;i+=5)
34 arg1 = (u-a[i+1])/a[i+2];
35 arg2 = (v-a[i+3])/a[i+4];
36 ex1 = exp(-0.5*arg1*arg1);
37 ex2 = exp(-0.5*arg2*arg2);
44 dyda[i+1] = fac1/a[i+2];
45 dyda[i+2] = fac1*arg1/a[i+2];
46 dyda[i+3] = fac2/a[i+4];
47 dyda[i+4] = fac2*arg2/a[i+4];
51 void nrerror(char error_text[])
52 /* Numerical Recipes standard error handler */
54 /*printf("%s\n",error_text);
58 void free_vector(double *v, long nl, long nh)
59 /* free a double vector allocated with vector() */
61 free((FREE_ARG) (v+nl-NR_END));
64 void free_ivector(int *v, long nl, long nh)
65 /* free an int vector allocated with ivector() */
67 free((FREE_ARG) (v+nl-NR_END));
70 void free_matrix(double **m, long nrl, long nrh, long ncl, long nch)
71 /* free a double matrix allocated by matrix() */
73 free((FREE_ARG) (m[nrl]+ncl-NR_END));
74 free((FREE_ARG) (m+nrl-NR_END));
77 int *ivector(long nl, long nh)
78 /* allocate an int vector with subscript range v[nl..nh] */
82 v=(int *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(int)));
83 if (!v) nrerror("allocation failure in ivector()");
87 double *vector(long nl,long nh)
88 /* allocate a double vector with subscript range v[nl..nh] */
92 v=(double *)malloc((unsigned int) ((nh-nl+1+NR_END)*sizeof(double)));
93 if (!v) nrerror("allocation failure in vector()");
97 double **matrix(long nrl,long nrh,long ncl,long nch)
98 /* allocate a double matrix with subscript range m[nrl..nrh][ncl..nch] */
100 long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
103 /* allocate pointers to rows */
104 m=(double **) malloc((unsigned int)((nrow+NR_END)*sizeof(double*)));
105 if (!m) nrerror("allocation failure 1 in matrix()");
109 /* allocate rows and set pointers to them */
110 m[nrl]=(double *) malloc((unsigned int)((nrow*ncol+NR_END)*sizeof(double)));
111 if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
115 for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
117 /* return pointer to array of pointers to rows */
121 int gaussj(double **a, int n, double **b, int m)
123 int *indxc,*indxr,*ipiv;
124 int i,icol=0,irow=0,j,k,l,ll;
125 double big,dum,pivinv,swap;
130 for (j=1;j<=n;j++) ipiv[j]=0;
137 if (fabs(a[j][k]) >= big) {
142 } else if (ipiv[k] > 1) {
143 free_ivector(ipiv,1,n);
144 free_ivector(indxr,1,n);
145 free_ivector(indxc,1,n);
146 nrerror("gaussj: Singular Matrix-1");
152 for (l=1;l<=n;l++) SWAP(a[irow][l],a[icol][l])
153 for (l=1;l<=m;l++) SWAP(b[irow][l],b[icol][l])
157 if (a[icol][icol] == 0.0){
158 free_ivector(ipiv,1,n);
159 free_ivector(indxr,1,n);
160 free_ivector(indxc,1,n);
161 nrerror("gaussj: Singular Matrix-2");
164 if (mabs(a[icol][icol]) < EPSILON )
166 nrerror("gaussj: a[icol][icol] == 0");
169 pivinv=1.0/a[icol][icol];
171 pivinv=1.0/a[icol][icol];
173 for (l=1;l<=n;l++) a[icol][l] *= pivinv;
174 for (l=1;l<=m;l++) b[icol][l] *= pivinv;
175 for (ll=1;ll<=n;ll++)
179 for (l=1;l<=n;l++) a[ll][l] -= a[icol][l]*dum;
180 for (l=1;l<=m;l++) b[ll][l] -= b[icol][l]*dum;
184 if (indxr[l] != indxc[l])
186 SWAP(a[k][indxr[l]],a[k][indxc[l]]);
188 free_ivector(ipiv,1,n);
189 free_ivector(indxr,1,n);
190 free_ivector(indxc,1,n);
194 void covsrt(double **covar, int ma, int ia[], int mfit)
199 for (i=mfit+1;i<=ma;i++)
200 for (j=1;j<=i;j++) covar[i][j]=covar[j][i]=0.0;
202 for (j=ma;j>=1;j--) {
204 for (i=1;i<=ma;i++) SWAP(covar[i][k],covar[i][j])
205 for (i=1;i<=ma;i++) SWAP(covar[k][i],covar[j][i])
211 void mrqcof(double x[], double y[], double sig[], int ndata, double a[], int ia[],
212 int ma, double **alpha, double beta[], double *chisq,
213 void (*funcs)(double, double [], double *, double [], int))
215 int i,j,k,l,m,mfit=0;
216 double ymod,wt,sig2i,dy,*dyda;
222 for (j=1;j<=mfit;j++) {
223 for (k=1;k<=j;k++) alpha[j][k]=0.0;
227 for (i=1;i<=ndata;i++) {
228 (*funcs)(x[i],a,&ymod,dyda,ma);
229 sig2i=1.0/(sig[i]*sig[i]);
231 for (j=0,l=1;l<=ma;l++) {
234 for (j++,k=0,m=1;m<=l;m++)
235 if (ia[m]) alpha[j][++k] += wt*dyda[m];
239 *chisq += dy*dy*sig2i;
241 for (j=2;j<=mfit;j++)
242 for (k=1;k<j;k++) alpha[k][j]=alpha[j][k];
243 free_vector(dyda,1,ma);
246 int mrqmin(double x[], double y[], double sig[], int ndata, double a[], int ia[],
247 int ma, double **covar, double **alpha, double *chisq,
248 void (*funcs)(double, double [], double *, double [], int), double *alamda)
250 void covsrt(double **covar, int ma, int ia[], int mfit);
251 int gaussj(double **a, int n, double **b, int m);
252 void mrqcof(double x[], double y[], double sig[], int ndata, double a[],
253 int ia[], int ma, double **alpha, double beta[], double *chisq,
254 void (*funcs)(double, double [], double *, double [], int));
257 static double ochisq,*atry,*beta,*da,**oneda;
263 for (mfit=0,j=1;j<=ma;j++)
265 oneda=matrix(1,mfit,1,1);
267 mrqcof(x,y,sig,ndata,a,ia,ma,alpha,beta,chisq,funcs);
269 for (j=1;j<=ma;j++) atry[j]=a[j];
271 for (j=0,l=1;l<=ma;l++) {
273 for (j++,k=0,m=1;m<=ma;m++) {
276 covar[j][k]=alpha[j][k];
279 covar[j][j]=alpha[j][j]*(1.0+(*alamda));
283 if(gaussj(covar,mfit,oneda,1)<0)
285 free_matrix(oneda,1,mfit,1,1);
286 free_vector(da,1,ma);
287 free_vector(beta,1,ma);
288 free_vector(atry,1,ma);
291 for (j=1;j<=mfit;j++) da[j]=oneda[j][1];
292 if (*alamda == 0.0) {
293 covsrt(covar,ma,ia,mfit);
294 free_matrix(oneda,1,mfit,1,1);
295 free_vector(da,1,ma);
296 free_vector(beta,1,ma);
297 free_vector(atry,1,ma);
300 for (j=0,l=1;l<=ma;l++)
301 if (ia[l]) atry[l]=a[l]+da[++j];
302 mrqcof(x,y,sig,ndata,atry,ia,ma,covar,da,chisq,funcs);
303 if (*chisq < ochisq) {
306 for (j=0,l=1;l<=ma;l++) {
308 for (j++,k=0,m=1;m<=ma;m++) {
311 alpha[j][k]=covar[j][k];
326 int lev_marq_fit( double x[], double y[], double sig[], int NPT, double a[], int ia[], double dev[], int MA,
327 double *chisq_p, void (*funcs)(double, double [], double *, double [], int) )
330 double alamda,chisq,ochisq,**covar,**alpha;
332 covar=matrix(1,MA,1,MA);
333 alpha=matrix(1,MA,1,MA);
335 if( setjmp(env) == 0 ) {
337 if(mrqmin(x,y,sig,NPT,a,ia,MA,covar,alpha,&chisq,funcs,&alamda)<0)
339 free_matrix(alpha,1,MA,1,MA);
340 free_matrix(covar,1,MA,1,MA);
348 if(mrqmin(x,y,sig,NPT,a,ia,MA,covar,alpha,&chisq,funcs,&alamda)<0)
350 free_matrix(alpha,1,MA,1,MA);
351 free_matrix(covar,1,MA,1,MA);
356 else if (fabs(ochisq-chisq) < 0.1)
358 if (itst < 4) continue;
360 if(mrqmin(x,y,sig,NPT,a,ia,MA,covar,alpha,&chisq,funcs,&alamda)<0)
362 free_matrix(alpha,1,MA,1,MA);
363 free_matrix(covar,1,MA,1,MA);
368 dev[i] = sqrt(covar[i][i]);
371 free_matrix(alpha,1,MA,1,MA);
372 free_matrix(covar,1,MA,1,MA);
376 /*if( control_g.print_fit_errors==2 )*/
377 fprintf( stderr, " runtime error\n" );
379 free_matrix(alpha,1,MA,1,MA);
380 free_matrix(covar,1,MA,1,MA);