17 #ifndef __itkLBFGSBOptimizer_txx
18 #define __itkLBFGSBOptimizer_txx
21 #include "vnl/algo/vnl_lbfgsb.h"
22 #include <vnl/vnl_math.h>
50 virtual bool report_iter();
65 m_OptimizerInitialized =
false;
73 m_CostFunctionConvergenceFactor = 1e+7;
74 m_ProjectedGradientTolerance = 1e-5;
75 m_MaximumNumberOfIterations = 500;
76 m_MaximumNumberOfEvaluations = 500;
77 m_MaximumNumberOfCorrections = 5;
78 m_CurrentIteration = 0;
79 m_InfinityNormOfProjectedGradient = 0.0;
80 m_StopConditionDescription.str(
"");
91 delete m_VnlOptimizer;
101 Superclass::PrintSelf(os, indent);
102 os << indent <<
"Trace: ";
112 os << indent <<
"LowerBound: " << m_LowerBound << std::endl;
113 os << indent <<
"UpperBound: " << m_UpperBound << std::endl;
114 os << indent <<
"BoundSelection: " << m_BoundSelection << std::endl;
116 os << indent <<
"CostFunctionConvergenceFactor: " <<
117 m_CostFunctionConvergenceFactor << std::endl;
119 os << indent <<
"ProjectedGradientTolerance: " <<
120 m_ProjectedGradientTolerance << std::endl;
122 os << indent <<
"MaximumNumberOfIterations: " <<
123 m_MaximumNumberOfIterations << std::endl;
125 os << indent <<
"MaximumNumberOfEvaluations: " <<
126 m_MaximumNumberOfEvaluations << std::endl;
128 os << indent <<
"MaximumNumberOfCorrections: " <<
129 m_MaximumNumberOfCorrections << std::endl;
131 os << indent <<
"CurrentIteration: " <<
132 m_CurrentIteration << std::endl;
134 os << indent <<
"Value: " <<
135 this->GetValue() << std::endl;
137 os << indent <<
"InfinityNormOfProjectedGradient: " <<
138 m_InfinityNormOfProjectedGradient << std::endl;
140 if( this->m_VnlOptimizer )
142 os << indent <<
"Vnl LBFGSB Failure Code: " <<
143 this->m_VnlOptimizer->get_failure_code() << std::endl;
154 if ( flag == m_Trace )
160 if ( m_OptimizerInitialized )
162 m_VnlOptimizer->set_trace( m_Trace );
176 m_LowerBound = value;
177 if( m_OptimizerInitialized )
179 m_VnlOptimizer->set_lower_bound( m_LowerBound );
204 return this->GetCachedValue();
215 m_UpperBound = value;
216 if( m_OptimizerInitialized )
218 m_VnlOptimizer->set_upper_bound( m_UpperBound );
245 m_BoundSelection = value;
246 if( m_OptimizerInitialized )
248 m_VnlOptimizer->set_bound_selection( m_BoundSelection );
262 return m_BoundSelection;
278 itkExceptionMacro(
"Value " << value
279 <<
" is too small for SetCostFunctionConvergenceFactor()"
280 <<
"a typical range would be from 1.0 to 1e+12");
282 m_CostFunctionConvergenceFactor = value;
283 if( m_OptimizerInitialized )
285 m_VnlOptimizer->set_cost_function_convergence_factor(
286 m_CostFunctionConvergenceFactor );
300 m_ProjectedGradientTolerance = value;
301 if( m_OptimizerInitialized )
303 m_VnlOptimizer->set_projected_gradient_tolerance(
304 m_ProjectedGradientTolerance );
315 m_MaximumNumberOfIterations = value;
325 m_MaximumNumberOfEvaluations = value;
326 if( m_OptimizerInitialized )
328 m_VnlOptimizer->set_max_function_evals( m_MaximumNumberOfEvaluations );
339 m_MaximumNumberOfCorrections = value;
340 if( m_OptimizerInitialized )
342 m_VnlOptimizer->set_max_variable_metric_corrections(
343 m_MaximumNumberOfCorrections );
358 const unsigned int numberOfParameters =
364 adaptor->SetCostFunction( costFunction );
402 unsigned int numberOfParameters = m_CostFunction->GetNumberOfParameters();
404 if ( this->GetInitialPosition().
Size() < numberOfParameters )
406 itkExceptionMacro( <<
"InitialPosition array does not have sufficient number of elements" );
409 if ( m_LowerBound.size() < numberOfParameters )
411 itkExceptionMacro( <<
"LowerBound array does not have sufficient number of elements" );
414 if ( m_UpperBound.size() < numberOfParameters )
416 itkExceptionMacro( <<
"UppperBound array does not have sufficient number of elements" );
419 if ( m_BoundSelection.size() < numberOfParameters )
421 itkExceptionMacro( <<
"BoundSelection array does not have sufficient number of elements" );
424 if( this->GetMaximize() )
426 this->GetNonConstCostFunctionAdaptor()->NegateCostFunctionOn();
429 this->SetCurrentPosition( this->GetInitialPosition() );
434 m_StopConditionDescription.str(
"");
438 m_VnlOptimizer->minimize( parameters );
440 if ( parameters.size() != this->GetInitialPosition().
Size() )
443 this->SetCurrentPosition( this->GetInitialPosition() );
444 itkExceptionMacro( <<
"Error occured in optimization" );
447 this->SetCurrentPosition( parameters );
474 Superclass::report_iter();
476 m_ItkObj->m_InfinityNormOfProjectedGradient =
477 this->get_inf_norm_projected_gradient();
481 m_ItkObj->m_CurrentIteration = this->num_iterations_;
484 if( this->num_iterations_ > m_ItkObj->m_MaximumNumberOfIterations )
486 m_ItkObj->m_StopConditionDescription <<
487 "Too many iterations. Iterations = " <<
488 m_ItkObj->m_MaximumNumberOfIterations;
507 case vnl_nonlinear_minimizer::ERROR_FAILURE:
510 case vnl_nonlinear_minimizer::ERROR_DODGY_INPUT:
513 case vnl_nonlinear_minimizer::CONVERGED_FTOL:
517 <<
"The relative reduction of the cost function <= "
519 <<
" = CostFunctionConvergenceFactor ("
521 <<
") * machine precision ("
525 case vnl_nonlinear_minimizer::CONVERGED_XTOL:
528 case vnl_nonlinear_minimizer::CONVERGED_XFTOL:
531 case vnl_nonlinear_minimizer::CONVERGED_GTOL:
533 <<
"Projected gradient tolerance is "
536 case vnl_nonlinear_minimizer::FAILED_TOO_MANY_ITERATIONS:
540 case vnl_nonlinear_minimizer::FAILED_FTOL_TOO_SMALL:
543 case vnl_nonlinear_minimizer::FAILED_XTOL_TOO_SMALL:
546 case vnl_nonlinear_minimizer::FAILED_GTOL_TOO_SMALL:
549 case vnl_nonlinear_minimizer::FAILED_USER_REQUEST:
556 return std::string(
"");