00001 #ifndef NR_LINMIN_H
00002 #define NR_LINMIN_H
00003
00004 #include <iostream>
00005 #include "brent.h"
00006 #include "mnbrak.h"
00007
00008 namespace nr {
00009
00010
00014 template < class TraitsT = Old_Traits<> >
00015 struct linmin {
00016
00018 typedef TraitsT Traits;
00020 typedef typename Traits::Real Real;
00022 typedef typename Traits::Vector Vector;
00023
00026
00031 template < class Func >
00032 linmin (
00033 Vector& p,
00034 Vector& xi,
00035 unsigned int n,
00036 Real *fret,
00037 Func (*func),
00038 const Real TOL = 2.0e-4
00039 )
00040 {
00041 unsigned int j;
00042 Real xx,xmin,fx,fb,fa,bx,ax;
00043
00044 F1dim<Real,Vector,Func> f1dim;
00045 Traits::alloc_vector(f1dim.pcom,n);
00046 Traits::alloc_vector(f1dim.xicom,n);
00047 Traits::alloc_vector(f1dim.xt,n);
00048 f1dim.funct = func;
00049 f1dim.ncom = n;
00050
00051 for (j=0;j<n;j++) {
00052 f1dim.pcom[j]=p[j];
00053 f1dim.xicom[j]=xi[j];
00054 }
00055 ax=0.0;
00056 xx=1.0;
00057
00058
00059 mnbrak(&ax,&xx,&bx,&fa,&fx,&fb,&f1dim);
00060
00061 *fret=brent(ax,xx,bx,&f1dim,TOL,&xmin);
00062
00063
00064
00065 for (j=0;j<n;j++) {
00066 xi[j] *= xmin;
00067 p[j] += xi[j];
00068 }
00069
00070
00071 Traits::free_vector( f1dim.pcom );
00072 Traits::free_vector( f1dim.xicom );
00073 Traits::free_vector( f1dim.xt );
00074
00075 }
00076
00077
00079
00080
00082 template < class Real, class Vector, class Func >
00083 struct F1dim
00084 {
00086 Real operator () (Real x)
00087 {
00088
00089 for ( unsigned int j=0;j<ncom;j++) {
00090 xt[j]=pcom[j]+x*xicom[j];
00091 }
00092
00093 return (*funct)( xt );
00094 }
00095
00097 F1dim(){}
00098
00099 Vector xt;
00100 Vector pcom;
00101 Vector xicom;
00102 unsigned int ncom;
00103 Func (*funct);
00104
00105 };
00106
00107 };
00108
00109 }
00110
00111
00112
00113 #endif