9#define SHFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d);
10#define CGOLD 0.3819660
19template <
typename T,
typename F>
20T f1dim_tp(T x,std::vector<T> &pcom,std::vector<T> &xicom,F &functor)
24 int ncom = pcom.size()-1;
25 std::vector<T> xt(ncom+1);
26 for (j=1;j<=ncom;j++) xt[j] = pcom[j] + x * xicom[j];
27 f = functor(xt.data() + 1);
32template <
typename T,
typename F>
33T brent_tp(T ax, T bx, T cx, T tol,T *xmin,std::vector<T> &pcom,std::vector<T> &xicom,F &functor)
36 T a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm;
39 a=(ax < cx ? ax : cx);
40 b=(ax > cx ? ax : cx);
42 fw=fv=fx=f1dim_tp(x,pcom,xicom,functor);
43 for (iter=1;iter<=ITMAX1;iter++) {
45 tol2=2.0*(tol1=tol*fabs(x)+ZEPS);
46 if (fabs(x-xm) <= (tol2-0.5*(b-a))) {
59 if (fabs(p) >= fabs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x))
60 d=CGOLD*(e=(x >= xm ? a-x : b-x));
64 if (u-a < tol2 || b-u < tol2)
68 d=CGOLD*(e=(x >= xm ? a-x : b-x));
70 u=(fabs(d) >= tol1 ? x+d : x+SIGN(tol1,d));
71 fu=f1dim_tp(u,pcom,xicom,functor);
73 if (u >= x) a=x;
else b=x;
77 if (u < x) a=u;
else b=u;
78 if (fu <= fw || w == x) {
83 }
else if (fu <= fv || v == x || v == w) {
89 throw std::runtime_error(
"Too many iterations in brent_tpd");
95template <
typename T,
typename F>
96void mnbrak_tp(T *ax, T *bx, T *cx, T *fa, T *fb, T *fc,std::vector<T> &pcom,std::vector<T> &xicom
101 *fa=f1dim_tp(*ax,pcom,xicom,functor);
102 *fb=f1dim_tp(*bx,pcom,xicom,functor);
104 SHFT(dum,*ax,*bx,dum)
105 SHFT(dum,*fb,*fa,dum)
107 *cx=(*bx)+GOLD*(*bx-*ax);
108 *fc=f1dim_tp(*cx,pcom,xicom,functor);
110 r=(*bx-*ax)*(*fb-*fc);
111 q=(*bx-*cx)*(*fb-*fa);
112 u=(*bx)-((*bx-*cx)*q-(*bx-*ax)*r)/
113 (2.0*SIGN(DMAX(fabs(q-r),TINY1),q-r));
114 ulim=(*bx)+GLIMIT*(*cx-*bx);
115 if ((*bx-u)*(u-*cx) > 0.0) {
116 fu=f1dim_tp(u,pcom,xicom,functor);
123 }
else if (fu > *fb) {
128 u=(*cx)+GOLD*(*cx-*bx);
129 fu=f1dim_tp(u,pcom,xicom,functor);
130 }
else if ((*cx-u)*(u-ulim) > 0.0) {
131 fu=f1dim_tp(u,pcom,xicom,functor);
133 SHFT(*bx,*cx,u,*cx+GOLD*(*cx-*bx))
134 SHFT(*fb,*fc,fu,f1dim_tp(u,pcom,xicom,functor))
136 }
else if ((u-ulim)*(ulim-*cx) >= 0.0) {
138 fu=f1dim_tp(u,pcom,xicom,functor);
140 u=(*cx)+GOLD*(*cx-*bx);
141 fu=f1dim_tp(u,pcom,xicom,functor);
148template <
typename T,
typename F>
149void linmind_tp(T p[], T xi[],
int n, T *fret, F &functor)
153 T xx,xmin,fx,fb,fa,bx,ax;
155 std::vector<T> pcom(n+1);
156 std::vector<T> xicom(n+1);
164 mnbrak_tp(&ax,&xx,&bx,&fa,&fx,&fb,pcom,xicom,functor);
165 *fret=brent_tp(ax,xx,bx,TOL,&xmin,pcom,xicom,functor);
179template <
typename T,
typename F>
194 std::vector<T> simplex((n+1)*(n+1));
196 T **xi =
new T*[n+1];
197 xi[0] = simplex.data();
198 for (
long i = 1; i <= n; ++i) xi[i] = xi[0] + i * (n+1);
200 for (
long i = 0; i <= n; ++i){
201 xi[i][i] = 2*sqrt(ftol);
202 for (
long j = i+1; j <= n; ++j) {
203 xi[i][j] = xi[j][i] = 0;
207 std::vector<T> pt(n+1);
208 std::vector<T> ptt(n+1);
209 std::vector<T> xit(n+1);
210 *fret = functor(p+1);
211 for (j=1;j<=n;j++) pt[j]=p[j];
212 for (*iter=1;;++(*iter)) {
217 for (j=1;j<=n;j++) xit[j]=xi[j][i];
219 linmind_tp(p,xit.data(),n,fret,functor);
220 if (fptt-(*fret) > del) {
225 if (2.0*(fp-(*fret)) <= ftol*(fabs(fp)+fabs(*fret))+TINY) {
229 throw std::runtime_error(
"powell_tp exceeding maximum iterations.");
232 ptt[j]=2.0*p[j]-pt[j];
236 fptt=functor(ptt.data()+1);
238 t=2.0*(fp-2.0*(*fret)+fptt)*sqrt(fp-(*fret)-del)-del*sqrt(fp-fptt);
240 linmind_tp(p,xit.data(),n,fret,functor);
242 xi[j][ibig]=xi[j][n];