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 }
00159 #endif