package ChaosDemos; import java.util.*; public class svdfitClass { double[][] u; double[][] v; double[] w; double[] xminus; double[] yminus; static double TOL=1.0e-5; int ma; int ndata; public svdfitClass(int inNdata, int inMa) { ndata=inNdata; ma=inMa; u=new double[ndata+1][ma+1]; v=new double[ma+1][ma+1]; w=new double[ma+1]; } public double svdfit(int[] ix, double y[], double inx[], double iny[], double sig[], double a[]) { int j,i; double wmax,tmp,thresh,sum; double chisq; double[] b=new double[ndata+1]; double[] afunc=new double[ma+1]; xminus=inx; yminus=iny; for (i=1;i<=ndata;i++) { funcs(ix[i],afunc,ma); tmp=1.0/sig[i]; for (j=1;j<=ma;j++) u[i][j]=afunc[j]*tmp; b[i]=y[i]*tmp; } svdcmp(ndata,ma); wmax=0.0; for (j=1;j<=ma;j++) if (w[j] > wmax) wmax=w[j]; thresh=TOL*wmax; for (j=1;j<=ma;j++) if (w[j] < thresh) w[j]=0.0; svbksb(ndata,ma,b,a); chisq=0.0; for (i=1;i<=ndata;i++) { funcs(ix[i],afunc,ma); for (sum=0.0,j=1;j<=ma;j++) sum += a[j]*afunc[j]; chisq += Math.pow((y[i]-sum)/sig[i],2); } return chisq; } private void svdcmp(int m, int n) { int i,its,j,jj,k; //Got error messages if these two weren't initialized: don;t know why int l=0; int nm=0; boolean flag; double anorm,c,f,g,h,s,scale,x,y,z; double[] rv1=new double[n+1]; g=scale=anorm=0.0; for (i=1;i<=n;i++) { l=i+1; rv1[i]=scale*g; g=s=scale=0.0; if (i <= m) { for (k=i;k<=m;k++) scale += Math.abs(u[k][i]); if (scale!=0.) { for (k=i;k<=m;k++) { u[k][i] /= scale; s += u[k][i]*u[k][i]; } f=u[i][i]; g = -SIGN(Math.sqrt(s),f); h=f*g-s; u[i][i]=f-g; for (j=l;j<=n;j++) { for (s=0.0,k=i;k<=m;k++) s += u[k][i]*u[k][j]; f=s/h; for (k=i;k<=m;k++) u[k][j] += f*u[k][i]; } for (k=i;k<=m;k++) u[k][i] *= scale; } } w[i]=scale *g; g=s=scale=0.0; if (i <= m && i != n) { for (k=l;k<=n;k++) scale += Math.abs(u[i][k]); if (scale!= 0.) { for (k=l;k<=n;k++) { u[i][k] /= scale; s += u[i][k]*u[i][k]; } f=u[i][l]; g = -SIGN(Math.sqrt(s),f); h=f*g-s; u[i][l]=f-g; for (k=l;k<=n;k++) rv1[k]=u[i][k]/h; for (j=l;j<=m;j++) { for (s=0.0,k=l;k<=n;k++) s += u[j][k]*u[i][k]; for (k=l;k<=n;k++) u[j][k] += s*rv1[k]; } for (k=l;k<=n;k++) u[i][k] *= scale; } } anorm=Math.max(anorm,(Math.abs(w[i])+Math.abs(rv1[i]))); } for (i=n;i>=1;i--) { if (i < n) { if (g!=0.) { for (j=l;j<=n;j++) v[j][i]=(u[i][j]/u[i][l])/g; for (j=l;j<=n;j++) { for (s=0.0,k=l;k<=n;k++) s += u[i][k]*v[k][j]; for (k=l;k<=n;k++) v[k][j] += s*v[k][i]; } } for (j=l;j<=n;j++) v[i][j]=v[j][i]=0.0; } v[i][i]=1.0; g=rv1[i]; l=i; } for (i=Math.min(m,n);i>=1;i--) { l=i+1; g=w[i]; for (j=l;j<=n;j++) u[i][j]=0.0; if (g!=0.) { g=1.0/g; for (j=l;j<=n;j++) { for (s=0.0,k=l;k<=m;k++) s += u[k][i]*u[k][j]; f=(s/u[i][i])*g; for (k=i;k<=m;k++) u[k][j] += f*u[k][i]; } for (j=i;j<=m;j++) u[j][i] *= g; } else for (j=i;j<=m;j++) u[j][i]=0.0; ++u[i][i]; } for (k=n;k>=1;k--) { for (its=1;its<=30;its++) { flag=true; for (l=k;l>=1;l--) { nm=l-1; if ((Math.abs(rv1[l])+anorm) == anorm) { flag=false; break; } if ((Math.abs(w[nm])+anorm) == anorm) break; } if (flag) { c=0.0; s=1.0; for (i=l;i<=k;i++) { f=s*rv1[i]; rv1[i]=c*rv1[i]; if ((Math.abs(f)+anorm) == anorm) break; g=w[i]; h=pythag(f,g); w[i]=h; h=1.0/h; c=g*h; s = -f*h; for (j=1;j<=m;j++) { y=u[j][nm]; z=u[j][i]; u[j][nm]=y*c+z*s; u[j][i]=z*c-y*s; } } } z=w[k]; if (l == k) { if (z < 0.0) { w[k] = -z; for (j=1;j<=n;j++) v[j][k] = -v[j][k]; } break; } if (its == 30) System.out.println("no convergence in 30 svdcmp iterations"); x=w[l]; nm=k-1; y=w[nm]; g=rv1[nm]; h=rv1[k]; f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y); g=pythag(f,1.0); f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x; c=s=1.0; for (j=l;j<=nm;j++) { i=j+1; g=rv1[i]; y=w[i]; h=s*g; g=c*g; z=pythag(f,h); rv1[j]=z; c=f/z; s=h/z; f=x*c+g*s; g = g*c-x*s; h=y*s; y *= c; for (jj=1;jj<=n;jj++) { x=v[jj][j]; z=v[jj][i]; v[jj][j]=x*c+z*s; v[jj][i]=z*c-x*s; } z=pythag(f,h); w[j]=z; if (z!=0.) { z=1.0/z; c=f*z; s=h*z; } f=c*g+s*y; x=c*y-s*g; for (jj=1;jj<=m;jj++) { y=u[jj][j]; z=u[jj][i]; u[jj][j]=y*c+z*s; u[jj][i]=z*c-y*s; } } rv1[l]=0.0; rv1[k]=f; w[k]=x; } } } private void svbksb(int m, int n, double[] b, double[] x) { int jj,j,i; double s; double[] tmp; tmp=new double[n+1]; for (j=1;j<=n;j++) { s=0.0; if (w[j]!=0.) { for (i=1;i<=m;i++) s += u[i][j]*b[i]; s /= w[j]; } tmp[j]=s; } for (j=1;j<=n;j++) { s=0.0; for (jj=1;jj<=n;jj++) s += v[j][jj]*tmp[jj]; x[j]=s; } } private double SIGN(double a, double b) { if(b>=0) return Math.abs(a); else return -Math.abs(a); } private double pythag(double a, double b) { double absa,absb; absa=Math.abs(a); absb=Math.abs(b); if(absa > absb) return absa*Math.sqrt(1.+Math.pow((absb/absa),2)); else if(absb==0.) return 0.; else return absb*Math.sqrt(1.+Math.pow((absa/absb),2)); } private void funcs(int ix, double[] afunc, int ma) { afunc[1]=xminus[ix]; afunc[2]=yminus[ix]; afunc[3]=1.; } }