#include #include #include #define TINY 1.0e-10 #define NMAX 100000 #define SWAP(a,b) {(a)+=(b);(b)=(a)-(b);(a)-=(b);} // Downhill Simplex Minimization int dsmin(double **p,double *y,int n,double ftol,double (*func)(double *)) { int i,j,nfunk=0; int ihi,ilo,ise; double *ptry,*pmid,*psum; double tol,ytry,rtol,ysave; double *vector_sum(double **,int); double dsmod(double **,double *,double *,int,double (*func)(double *),int,double); // Get function values for (i=0;i<=n;i++) y[i]=func(p[i]); // Sum vectors psum=vector_sum(p,n); // Start forever loop for (;;) { // Find high and low point ilo=0; ihi = (y[0]>y[1]) ? (ise=1,0) : (ise=0,1); for (i=0;i<=n;i++) { if (y[i]<=y[ilo]) ilo=i; if (y[i]>y[ihi]) { ise=ihi; ihi=i; } else if (y[i]>y[ise] && i!=ihi) ise=i; } // Compute fractional range from highest to lowest point rtol=2.0*fabs(y[ihi]-y[ilo])/(fabs(y[ihi])+fabs(y[ilo])+TINY); // Return if fractional tolerance is acceptable if (rtol=NMAX) { printf("dsmin: NMAX exceeded!\n"); return -1; } nfunk+=2; // Reflect simplex ytry=dsmod(p,y,psum,n,func,ihi,-1.0); if (ytry<=y[ilo]) // Goes right direction, extrapolate by factor 2 ytry=dsmod(p,y,psum,n,func,ihi,2.0); else if (ytry>=y[ise]) { // 1D contraction ysave=y[ihi]; ytry=dsmod(p,y,psum,n,func,ihi,0.5); if (ytry>=ysave) { for (i=0;i<=n;i++) { if (i!=ilo) { for (j=0;j