00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "freAmoebaSOOptimizer.h"
00020 #include "itkCommand.h"
00021 #include "itkEventObject.h"
00022
00023 namespace FREE
00024 {
00025
00026 AmoebaSOOptimizer
00027 ::AmoebaSOOptimizer()
00028 : m_InitialSimplexDelta(1)
00029 {
00030 m_OptimizerInitialized = false;
00031 m_VnlOptimizer = 0;
00032 m_MaximumNumberOfIterations = 500;
00033 m_ParametersConvergenceTolerance = 1e-8;
00034 m_FunctionConvergenceTolerance = 1e-4;
00035 m_AutomaticInitialSimplex = true;
00036 m_InitialSimplexDelta.Fill(itk::NumericTraits<ParametersType::ValueType>::One);
00037 }
00038
00039 AmoebaSOOptimizer
00040 ::~AmoebaSOOptimizer()
00041 {
00042 if (m_VnlOptimizer) delete m_VnlOptimizer;
00043 }
00044
00045 void
00046 AmoebaSOOptimizer
00047 ::PrintSelf(std::ostream& os, itk::Indent indent) const
00048 {
00049 Superclass::PrintSelf(os,indent);
00050
00051 os << indent << "MaximumNumberOfIterations: "
00052 << m_MaximumNumberOfIterations << std::endl;
00053 os << indent << "ParametersConvergenceTolerance: "
00054 << m_ParametersConvergenceTolerance << std::endl;
00055 os << indent << "FunctionConvergenceTolerance: "
00056 << m_FunctionConvergenceTolerance << std::endl;
00057 os << indent << "AutomaticInitialSimplex: "
00058 << (m_AutomaticInitialSimplex ? "On" : "Off") << std::endl;
00059 os << indent << "InitialSimplexDelta: "
00060 << m_InitialSimplexDelta << std::endl;
00061 }
00062
00063 AmoebaSOOptimizer::MeasureType
00064 AmoebaSOOptimizer
00065 ::GetValue (const ParametersType ¶meters)
00066 {
00067 ParametersType scaledParameters = parameters;
00068 if(m_ScalesInitialized)
00069 {
00070 const ScalesType scales = this->GetScales();
00071 for(unsigned int i=0;i<parameters.size();i++)
00072 {
00073 scaledParameters[i] *= scales[i];
00074 }
00075 }
00076 return this->GetNonConstCostFunctionAdaptor()->f( scaledParameters );
00077 };
00078
00079 AmoebaSOOptimizer::DecomposedMeasureType
00080 AmoebaSOOptimizer
00081 ::GetDecomposedValue (const ParametersType ¶meters)
00082 {
00083 this->GetValue(parameters);
00084 return this->GetNonConstCostFunctionAdaptor()->GetCachedDecomposedValue();
00085 };
00086
00087 void
00088 AmoebaSOOptimizer
00089 ::SetMaximumNumberOfIterations( unsigned int n )
00090 {
00091 if ( n == m_MaximumNumberOfIterations )
00092 {
00093 return;
00094 }
00095
00096 m_MaximumNumberOfIterations = n;
00097 if ( m_OptimizerInitialized )
00098 {
00099 m_VnlOptimizer->set_max_iterations( static_cast<int>( n ) );
00100 }
00101 this->Modified();
00102 }
00103
00104 void
00105 AmoebaSOOptimizer
00106 ::SetParametersConvergenceTolerance( double tol )
00107 {
00108 if ( tol == m_ParametersConvergenceTolerance )
00109 {
00110 return;
00111 }
00112
00113 m_ParametersConvergenceTolerance = tol;
00114 if ( m_OptimizerInitialized )
00115 {
00116 m_VnlOptimizer->set_x_tolerance( tol );
00117 }
00118
00119 this->Modified();
00120 }
00121
00122 void
00123 AmoebaSOOptimizer
00124 ::SetFunctionConvergenceTolerance( double tol )
00125 {
00126 if ( tol == m_FunctionConvergenceTolerance )
00127 {
00128 return;
00129 }
00130
00131 m_FunctionConvergenceTolerance = tol;
00132 if ( m_OptimizerInitialized )
00133 {
00134 m_VnlOptimizer->set_f_tolerance( tol );
00135 }
00136
00137 this->Modified();
00138 }
00139
00140 void
00141 AmoebaSOOptimizer::
00142 SetCostFunction( CostFunctionType * costFunction )
00143 {
00144 const unsigned int numberOfParameters =
00145 costFunction->GetNumberOfParameters();
00146
00147 CostFunctionAdaptorType * adaptor =
00148 new CostFunctionAdaptorType( numberOfParameters );
00149
00150 this->m_CostFunction = costFunction;
00151 adaptor->SetCostFunction( costFunction );
00152
00153 if( m_OptimizerInitialized )
00154 {
00155 delete m_VnlOptimizer;
00156 }
00157
00158 this->SetCostFunctionAdaptor( adaptor );
00159
00160 m_VnlOptimizer = new vnl_amoeba( *adaptor );
00161
00162
00163 m_VnlOptimizer->set_max_iterations( static_cast<int>( m_MaximumNumberOfIterations ) );
00164 m_VnlOptimizer->set_x_tolerance( m_ParametersConvergenceTolerance );
00165 m_VnlOptimizer->set_f_tolerance( m_FunctionConvergenceTolerance );
00166
00167 m_OptimizerInitialized = true;
00168 }
00169
00170 void
00171 AmoebaSOOptimizer
00172 ::StartOptimization( void )
00173 {
00174
00175 this->InvokeEvent( itk::StartEvent() );
00176
00177 if( this->GetMaximize() )
00178 {
00179 this->GetNonConstCostFunctionAdaptor()->NegateCostFunctionOn();
00180 }
00181
00182 ParametersType initialPosition = this->GetInitialPosition();
00183
00184 ParametersType parameters( initialPosition );
00185
00186
00187
00188
00189
00190
00191 if(m_ScalesInitialized)
00192 {
00193 ScalesType scales = this->GetScales();
00194 this->GetNonConstCostFunctionAdaptor()->SetScales(scales);
00195 for(unsigned int i=0;i<parameters.size();i++)
00196 {
00197 parameters[i] *= scales[i];
00198 }
00199 }
00200
00201
00202
00203 if (m_AutomaticInitialSimplex)
00204 {
00205 m_VnlOptimizer->minimize( parameters );
00206 }
00207 else
00208 {
00209 InternalParametersType delta( m_InitialSimplexDelta );
00210
00211 m_VnlOptimizer->minimize( parameters, delta );
00212 }
00213
00214
00215 if(m_ScalesInitialized)
00216 {
00217 ScalesType scales = this->GetScales();
00218 for(unsigned int i=0;i<parameters.size();i++)
00219 {
00220 parameters[i] /= scales[i];
00221 }
00222 }
00223
00224 this->SetCurrentPosition( parameters );
00225
00226 m_BestPosition = parameters;
00227 m_BestValue = this->GetCachedValue();
00228
00229 this->InvokeEvent( itk::EndEvent() );
00230 }
00231
00232 vnl_amoeba *
00233 AmoebaSOOptimizer
00234 ::GetOptimizer()
00235 {
00236 return m_VnlOptimizer;
00237 }
00238
00239 }
00240
00241