00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "freConstrainedOnePlusOneEvolutionarySOOptimizer.h"
00024
00025 #include "itkEventObject.h"
00026
00027 #include "vcl_cmath.h"
00028 #include "vnl/vnl_matrix.h"
00029
00030 namespace FREE
00031 {
00032
00033 ConstrainedOnePlusOneEvolutionarySOOptimizer
00034 ::ConstrainedOnePlusOneEvolutionarySOOptimizer()
00035 {
00036 m_Maximize = false;
00037 m_Epsilon = (double) 1.5e-4 ;
00038 m_RandomGenerator = 0 ;
00039
00040 m_Initialized = false ;
00041 m_GrowthFactor = 1.05 ;
00042 m_ShrinkFactor = pow(m_GrowthFactor, -0.25) ;
00043 m_InitialRadius = 1.01 ;
00044 m_MaximumIteration = 100 ;
00045 m_Stop = false ;
00046 m_CurrentValue = 0;
00047 m_CurrentIteration = 0;
00048 m_FrobeniusNorm = 0.0;
00049 }
00050
00051 ConstrainedOnePlusOneEvolutionarySOOptimizer
00052 ::~ConstrainedOnePlusOneEvolutionarySOOptimizer()
00053 {
00054 }
00055
00056 void
00057 ConstrainedOnePlusOneEvolutionarySOOptimizer
00058 ::SetNormalVariateGenerator(NormalVariateGeneratorType* generator)
00059 {
00060 if ( m_RandomGenerator != generator )
00061 {
00062 m_RandomGenerator = generator ;
00063 this->Modified() ;
00064 }
00065 }
00066
00067 void
00068 ConstrainedOnePlusOneEvolutionarySOOptimizer
00069 ::Initialize(double initialRadius, double grow, double shrink)
00070 {
00071 m_InitialRadius = initialRadius ;
00072
00073 if (grow == -1)
00074 m_GrowthFactor = 1.05 ;
00075 else
00076 m_GrowthFactor = grow ;
00077
00078 if (shrink == -1)
00079 m_ShrinkFactor = pow(m_GrowthFactor, -0.25) ;
00080 else
00081 m_ShrinkFactor = shrink ;
00082 }
00083
00084 void
00085 ConstrainedOnePlusOneEvolutionarySOOptimizer
00086 ::PrintSelf(std::ostream& os, itk::Indent indent) const
00087 {
00088 Superclass::PrintSelf(os,indent);
00089
00090 if (m_RandomGenerator)
00091 {
00092 os << indent << "Random Generator " << m_RandomGenerator.GetPointer() << std::endl;
00093 }
00094 else
00095 {
00096 os << indent << "Random Generator " << "(none)" << std::endl;
00097 }
00098 os << indent << "Maximum Iteration " << m_MaximumIteration << std::endl;
00099 os << indent << "Epsilon " << m_Epsilon << std::endl;
00100 os << indent << "Initial Radius " << m_InitialRadius << std::endl;
00101 os << indent << "Growth Fractor " << m_GrowthFactor << std::endl;
00102 os << indent << "Shrink Fractor " << m_ShrinkFactor << std::endl;
00103 os << indent << "Initialized " << m_Initialized << std::endl;
00104 os << indent << "Current Cost " << m_CurrentValue << std::endl;
00105 os << indent << "Current Iteration " << m_CurrentIteration << std::endl;
00106 os << indent << "Frobenius Norm " << m_FrobeniusNorm << std::endl;
00107 os << indent << "Maximize On/Off " << m_Maximize << std::endl;
00108 }
00109
00110
00111 void
00112 ConstrainedOnePlusOneEvolutionarySOOptimizer
00113 ::CheckTraitsOfChild( vnl_vector<double>& child )
00114 {
00115 unsigned int spaceDimension = m_CostFunction->GetNumberOfParameters();
00116 ParametersType tempChildPosition(spaceDimension) ;
00117 ParametersType validChildPosition(spaceDimension) ;
00118
00119 tempChildPosition = child;
00120
00121 this->GetCostFunction()->GetTransform()->ComputeParametersTraits(tempChildPosition, validChildPosition);
00122
00123 for( unsigned int i=0; i<spaceDimension; i++)
00124 {
00125 child[i] = validChildPosition[i];
00126 }
00127 }
00128
00129
00130 void
00131 ConstrainedOnePlusOneEvolutionarySOOptimizer
00132 ::StartOptimization( void )
00133 {
00134 if( m_CostFunction.IsNull() )
00135 {
00136 return ;
00137 }
00138
00139 this->InvokeEvent( itk::StartEvent() );
00140 m_Stop = false ;
00141
00142 unsigned int spaceDimension = m_CostFunction->GetNumberOfParameters();
00143 vnl_matrix<double> A(spaceDimension, spaceDimension) ;
00144 vnl_vector<double> parent(this->GetInitialPosition());
00145 vnl_vector<double> f_norm(spaceDimension);
00146 vnl_vector<double> child(spaceDimension);
00147 vnl_vector<double> delta(spaceDimension);
00148
00149 ParametersType parentPosition( spaceDimension );
00150 ParametersType childPosition(spaceDimension) ;
00151
00152 for( unsigned int i=0; i<spaceDimension; i++)
00153 {
00154 parentPosition[i] = parent[i];
00155 }
00156
00157 itkDebugMacro(<< ": initial position: " << parentPosition) ;
00158 double pvalue = m_CostFunction->GetValue(parentPosition);
00159
00160
00161 this->m_CurrentValue = pvalue;
00162 this->m_CurrentChildValue = pvalue;
00163 this->m_CurrentDecomposedValue = this->m_CostFunction->GetCurrentDecomposedValue();
00164 this->m_CurrentChildPosition = this->m_CostFunction->GetCurrentParameters();
00165 this->SetCurrentPosition(parentPosition) ;
00166
00167 this->InvokeEvent( itk::IterationEvent() );
00168
00169
00170
00171 const Optimizer::ScalesType& scales = this->GetScales() ;
00172
00173
00174 if (scales.size() != spaceDimension)
00175 {
00176 itkExceptionMacro(<< "The size of Scales is "
00177 << scales.size()
00178 << ", but the NumberOfParameters for the CostFunction is "
00179 << spaceDimension
00180 << ".");
00181 }
00182
00183 A.set_identity() ;
00184 for(unsigned int i = 0 ; i < spaceDimension ; i++)
00185 {
00186 A(i,i) = m_InitialRadius / scales[i] ;
00187 }
00188 m_CurrentIteration = 0 ;
00189
00190 for (unsigned int iter = 0 ; iter < m_MaximumIteration ; iter++)
00191 {
00192 if ( m_Stop )
00193 {
00194 break ;
00195 }
00196
00197 ++m_CurrentIteration ;
00198
00199 for (unsigned int i=0 ; i < spaceDimension ; i++)
00200 {
00201 if(!m_RandomGenerator)
00202 {
00203 itkExceptionMacro(<< "Random Generator is not set!");
00204 }
00205 f_norm[i] = m_RandomGenerator->GetVariate() ;
00206 }
00207
00208 delta = A * f_norm ;
00209 child = parent + delta ;
00210
00211
00212
00213
00214
00215 this->CheckTraitsOfChild(child);
00216
00217 for( unsigned int i=0; i<spaceDimension; i++)
00218 {
00219 childPosition[i] = child[i];
00220 }
00221
00222 double cvalue = m_CostFunction->GetValue(childPosition);
00223
00224 itkDebugMacro(<< iter << ": parent: " << pvalue
00225 << " child: "<< cvalue );
00226
00227 double adjust = m_ShrinkFactor ;
00228 if( m_Maximize )
00229 {
00230 if (cvalue > pvalue)
00231 {
00232 pvalue = cvalue ;
00233 parent.swap(child) ;
00234 adjust = m_GrowthFactor ;
00235 for( unsigned int i=0; i<spaceDimension; i++)
00236 {
00237 parentPosition[i] = parent[i];
00238 }
00239 this->SetCurrentPosition(parentPosition) ;
00240 }
00241 }
00242 else
00243 {
00244 if (cvalue < pvalue)
00245 {
00246 pvalue = cvalue ;
00247 parent.swap(child) ;
00248 adjust = m_GrowthFactor ;
00249 for( unsigned int i=0; i<spaceDimension; i++)
00250 {
00251 parentPosition[i] = parent[i];
00252 }
00253 this->SetCurrentPosition(parentPosition) ;
00254 }
00255 }
00256
00257
00258
00259
00260 m_FrobeniusNorm = A.fro_norm() ;
00261 itkDebugMacro(<< "A f-norm:" << m_FrobeniusNorm);
00262 if (m_FrobeniusNorm <= m_Epsilon)
00263 {
00264 itkDebugMacro(<< "converges at iteration = " << iter) ;
00265 break ;
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 double alpha = ((adjust - 1.0) / dot_product(f_norm, f_norm)) ;
00282 for ( unsigned int c = 0 ; c < spaceDimension ; c++ )
00283 {
00284 for (unsigned int r = 0 ; r < spaceDimension ; r++)
00285 {
00286 A(r, c) += alpha * delta[r] * f_norm[c];
00287 }
00288 }
00289
00290 this->m_CurrentChildValue = this->m_CostFunction->GetCurrentValue();
00291 this->m_CurrentDecomposedValue = this->m_CostFunction->GetCurrentDecomposedValue();
00292 this->m_CurrentChildPosition = this->m_CostFunction->GetCurrentParameters();
00293 this->m_CurrentValue = pvalue;
00294
00295 m_BestValue = m_CurrentValue;
00296 m_BestPosition = this->GetCurrentPosition();
00297
00298 this->InvokeEvent( itk::IterationEvent() );
00299 itkDebugMacro(<< "Current position: " << this->GetCurrentPosition()) ;
00300 }
00301 this->InvokeEvent( itk::EndEvent() );
00302 }
00303
00304 }
00305
00306