00001 #ifndef NR_DLINMIN
00002 #define NR_DLINMIN
00003
00004 #include "mnbrak.h"
00005 #include "dbrent.h"
00006
00007 namespace nr {
00008
00012 template < class TraitsT = Old_Traits<> >
00013 struct dlinmin
00014 {
00015
00017 typedef TraitsT Traits;
00019 typedef typename Traits::Real Real;
00021 typedef typename Traits::Vector Vector;
00022
00025
00031 template < class Func, class DFunc >
00032 dlinmin (
00033 Vector& p,
00034 Vector& xi,
00035 unsigned int n,
00036 Real *fret,
00037 Func (*func),
00038 DFunc (*dfunc),
00039 Real TOL = 2.0e-4
00040 )
00041 : n(n)
00042 {
00043 unsigned int j;
00044 Real xx,xmin,fx,fb,fa,bx,ax;
00045
00046
00047
00048
00049
00050 Traits::alloc_vector( pcom, n );
00051 Traits::alloc_vector( xicom, n );
00052 Traits::alloc_vector( xt, n );
00053 Traits::alloc_vector( df, n );
00054
00055 F1dim< Real, Vector, Func > f1dim( func, xt, pcom, xicom, n );
00056 DF1dim< Real, Vector, DFunc > df1dim( dfunc, xt, pcom, xicom, df, n );
00057
00058 for (j=0;j<n;j++) {
00059 pcom[j]=p[j];
00060 xicom[j]=xi[j];
00061 }
00062 ax=0.0;
00063 xx=1.0;
00064 mnbrak(&ax,&xx,&bx,&fa,&fx,&fb,&f1dim);
00065 *fret=dbrent(ax,xx,bx,&f1dim,&df1dim,TOL,&xmin);
00066 for (j=0;j<n;j++) {
00067 xi[j] *= xmin;
00068 p[j] += xi[j];
00069 }
00070
00071 Traits::free_vector( pcom );
00072 Traits::free_vector( xicom );
00073 Traits::free_vector( xt );
00074 Traits::free_vector( df );
00075 }
00076
00077
00079
00080
00081 private:
00082
00083 Vector pcom;
00084 Vector xicom;
00085 Vector xt;
00086 Vector df;
00087 unsigned int n;
00088
00089
00091 template < class Real, class Vector, class Func >
00092 struct F1dim
00093 {
00094
00095 Func *func;
00096 Vector &xt;
00097 Vector &pcom;
00098 Vector &xicom;
00099 unsigned int n;
00100
00102 F1dim( Func *func, Vector& xt, Vector& pcom, Vector& xicom, unsigned int n )
00103 : func(func), xt(xt), pcom(pcom), xicom(xicom), n(n)
00104 {}
00105
00107 Real operator() (Real x)
00108 {
00109 unsigned int j;
00110
00111 for (j=0;j<n;j++) xt[j]=pcom[j]+x*xicom[j];
00112 return (*func)(xt);
00113 }
00114 };
00115
00117 template < class Real, class Vector, class DFunc >
00118 struct DF1dim
00119 {
00120
00121 DFunc *dfunc;
00122 Vector &xt;
00123 Vector &pcom;
00124 Vector &xicom;
00125 Vector &df;
00126 unsigned int n;
00127
00129 DF1dim( DFunc *dfunc, Vector& xt, Vector& pcom, Vector& xicom, Vector& df, unsigned int n )
00130 : dfunc(dfunc), xt(xt), pcom(pcom), xicom(xicom), df(df), n(n)
00131 {}
00132
00134 Real operator () (Real x)
00135 {
00136 unsigned int j;
00137 Real df1=0;
00138
00139 for (j=0;j<n;j++) xt[j]=pcom[j]+x*xicom[j];
00140 (*dfunc)(xt,df);
00141 for (j=0;j<n;j++) df1 += df[j]*xicom[j];
00142 return df1;
00143 }
00144 };
00145
00146 };
00147
00148
00149 }
00150
00151 #endif