struct Amoeba { const Doub ftol; Int nfunc; Int mpts; Int ndim; Doub fmin; VecDoub y; MatDoub p; Amoeba(const Doub ftoll) : ftol(ftoll) {} template VecDoub minimize(VecDoub_I &point, const Doub del, T &func) { VecDoub dels(point.size(),del); return minimize(point,dels,func); } template VecDoub minimize(VecDoub_I &point, VecDoub_I &dels, T &func) { Int ndim=point.size(); MatDoub pp(ndim+1,ndim); for (Int i=0;i VecDoub minimize(MatDoub_I &pp, T &func) { const Int NMAX=5000; const Doub TINY=1.0e-10; Int ihi,ilo,inhi; mpts=pp.nrows(); ndim=pp.ncols(); VecDoub psum(ndim),pmin(ndim),x(ndim); p=pp; y.resize(mpts); for (Int i=0;iy[1] ? (inhi=1,0) : (inhi=0,1); for (Int i=0;i y[ihi]) { inhi=ihi; ihi=i; } else if (y[i] > y[inhi] && i != ihi) inhi=i; } Doub rtol=2.0*abs(y[ihi]-y[ilo])/(abs(y[ihi])+abs(y[ilo])+TINY); if (rtol < ftol) { SWAP(y[0],y[ilo]); for (Int i=0;i= NMAX) throw("NMAX exceeded"); nfunc += 2; Doub ytry=amotry(p,y,psum,ihi,-1.0,func); if (ytry <= y[ilo]) ytry=amotry(p,y,psum,ihi,2.0,func); else if (ytry >= y[inhi]) { Doub ysave=y[ihi]; ytry=amotry(p,y,psum,ihi,0.5,func); if (ytry >= ysave) { for (Int i=0;i Doub amotry(MatDoub_IO &p, VecDoub_O &y, VecDoub_IO &psum, const Int ihi, const Doub fac, T &func) { VecDoub ptry(ndim); Doub fac1=(1.0-fac)/ndim; Doub fac2=fac1-fac; for (Int j=0;j