proj home

Files   Classes   Functions   Hierarchy  

lineopgold.h

Go to the documentation of this file.
00001 #ifndef LINEOPGOLD_H
00002 #define LINEOPGOLD_H
00003 
00004 #include <vec.h>
00005 #include <typeop.h>
00006 
00007 /*
00008   \brief  Golden ratio line optimization.
00009 
00010   Find the minimum in an interval.
00011 */
00012 template< typename EXP >
00013 class lineopgold
00014 {
00015 
00016 public:
00017 
00018 
00019 //  typedef typename typeop<EXP>::Tconst::Tconst Tconst
00020   typedef typename typeop<EXP>::Tbare::Ttype T;
00021   typedef typename typeop<EXP>::Tref EXP2;
00022 
00023   typedef T const Tconst;
00024 
00026   EXP2 exp;
00027 
00028   uintc N;
00029 
00031   T* di;
00032 
00034   lineopgold(EXP2 _exp); 
00036   ~lineopgold();
00037 
00039   T const hlarge() const;
00040 
00042   bool const minimize( T const hstep, uintc kiterations );
00043 
00044 protected:
00045 
00047   T* X0;
00049   T X0fmin; 
00050 
00052   T ti[4];
00053 
00055   T fxk[4];
00056 
00058   static T goldratio;
00059 
00060 #ifndef NDEBUG
00061   bool const verifyti( uintc ai0, uintc ai1, uintc ai2, uintc ai3) const;
00062 #endif
00063 
00064 };
00065 
00066 
00067 template< typename EXP >
00068 typename lineopgold<EXP>::T lineopgold<EXP>::goldratio = 0.61803398875;
00069 
00070 
00071 template< typename EXP >
00072 bool const lineopgold<EXP>::minimize( T const hstep, uintc kiterations )
00073 {
00074   assert( kiterations>6); // Make minimization effective, min 4+k function evaluations.
00075   // Save the current state.
00076   uint k;
00077   for ( k=0; k<N; ++k)
00078     X0[k] = exp.xi[k];
00079   X0fmin = exp.fn.fmin;
00080 
00081   // Indexes to vectors.
00082   uint ai0=0;
00083   uint ai1=1;
00084   uint ai2=2;
00085   uint ai3=3;
00086   uint rej;
00087 
00088   // these are the 4 points about xi which are being sampled.
00089   T len = goldratio*hstep*2.0;
00090   ti[0] = -hstep;
00091   ti[3] = hstep;
00092   ti[1] = ti[3]-len;
00093   ti[2] = ti[0]+len; 
00094 
00095   // Evaluate the function at the 4 points.
00096   for ( k=0; k<N; ++k)
00097     exp.xi[k] = X0[k] + di[k]*ti[ai0]; 
00098   exp.fn(fxk[ai0]);
00099 
00100   for ( k=0; k<N; ++k)
00101     exp.xi[k] = X0[k] + di[k]*ti[ai3];
00102   exp.fn(fxk[ai3]);
00103 
00104   for ( k=0; k<N; ++k)
00105     exp.xi[k] = X0[k] + di[k]*ti[ai1];
00106   exp.fn(fxk[ai1]);
00107 
00108   for ( k=0; k<N; ++k)
00109     exp.xi[k] = X0[k] + di[k]*ti[ai2];
00110   exp.fn(fxk[ai2]);
00111 
00112   // Minimization
00113   for (uint i=0; i<kiterations; ++i)
00114   {
00115     len *= goldratio;
00116 
00117     // Test - reject x0 if successful.
00118     if (fxk[ai2]<fxk[ai1])
00119     {
00120       // Reject x0 
00121       rej = ai0;
00122       ai0 = ai1;
00123       ai1 = ai2;
00124       ai2 = rej;
00125       ti[ai2] = ti[ai3]-len;
00126       assert(verifyti(ai0,ai1,ai2,ai3));
00127       for ( k=0; k<N; ++k)
00128         exp.xi[k] = X0[k] + di[k]*ti[ai2];
00129       exp.fn(fxk[ai2]);
00130     }
00131     else
00132     {
00133       // Reject x3 
00134       rej = ai3;
00135       ai3 = ai2;
00136       ai2 = ai1;
00137       ai1 = rej;
00138       ti[ai1] = ti[ai0]+len;
00139       assert(verifyti(ai0,ai1,ai2,ai3));
00140       for ( k=0; k<N; ++k)
00141         exp.xi[k] = X0[k] + di[k]*ti[ai1];
00142       exp.fn(fxk[ai1]);
00143     }
00144   }
00145 
00146   // Find the new minimum.
00147   if (fxk[ai1]<fxk[ai2])
00148   {
00149     if (fxk[ai1]<X0fmin)
00150     {
00151       for ( k=0; k<N; ++k)
00152         exp.xi[k] = X0[k] + di[k]*ti[ai1];
00153       exp.fmin = fxk[ai1]; 
00154 
00155       return true;
00156     }
00157   }
00158   else
00159   {
00160     if (fxk[ai2]<X0fmin)
00161     {
00162       for ( k=0; k<N; ++k)
00163         exp.xi[k] = X0[k] + di[k]*ti[ai2];
00164       exp.fmin = fxk[ai2]; 
00165 
00166       return true;
00167     }
00168   }
00169 
00170   // Restore the original position, no change.
00171   for ( k=0; k<N; ++k)
00172     exp.xi[k] = X0[k];
00173   exp.fmin = X0fmin;
00174 
00175   return false;
00176 }
00177 
00178 
00179 template< typename EXP >
00180 lineopgold<EXP>::lineopgold(EXP2 _exp) 
00181   : exp(_exp), N(exp.N), di(new T[N]),  
00182     X0(new T[N])
00183 {
00184 }
00185 
00186 
00187 template< typename EXP >
00188 lineopgold<EXP>::~lineopgold()
00189 {
00190   delete[] di; 
00191   delete[] X0;
00192 }
00193 
00194 
00195 template< typename EXP >
00196 typename lineopgold<EXP>::T const lineopgold<EXP>::hlarge() const
00197 {
00198   T h = exp.hi[0];
00199   if (h<0)
00200     h *= -1.0;
00201   T y;
00202   for (uint i=1; i<N; ++i)
00203   {
00204     y = exp.hi[0];
00205     if (y<0)
00206       y += -1.0;
00207 
00208     if (y>h)
00209       h=y;
00210   }
00211 
00212   return h;
00213 }
00214 
00215 
00216 template< typename EXP >
00217 bool const lineopgold<EXP>::verifyti
00218 (
00219   uintc ai0, 
00220   uintc ai1, 
00221   uintc ai2, 
00222   uintc ai3
00223 ) const
00224 {
00225   bool valid=true;
00226 
00227   if ( ti[ai1] < ti[ai0] )
00228     valid=false;
00229   if ( ti[ai2] < ti[ai0] )
00230     valid=false;
00231   if ( ti[ai3] < ti[ai0] )
00232     valid=false;
00233 
00234   if ( ti[ai2] < ti[ai1] )
00235     valid=false;
00236   if ( ti[ai3] < ti[ai1] )
00237     valid=false;
00238 
00239   if ( ti[ai3] < ti[ai2] )
00240     valid=false;
00241 
00242   if (valid==false)
00243   {
00244     cout << "error: ai indexes incorrect" << endl;
00245     cout << SHOW(ai0) << " " << SHOW(ai1) << " ";
00246     cout << SHOW(ai2) << " " << SHOW(ai3) << endl;
00247 
00248     cout << SHOW(ti[0]) << " " << SHOW(ti[1]) << " ";
00249     cout << SHOW(ti[2]) << " " << SHOW(ti[3]) << endl;
00250   }
00251      
00252   return valid;
00253 }
00254 
00255 
00256 
00257 
00258 #endif
00259 
00260 

Generated on Fri Mar 4 00:49:30 2011 for Chelton Evans Source by  doxygen 1.5.8