itkContinuousLBFGSOptimizer.cxx

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Insight Segmentation & Registration Toolkit
00004   Module:    $RCSfile: itkContinuousLBFGSOptimizer.cxx,v $
00005   Language:  C++
00006   Date:      $Date: 2005/03/15 02:19:46 $
00007   Version:   $Revision: 1.20 $
00008 
00009   Copyright (c) Insight Software Consortium. All rights reserved.
00010   See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
00011 
00012      This software is distributed WITHOUT ANY WARRANTY; without even 
00013      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
00014      PURPOSE.  See the above copyright notices for more information.
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   // set the optimizer parameters
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   // If the user provides the scales then we set otherwise we don't
00246   // for computation speed.
00247   // We also scale the initial parameters up if scales are defined.
00248   // This compensates for later scaling them down in the cost function adaptor
00249   // and at the end of this function.  
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   // vnl optimizers return the solution by reference 
00263   // in the variable provided as initial position
00264   m_VnlOptimizer->minimize( parameters );
00265 
00266   if ( parameters.size() != initialPosition.size() )
00267     { //there was an error in the optimization process
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     { // we scale the parameters down if scales are defined
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 } // end namespace itk
00303 
00304 #endif

Generated at Sat Oct 13 18:14:02 2007 for f.r.e.e. - Flexible Registration and Evaluation Engine by doxygen 1.5.3 written by Dimitri van Heesch, © 1997-2000