00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _itkContinuousLBFGSOptimizer_txx
00018 #define _itkContinuousLBFGSOptimizer_txx
00019
00020 #include "itkContinuousLBFGSOptimizer.h"
00021
00022 namespace itk
00023 {
00024
00028 ContinuousLBFGSOptimizer
00029 ::ContinuousLBFGSOptimizer()
00030 {
00031 m_OptimizerInitialized = false;
00032 m_VnlOptimizer = 0;
00033 m_ErrorOccurred = false;
00034 m_Trace = false;
00035 m_MaximumNumberOfFunctionEvaluations = 2000;
00036 m_GradientConvergenceTolerance = 1e-5;
00037 m_LineSearchAccuracy = 0.9;
00038 m_DefaultStepLength = 1.0;
00039 }
00040
00041
00045 ContinuousLBFGSOptimizer
00046 ::~ContinuousLBFGSOptimizer()
00047 {
00048 delete m_VnlOptimizer;
00049 }
00050
00054 void
00055 ContinuousLBFGSOptimizer
00056 ::PrintSelf(std::ostream& os, Indent indent) const
00057 {
00058 Superclass::PrintSelf( os, indent );
00059 os << indent << "Trace: ";
00060 if ( m_Trace ) { os << "On"; } else { os << "Off"; }
00061 os << std::endl;
00062 os << indent << "MaximumNumberOfFunctionEvaluations: ";
00063 os << m_MaximumNumberOfFunctionEvaluations << std::endl;
00064 os << indent << "GradientConvergenceTolerance: ";
00065 os << m_GradientConvergenceTolerance << std::endl;
00066 os << indent << "LineSearchAccuracy: ";
00067 os << m_LineSearchAccuracy << std::endl;
00068 os << indent << "DefaultStepLength: ";
00069 os << m_DefaultStepLength << std::endl;
00070 os << indent << "ErrorOccured: ";
00071 os << m_ErrorOccurred << std::endl;
00072
00073 }
00074
00078 void
00079 ContinuousLBFGSOptimizer
00080 ::SetTrace( bool flag )
00081 {
00082 if ( flag == m_Trace )
00083 {
00084 return;
00085 }
00086
00087 m_Trace = flag;
00088 if ( m_OptimizerInitialized )
00089 {
00090 m_VnlOptimizer->set_trace( m_Trace );
00091 }
00092
00093 this->Modified();
00094 }
00095
00099 void
00100 ContinuousLBFGSOptimizer
00101 ::SetMaximumNumberOfFunctionEvaluations( unsigned int n )
00102 {
00103 if ( n == m_MaximumNumberOfFunctionEvaluations )
00104 {
00105 return;
00106 }
00107
00108 m_MaximumNumberOfFunctionEvaluations = n;
00109 if ( m_OptimizerInitialized )
00110 {
00111 m_VnlOptimizer->set_max_function_evals(
00112 static_cast<int>( m_MaximumNumberOfFunctionEvaluations ) );
00113 }
00114
00115 this->Modified();
00116 }
00117
00121 void
00122 ContinuousLBFGSOptimizer
00123 ::SetGradientConvergenceTolerance( double f )
00124 {
00125 if ( f == m_GradientConvergenceTolerance )
00126 {
00127 return;
00128 }
00129
00130 m_GradientConvergenceTolerance = f;
00131 if ( m_OptimizerInitialized )
00132 {
00133 m_VnlOptimizer->set_g_tolerance( m_GradientConvergenceTolerance );
00134 }
00135
00136 this->Modified();
00137 }
00138
00142 void
00143 ContinuousLBFGSOptimizer
00144 ::SetLineSearchAccuracy( double f )
00145 {
00146 if ( f == m_LineSearchAccuracy )
00147 {
00148 return;
00149 }
00150
00151 m_LineSearchAccuracy = f;
00152 if ( m_OptimizerInitialized )
00153 {
00154 m_VnlOptimizer->line_search_accuracy = m_LineSearchAccuracy;
00155 }
00156
00157 this->Modified();
00158 }
00159
00163 void
00164 ContinuousLBFGSOptimizer
00165 ::SetDefaultStepLength( double f )
00166 {
00167 if ( f == m_DefaultStepLength )
00168 {
00169 return;
00170 }
00171
00172 m_DefaultStepLength = f;
00173 if ( m_OptimizerInitialized )
00174 {
00175 m_VnlOptimizer->default_step_length = m_DefaultStepLength;
00176 }
00177
00178 this->Modified();
00179 }
00180
00182 ContinuousLBFGSOptimizer::MeasureType
00183 ContinuousLBFGSOptimizer
00184 ::GetValue()
00185 {
00186 return this->GetNonConstCostFunctionAdaptor()->f(this->GetCurrentPosition());
00187 }
00188
00192 void
00193 ContinuousLBFGSOptimizer
00194 ::SetCostFunction( SingleValuedCostFunction * costFunction )
00195 {
00196 const unsigned int numberOfParameters =
00197 costFunction->GetNumberOfParameters();
00198
00199 CostFunctionAdaptorType * adaptor =
00200 new CostFunctionAdaptorType( numberOfParameters );
00201
00202 adaptor->SetCostFunction( costFunction );
00203
00204 if( m_OptimizerInitialized )
00205 {
00206 delete m_VnlOptimizer;
00207 }
00208
00209 this->SetCostFunctionAdaptor( adaptor );
00210
00211 m_VnlOptimizer = new vnl_lbfgs( *adaptor );
00212
00213
00214 m_VnlOptimizer->set_trace( m_Trace );
00215 m_VnlOptimizer->set_max_function_evals(
00216 static_cast<int>( m_MaximumNumberOfFunctionEvaluations ) );
00217 m_VnlOptimizer->set_g_tolerance( m_GradientConvergenceTolerance );
00218 m_VnlOptimizer->line_search_accuracy = m_LineSearchAccuracy;
00219 m_VnlOptimizer->default_step_length = m_DefaultStepLength;
00220
00221 m_OptimizerInitialized = true;
00222
00223 }
00224
00225
00226
00230 void
00231 ContinuousLBFGSOptimizer
00232 ::StartOptimization( void )
00233 {
00234
00235 this->InvokeEvent( StartEvent() );
00236
00237 if( this->GetMaximize() )
00238 {
00239 this->GetNonConstCostFunctionAdaptor()->NegateCostFunctionOn();
00240 }
00241
00242 ParametersType initialPosition = this->GetInitialPosition();
00243 ParametersType parameters( initialPosition );
00244
00245
00246
00247
00248
00249
00250 if(m_ScalesInitialized)
00251 {
00252 ScalesType scales = this->GetScales();
00253 this->GetNonConstCostFunctionAdaptor()->SetScales(scales);
00254 for(unsigned int i=0;i<parameters.size();i++)
00255 {
00256 parameters[i] *= scales[i];
00257 }
00258 }
00259
00260 m_ErrorOccurred = false;
00261
00262
00263
00264 m_VnlOptimizer->minimize( parameters );
00265
00266 if ( parameters.size() != initialPosition.size() )
00267 {
00268 m_ErrorOccurred = true;
00269 std::cerr << std::endl << "Error occured on in lbfgs optimizer. Continued with initial position." << std::endl;
00270 parameters = initialPosition;
00271 }
00272 else if(m_ScalesInitialized)
00273 {
00274 ScalesType scales = this->GetScales();
00275 for(unsigned int i=0;i<parameters.size();i++)
00276 {
00277 parameters[i] /= scales[i];
00278 }
00279 }
00280
00281 this->SetCurrentPosition( parameters );
00282
00283 this->InvokeEvent( EndEvent() );
00284 }
00285
00286
00287
00288
00292 vnl_lbfgs *
00293 ContinuousLBFGSOptimizer
00294 ::GetOptimizer()
00295 {
00296 return m_VnlOptimizer;
00297 }
00298
00299
00300
00301
00302 }
00303
00304 #endif