#include #define ITMAX 200 static float sqrarg; #define SQR(a) (sqrarg=(a),sqrarg*sqrarg) void powell(p,xi,n,ftol,iter,fret,func) float p[],**xi,ftol,*fret,(*func)(); int n,*iter; { int i,ibig,j; float t,fptt,fp,del; float *pt,*ptt,*xit,*vector(); void linmin(),nrerror(),free_vector(); pt=vector(1,n); ptt=vector(1,n); xit=vector(1,n); *fret=(*func)(p); for (j=1;j<=n;j++) pt[j]=p[j]; for (*iter=1;;(*iter)++) { fp=(*fret); ibig=0; del=0.0; for (i=1;i<=n;i++) { for (j=1;j<=n;j++) xit[j]=xi[j][i]; fptt=(*fret); linmin(p,xit,n,fret,func); if (fabs(fptt-(*fret)) > del) { del=fabs(fptt-(*fret)); ibig=i; } } if (2.0*fabs(fp-(*fret)) <= ftol*(fabs(fp)+fabs(*fret))) { free_vector(xit,1,n); free_vector(ptt,1,n); free_vector(pt,1,n); return; } if (*iter == ITMAX) nrerror("Too many iterations in routine POWELL"); for (j=1;j<=n;j++) { ptt[j]=2.0*p[j]-pt[j]; xit[j]=p[j]-pt[j]; pt[j]=p[j]; } fptt=(*func)(ptt); if (fptt < fp) { t=2.0*(fp-2.0*(*fret)+fptt)*SQR(fp-(*fret)-del)-del*SQR(fp-fptt); if (t < 0.0) { linmin(p,xit,n,fret,func); for (j=1;j<=n;j++) xi[j][ibig]=xit[j]; } } } } #undef ITMAX #undef SQR