int main(void) { long idum=(-911); int i; float chisq,*x,*y,*sig,*a,*w,**cvm,**u,**v; x=vector(1,NPT); y=vector(1,NPT); sig=vector(1,NPT); a=vector(1,NPOL); w=vector(1,NPOL); cvm=matrix(1,NPOL,1,NPOL); u=matrix(1,NPT,1,NPOL); v=matrix(1,NPOL,1,NPOL); for (i=1;i<=NPT;i++) { x[i]=0.02*i; y[i]=1.0+x[i]*(2.0+x[i]*(3.0+x[i]*(4.0+x[i]*5.0))); y[i] *= (1.0+SPREAD*gasdev(&idum)); sig[i]=y[i]*SPREAD; } svdfit(x,y,sig,NPT,a,NPOL,u,v,w,&chisq,fpoly); svdvar(v,NPOL,w,cvm); printf("\npolynomial fit:\n\n"); for (i=1;i<=NPOL;i++) printf("%12.6f %s %10.6f\n",a[i]," +-",sqrt(cvm[i][i])); printf("\nChi-squared %12.6f\n",chisq); svdfit(x,y,sig,NPT,a,NPOL,u,v,w,&chisq,fleg); svdvar(v,NPOL,w,cvm); printf("\nLegendre polynomial fit:\n\n"); for (i=1;i<=NPOL;i++) printf("%12.6f %s %10.6f\n",a[i]," +-",sqrt(cvm[i][i])); printf("\nChi-squared %12.6f\n",chisq); free_matrix(v,1,NPOL,1,NPOL); free_matrix(u,1,NPT,1,NPOL); free_matrix(cvm,1,NPOL,1,NPOL); free_vector(w,1,NPOL); free_vector(a,1,NPOL); free_vector(sig,1,NPT); free_vector(y,1,NPT); free_vector(x,1,NPT); return 0; }
/****************************************************************************** General linear least squares fit routine from section 15.4 of Numerical Recipes. yfit(x) = function which fills f[i],i=0..o-1 with the o fitting functions evaluated at x. fom = if nonzero figure-of-merit is returned here. a = fitting parameters av = if (av) error variances for the fitting parameters returned here. x = n abscissas y = n ordinates ys = if (ys) = n error standard deviations for y values tol = smallest fraction of maximum singular value (eigenvalues, roughly) which a small singular value can equal -- smaller values are set to zero, assumed to indicate redundancy. NR suggests of order 10^-6 n = number of abscissas. o = number of fitting parameters. */ static fit_rc fit_lsq(void (*yfit)(), double *fom, double *a, double *av, const double *x, const double *y, const double *ys, double tol, int n, int o) { double wmax,wmin,xsq,sum ; int i,j ; const char *me = "fit_lsq" ; if (check_memory(o,n) != OK) return(memfail(__LINE__,me)) ; for(i=0;i<n;i++) { yfit(x[i]) ; for(j=0;j<o;j++) u[i][j] = f[j] * (ys ? 1.0/ys[i] : 1.0) ; } ; memcpy(b,y,n*sizeof(double)) ; if (ys) for(i=0;i<n;i++) b[i] /= ys[i] ; if (svdcmp(u,n,o) != OK) return(punt(__LINE__,me,"singular value decomposition failed.")) ; wmax = 0.0 ; for(wmax=0.0,j=0;j<o;j++) if (w[j] > wmax) wmax = w[j] ; wmin = tol * wmax ; for(j=0;j<o;j++) if (w[j] < wmin) w[j] = 0.0 ; if (svbksb(a,n,o) != OK) return(punt(__LINE__,me,"back substitution failed.")) ; if (av) { if (svdvar(o) != OK) return(punt(__LINE__,me,"variance calculation failed.")) ; for(i=0;i<o;i++) av[i] = cvm[i][i] ; } ; if (fom) { xsq = 0.0 ; for(i=0;i<o;i++) { yfit(x[i]) ; sum = 0.0 ; for(j=0;j<o;j++) sum += a[j] * f[j] ; sum = (y[i] - sum)/(ys ? ys[i]*ys[i] : 1.0) ; xsq += sum*sum ; } ; *fom = xsq ; } ; return(OK) ; }