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