Documentation


powell.h

Go to the documentation of this file.
00001 #ifndef NR_POWELL_H
00002 #define NR_POWELL_H
00003 
00004 #include <math.h>
00005 #include "utils.h"
00006 #include "linmin.h"
00007 
00008 namespace nr {
00009 
00010 
00014 template < class TraitsT = Old_Traits<> >
00015 struct powell {
00016 
00018     typedef TraitsT Traits;
00020     typedef typename Traits::Real Real;
00022     typedef typename Traits::Vector Vector;
00024     typedef typename Traits::Matrix Matrix;
00025 
00028     
00033     template <class Func>
00034     powell (
00035         Vector& p, 
00036         Matrix& xi, 
00037         unsigned int n, 
00038         Real ftol, 
00039         unsigned int *iter, 
00040         Real *fret, 
00041         Func (*func), 
00042         unsigned int ITMAX = 200 
00043     )
00044     {
00045         unsigned int i,ibig,j;
00046         Real del,fp,fptt,t;
00047         Vector pt, ptt, xit;
00048 
00049         Traits::alloc_vector( pt, n );
00050         Traits::alloc_vector( ptt, n );
00051         Traits::alloc_vector( xit, n );
00052 
00053         *fret=(*func)(p);
00054         for (j=0;j<n;j++) pt[j]=p[j];
00055         for (*iter=1;;++(*iter)) {
00056             fp=(*fret);
00057             ibig=0;
00058             del=0.0;
00059             for (i=0;i<n;i++) {
00060                 for (j=0;j<n;j++) xit[j]=xi[j][i];
00061                 fptt=(*fret);
00062                 linmin<Traits>(p,xit,n,fret,func,ftol);
00063                 if (fabs(fptt-(*fret)) > del) {
00064                     del=fabs(fptt-(*fret));
00065                     ibig=i;
00066                 }
00067             }
00068             if (2.0*fabs(fp-(*fret)) <= ftol*(fabs(fp)+fabs(*fret))) {
00069                 Traits::free_vector( pt );
00070                 Traits::free_vector( ptt );
00071                 Traits::free_vector( xit );
00072                 return;
00073             }
00074             if (*iter == ITMAX) {
00075                 throw TooManyIterations( *iter, *fret );
00076             }
00077             for (j=0;j<n;j++) {
00078                 ptt[j]=2.0*p[j]-pt[j];
00079                 xit[j]=p[j]-pt[j];
00080                 pt[j]=p[j];
00081             }
00082             fptt=(*func)(ptt);
00083             if (fptt < fp) {
00084                 t=2.0*(fp-2.0*(*fret)+fptt)*SQR(fp-(*fret)-del)-del*SQR(fp-fptt);
00085                 if (t < 0.0) {
00086                     linmin<Traits>(p,xit,n,fret,func);
00087                     for (j=0;j<n;j++) {
00088                         xi[j][ibig]=xi[j][n-1];
00089                         xi[j][n-1]=xit[j];
00090                     }
00091                 }
00092             }
00093         }
00094     }
00095 
00099     template <class Func>
00100     powell (
00101         Vector& p, 
00102         unsigned int n, 
00103         Real ftol, 
00104         unsigned int *iter, 
00105         Real *fret, 
00106         Func (*func),
00107         unsigned int ITMAX = 200 
00108     )
00109     {
00110         Matrix unit_xi;
00111         Traits::alloc_matrix( unit_xi, n, n );
00112         for( int i=0; i<n; ++i ){
00113             for( int j=0; j<n; ++j ){
00114                 unit_xi[i][j] = i==j ? 1 : 0;
00115             }
00116         }
00117 
00118         powell( p, unit_xi, n, ftol, iter, fret, func, ITMAX );
00119 
00120         Traits::free_matrix(unit_xi,n,n);
00121 
00122     }
00123     
00125 
00126     
00129     struct TooManyIterations 
00130     {
00131         unsigned int nbIterations;   
00132         Real functionValue;          
00133 
00135         TooManyIterations ( unsigned int n, Real f )
00136             : nbIterations( n )
00137             , functionValue( f )
00138         {}
00139         
00140 
00143 
00145         void print ( std::ostream& str ) const
00146         {
00147             str << "powell gives up after " << nbIterations
00148                 << " iterations, function value = " << functionValue
00149                 << endl;
00150         }
00151         
00153 
00154     };
00155 
00156 };
00157 
00158 } // end namespace nr
00159 #endif

Generated on Thu Dec 23 13:52:27 2004 by doxygen 1.3.6