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];