Files Classes Functions Hierarchy
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
1.5.8