freConstrainedOnePlusOneEvolutionarySOOptimizer.cxx

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   F.R.E.E. - flexible registration evaluation engine
00004   Version:   v.1.0.0
00005   Date:      $Date: 2006/09/01 12:00:00 $
00006   Module:    $RCSfile: freConstrainedOnePlusOneEvolutionarySOOptimizer.cxx,v $
00007   Language:  C++
00008 
00009 
00010 
00011   Copyright (c) 2007 Ralf o Floca (Department of Medical Informatics,
00012   Institute for Medical Biometry and Informatics, University of Heidelberg,
00013   Germany). All rights reserved.
00014   See FREECopyright.txt or http://www.mi.med.uni-hd.de/free/copyright.htm
00015   for details.
00016 
00017      This software is distributed WITHOUT ANY WARRANTY; without even 
00018      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
00019      PURPOSE.  See the above copyright notices for more information.
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         //In difference to the itk implementation the calculation of the first parent generates also
00160         //an iteration event.
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   // Make sure the scales have been set properly
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                 //Check if parameters of child are valid in context
00212                 //of the parameter traits.
00213                 //This function call distinguishes the orignial itk::implementation from
00214                 //the f.r.e.e. implementation.
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     // convergence criterion: f-norm of A < epsilon_A
00258     // Compute double precision sum of absolute values of 
00259     // a single precision vector
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     // A += (adjust - 1)/ (f_norm * f_norm) * A * f_norm * f_norm ;
00269     // Blas_R1_Update(A, A * f_norm, f_norm, 
00270     //             ((adjust - 1) / Blas_Dot_Prod(f_norm, f_norm)));    
00271     // = DGER(Fortran)
00272     //   performs the rank 1 operation
00273     // A := alpha*x*y' + A,
00274     // where y' = transpose(y)
00275     // where alpha is a scalar, x is a m element vector, y is a n element
00276     // vector and A is a m by n matrix.
00277     // x = A * f_norm , y = f_norm, alpha = (adjust - 1) / Blas_Dot_Prod(
00278     // f_norm, f_norm)
00279 
00280     //A = A + (adjust - 1.0) * A ;
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 } // end namespace FREE
00305 
00306 

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