proj home

Files   Classes   Functions   Hierarchy  

lineoptimizerparabola.h

Go to the documentation of this file.
00001 #ifndef LINEOPTIMIZERPARABOLA_H
00002 #define LINEOPTIMIZERPARABOLA_H
00003 
00004 #include <cassert>
00005 #include <iostream>
00006 using namespace std;
00007 
00008 typedef unsigned int const uintc;
00009 
00010 #include <typeop.h>
00011 #include <print.h>
00012 
00013 #include <lineoptimizergold2.h>
00014 
00015 
00016 
00041 template< typename LNPATH, typename T >
00042 class lineoptimizerparabola : public lineoptimizergold2<LNPATH,T>
00043 {
00044 public:
00045 
00046   typedef lineoptimizergold2<LNPATH,T> lopg;
00047 
00049   static T zero;
00050 
00052   lineoptimizerparabola( LNPATH linepath_) :
00053     lineoptimizergold2<LNPATH,T>(linepath_) {}
00054 
00056   bool const parabolamin
00057   (
00058     T & tnew,
00059     uintc a0,
00060     uintc a1, 
00061     uintc a2 
00062   ) const;
00063 
00064   //void convergencetest();
00065 
00067   void operator ++ ();
00068 
00069 };
00070 
00071 //-----------------------------------------------
00072 //  Implementation
00073 
00074 /*
00075 KEEP THIS CODE, even though it failed to deliver a gain.
00076 template< typename LNPATH, typename T >
00077 void lineoptimizerparabola<LNPATH,T>::convergencetest()
00078 {
00079   T df0 = lopg::fti[lopg::ai[1]] - lopg::fti[lopg::ai[0]];
00080   df0 *= df0;
00081 
00082   T df3 = lopg::fti[lopg::ai[3]] - lopg::fti[lopg::ai[2]];
00083   df3 *= df3;
00084 
00085   T factor=40.0;
00086 
00087   // Test for convergence from the left hand side.
00088   if ( lopg::fti[lopg::ai[2]] < lopg::fti[lopg::ai[1]] )
00089   {
00090     if (df0*factor<df3)
00091     {
00092       T t = lopg::ti[lopg::ai[2]] + lopg::ti[lopg::ai[1]] - lopg::ti[lopg::ai[0]];
00093       T ft;
00094       lopg::linepath.fneval(ft,t);
00095       if (lopg::fti[lopg::ai[2]] < ft)
00096       {
00097         lopg::ti[lopg::ai[3]] = t;
00098         lopg::fti[lopg::ai[3]] = ft;
00099 cout << "modified" << endl;
00100       }
00101     
00102       return;
00103     }
00104   }
00105 }
00106 */
00107 
00108 
00109 template< typename LNPATH, typename T >
00110 void lineoptimizerparabola<LNPATH,T>::operator ++ ()
00111 {
00112   lopg::lengthgold *= lopg::goldratio;
00113 //cout << SHOW(lengthgold) << endl;
00114 
00115   // Minimization
00116   uint rej;
00117 
00118   T w;
00119 
00120   //printstate();
00121 
00122   // Test - reject x0 if successful.
00123   if (lopg::fti[lopg::ai[2]]<lopg::fti[lopg::ai[1]])
00124   {
00125 
00126     // If parabola minimization fails, do two gold section minimizations
00127     if (parabolamin(w,lopg::ai[1],lopg::ai[2],lopg::ai[3])==false)
00128     {
00129 cout << "parabolamin failed in x0 rejection." << endl;
00130 
00131       rej = lopg::ai[0];
00132 //cout << "parab min failed, rejecting x0" << endl;
00133 lopg::printstate();
00134       lopg::ai[0] = lopg::ai[1];
00135       lopg::ai[1] = rej;
00136       lopg::resetInnerTwoPoints();
00137 
00138       return;
00139     }
00140 
00141 //cout << "Reject x0" << endl;
00142     rej = lopg::ai[0];
00143     lopg::ti[rej] = w;
00144     lopg::linepath.fneval(lopg::fti[rej],lopg::ti[rej]);
00145     lopg::ai[0] = lopg::ai[1];
00146 
00147     if (w<lopg::ti[lopg::ai[2]])
00148       lopg::ai[1] = rej;
00149     else
00150     {
00151       lopg::ai[1] = lopg::ai[2];
00152       lopg::ai[2] = rej;
00153     }
00154 
00155     //convergencetest();
00156 
00157     //printstate();
00158     assert(lopg::verify());
00159     return;
00160   }
00161 
00162 
00163 //cout << "Reject x3" << endl;
00164   rej = lopg::ai[3];
00165 
00166   // Test - reject x3 if successful.
00167   if (lopg::fti[lopg::ai[1]]<lopg::fti[lopg::ai[2]])
00168   {
00169 
00170     // If parabola minimization fails, do two gold section minimizations
00171     if (parabolamin(w,lopg::ai[0],lopg::ai[1],lopg::ai[2])==false)
00172     {
00173 cout << "parabolamin failed in x3 rejection." << endl;
00174 //cout << "parab min failed, rejecting x3" << endl;
00175       rej = lopg::ai[3];
00176 
00177       lopg::ai[3] = lopg::ai[2];
00178       lopg::ai[2] = rej;
00179       lopg::resetInnerTwoPoints();
00180 
00181       return;
00182     }
00183 
00184 //cout << "Reject x0" << endl;
00185     rej = lopg::ai[3];
00186     lopg::ti[rej] = w;
00187     lopg::linepath.fneval(lopg::fti[rej],lopg::ti[rej]);
00188     lopg::ai[3] = lopg::ai[2];
00189 
00190     if (w<lopg::ti[lopg::ai[1]])
00191     {
00192       lopg::ai[2] = lopg::ai[1];
00193       lopg::ai[1] = rej;
00194     }
00195     else
00196     {
00197       lopg::ai[2] = rej;
00198     }
00199 
00200     //printstate();
00201     assert(lopg::verify());
00202     return;
00203   }
00204 
00205   // No interval can be rejected because both points are the same height.
00206   // This is a hack. If the value between 1 and 2 is the same then the method
00207   // will fail.  
00208   lopg::ti[lopg::ai[1]] += lopg::ti[ lopg::ai[2] ];
00209   lopg::ti[lopg::ai[1]] *= (T)0.5;
00210   lopg::linepath.fneval(lopg::fti[lopg::ai[1]],lopg::ti[lopg::ai[1]]);
00211 
00212 }
00213 
00214 
00215 template< typename LNPATH, typename T >
00216 bool const lineoptimizerparabola<LNPATH,T>::parabolamin
00217 (
00218   T & tnew, 
00219   uintc a0,
00220   uintc a1, 
00221   uintc a2 
00222 ) const
00223 {
00224 // Scale and minimize
00225 // max/min at -b/2a = (-q^2*f2+q^2*f0+f1-f0)/(2*(f1-f0+q(f0-f2))
00226 // where q=(t1-t0)/(t2-t0)
00227   assert( lopg::ti[a2] != lopg::ti[a0] );
00228 
00229   T f5 = lopg::fti[a1]-lopg::fti[a0];
00230   T q = (lopg::ti[a1]-lopg::ti[a0])/(lopg::ti[a2]-lopg::ti[a0]);
00231   T den = (f5+q*(lopg::fti[a0]-lopg::fti[a2]))*2;
00232   if ( den*den < zero )
00233     return false;
00234   T num = q*q*(lopg::fti[a0]-lopg::fti[a2])+f5;
00235   T w = num/den;
00236   if (w<=(T)0.0)
00237     return false;
00238   if (w>=(T)1.0)
00239     return false;
00240 
00241   tnew = lopg::ti[a0] + (lopg::ti[a2]-lopg::ti[a0])*w;
00242 
00243   return true;
00244 }
00245 
00246 
00247 template< typename LNPATH, typename T >
00248 T lineoptimizerparabola<LNPATH,T>::zero = 1E-20;
00249 
00250 #endif
00251 
00252 

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