001 package numal.highprecision; 002 003 import java.util.*; 004 import numal.highprecision.*; 005 006 public class Analytic_problems extends Object { 007 008 public static void marquardt(int m, int n, double par[], 009 double g[], double v[][], 010 AP_marquardt_methods method, 011 double in[], double out[]) 012 { 013 boolean emergency; 014 int maxfe,fe,it,i,j,err; 015 double vv,ww,w,mu,res,fpar,fparpres,lambda,lambdamin,p,pw, 016 reltolres,abstolres,temp; 017 double em[] = new double[8]; 018 double val[] = new double[n+1]; 019 double b[] = new double[n+1]; 020 double bb[] = new double[n+1]; 021 double parpres[] = new double[n+1]; 022 double jac[][] = new double[m+1][n+1]; 023 024 lambda=0.0; 025 vv=10.0; 026 w=0.5; 027 mu=0.01; 028 ww = (in[6] < 1.0e-7) ? 1.0e-8 : 1.0e-1*in[6]; 029 em[0]=em[2]=em[6]=in[0]; 030 em[4]=10*n; 031 reltolres=in[3]; 032 abstolres=in[4]*in[4]; 033 maxfe=(int)in[5]; 034 err=0; 035 fe=it=1; 036 p=fpar=res=0.0; 037 pw = -Math.log(ww*in[0])/2.30; 038 if (!method.funct(m,n,par,g)) { 039 err=3; 040 out[4]=fe; 041 out[5]=it-1; 042 out[1]=err; 043 return; 044 } 045 fpar=Basic.vecvec(1,m,0,g,g); 046 out[3]=Math.sqrt(fpar); 047 emergency=false; 048 it=1; 049 do { 050 method.jacobian(m,n,par,g,jac); 051 i=Linear_algebra.qrisngvaldec(jac,m,n,val,v,em); 052 if (it == 1) 053 lambda=in[6]*Basic.vecvec(1,n,0,val,val); 054 else 055 if (p == 0.0) lambda *= w; 056 for (i=1; i<=n; i++) b[i]=val[i]*Basic.tamvec(1,m,i,jac,g); 057 while (true) { 058 for (i=1; i<=n; i++) bb[i]=b[i]/(val[i]*val[i]+lambda); 059 for (i=1; i<=n; i++) 060 parpres[i]=par[i]-Basic.matvec(1,n,i,v,bb); 061 fe++; 062 if (fe >= maxfe) 063 err=1; 064 else 065 if (!method.funct(m,n,parpres,g)) err=2; 066 if (err != 0) { 067 emergency=true; 068 break; 069 } 070 fparpres=Basic.vecvec(1,m,0,g,g); 071 res=fpar-fparpres; 072 if (res < mu*Basic.vecvec(1,n,0,b,bb)) { 073 p += 1.0; 074 lambda *= vv; 075 if (p == 1.0) { 076 lambdamin=ww*Basic.vecvec(1,n,0,val,val); 077 if (lambda < lambdamin) lambda=lambdamin; 078 } 079 if (p >= pw) { 080 err=4; 081 emergency=true; 082 break; 083 } 084 } else { 085 Basic.dupvec(1,n,0,par,parpres); 086 fpar=fparpres; 087 break; 088 } 089 } 090 if (emergency) break; 091 it++; 092 } while (fpar > abstolres && res > reltolres*fpar+abstolres); 093 for (i=1; i<=n; i++) 094 Basic.mulcol(1,n,i,i,jac,v,1.0/(val[i]+in[0])); 095 for (i=1; i<=n; i++) 096 for (j=1; j<=i; j++) 097 v[i][j]=v[j][i]=Basic.mattam(1,n,i,j,jac,jac); 098 lambda=lambdamin=val[1]; 099 for (i=2; i<=n; i++) 100 if (val[i] > lambda) 101 lambda=val[i]; 102 else 103 if (val[i] < lambdamin) lambdamin=val[i]; 104 temp=lambda/(lambdamin+in[0]); 105 out[7]=temp*temp; 106 out[2]=Math.sqrt(fpar); 107 out[6]=Math.sqrt(res+fpar)-out[2]; 108 out[4]=fe; 109 out[5]=it-1; 110 out[1]=err; 111 } 112 113 }