00001 #ifndef NR_FRPRMN
00002 #define NR_FRPRMN
00003
00004 #include <iostream>
00005 #include "utils.h"
00006 #include "linmin.h"
00007 #include "dlinmin.h"
00008
00009 namespace nr {
00010
00014 template < class TraitsT = Old_Traits<> >
00015 struct frprmn
00016 {
00017
00019 typedef TraitsT Traits;
00021 typedef typename Traits::Real Real;
00023 typedef typename Traits::Vector Vector;
00024
00027
00036 template < class Func, class DFunc >
00037 frprmn (
00038 Vector& p,
00039 unsigned int n,
00040 Real ftol,
00041 unsigned int *iter,
00042 Real *fret,
00043 Func *funct,
00044 DFunc *gradient,
00045 unsigned int ITMAX = 200,
00046 Real TOL = 2.0e-4,
00047 Real EPS = 1.0e-10
00048 )
00049 {
00050 std::size_t j,its;
00051 Real gg,gam,fp,dgg;
00052 Vector g, h, xi;
00053
00054 Traits::alloc_vector( g, n );
00055 Traits::alloc_vector( h, n );
00056 Traits::alloc_vector( xi, n );
00057
00058 fp=(*funct)(p);
00059 (*gradient)(p,xi);
00060 for (j=0;j<n;j++) {
00061 g[j] = -xi[j];
00062 xi[j]=h[j]=g[j];
00063 }
00064 for (its=1;its<=ITMAX;its++) {
00065 *iter=its;
00066 dlinmin<Traits>(p,xi,n,fret,funct,gradient,TOL);
00067
00068
00069 if (2.0*fabs(*fret-fp) <= ftol*(fabs(*fret)+fabs(fp)+EPS)) {
00070
00071 Traits::free_vector( g );
00072 Traits::free_vector( h );
00073 Traits::free_vector( xi );
00074
00075 return;
00076 }
00077
00078 fp=(*funct)(p);
00079 (*gradient)(p,xi);
00080 dgg=gg=0.0;
00081
00082 for (j=0;j<n;j++) {
00083 gg += g[j]*g[j];
00084 dgg += (xi[j]+g[j])*xi[j];
00085 }
00086
00087 if ( gg == 0.0 ) {
00088
00089 Traits::free_vector( g );
00090 Traits::free_vector( h );
00091 Traits::free_vector( xi );
00092
00093 return;
00094 }
00095 gam=dgg/gg;
00096 for (j=0;j<n;j++) {
00097 g[j] = -xi[j];
00098 xi[j]=h[j]=g[j]+gam*h[j];
00099 }
00100
00101 }
00102
00103
00104 }
00105
00106
00108
00109
00112
00113 struct TooManyIterations
00114 {
00115 unsigned int nbIterations;
00116 Real functionValue;
00117
00119 TooManyIterations ( unsigned int n, Real f )
00120 : nbIterations( n )
00121 , functionValue( f )
00122 {}
00123
00126
00128 void print ( std::ostream& str ) const
00129 {
00130 str << "frprmn gives up after " << nbIterations
00131 << " iterations, function value = " << functionValue
00132 << std::endl;
00133 }
00134
00136
00137 };
00138
00139 };
00140
00141
00142 }
00143
00144
00145 #endif