freSingleValuedVnlSOMetricAdaptor.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: freSingleValuedVnlSOMetricAdaptor.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 #include "freSingleValuedVnlSOMetricAdaptor.h"
00023 
00024 namespace FREE
00025 {
00026   
00028 SingleValuedVnlSOMetricAdaptor 
00029 ::SingleValuedVnlSOMetricAdaptor(unsigned int spaceDimension):
00030   vnl_cost_function(spaceDimension) 
00031 { 
00032   m_ScalesInitialized = false;
00033   m_NegateCostFunction = false;
00034         m_Reporter = itk::Object::New();
00035 }    
00036 
00037     
00039 void
00040 SingleValuedVnlSOMetricAdaptor
00041 ::SetScales(const ScalesType & scales)
00042 {
00043         if (scales.size()!=this->get_number_of_unknowns()) throwExceptionMacro("Error: number of parameter scales ("<<scales.size()<<") doesn't equal the defined number of parameters ("<<this->get_number_of_unknowns()<<").")
00044   m_Scales = scales;
00045   m_ScalesInitialized = true;
00046 }   
00047 
00048 SingleValuedVnlSOMetricAdaptor::ParametersType
00049 SingleValuedVnlSOMetricAdaptor::
00050 ConvertInternalToParameter(const InternalParametersType & inparameters)
00051 {
00052         // Use scales if they are provided
00053         ParametersType parameters(inparameters.size());
00054         if(m_ScalesInitialized)
00055         {
00056                 for(unsigned int i=0;i<parameters.size();i++)
00057                 {
00058                         parameters[i] = inparameters[i]/m_Scales[i];
00059                 }
00060         }
00061         else
00062         {
00063                 parameters.SetData(const_cast<double*>(inparameters.data_block()));
00064         }
00065 
00066         return parameters;
00067 };
00068 
00069 SingleValuedVnlSOMetricAdaptor::InternalParametersType
00070 SingleValuedVnlSOMetricAdaptor::
00071 ConvertParameterToInternal(const ParametersType & parameters)
00072 {
00073         // Use scales if they are provided
00074         InternalParametersType inparameters(parameters.Size());
00075         
00076         for(unsigned int i=0;i<parameters.size();i++)
00077         {
00078                 if(m_ScalesInitialized)
00079                 {
00080                         inparameters[i] = parameters[i]*m_Scales[i];
00081                 }
00082                 else
00083                 {
00084                         inparameters[i] = parameters[i];
00085                 }
00086         }
00087 
00088         return parameters;
00089 };
00090 
00092 SingleValuedVnlSOMetricAdaptor::InternalMeasureType 
00093 SingleValuedVnlSOMetricAdaptor
00094 ::f( const InternalParametersType & inparameters )
00095 {
00096         if( !m_CostFunction )
00097         {
00098                 itkGenericExceptionMacro(<<"Attempt to use a SingleValuedVnlSOMetricAdaptor without any CostFunction plugged in");
00099         }
00100 
00101         ParametersType parameters = ConvertInternalToParameter(inparameters);
00102 
00103         m_CachedValue = m_CostFunction->GetValue( parameters );
00104         m_CachedCurrentParameters = parameters;
00105         m_CachedDecomposedValue = this->m_CostFunction->GetCurrentDecomposedValue();
00106 
00107         if( m_NegateCostFunction )
00108         {
00109                 m_CachedValue = -1.0*m_CachedValue;
00110 
00111                 for (unsigned int index=0; index < m_CachedDecomposedValue.GetSize(); index++)
00112                 {
00113                         m_CachedDecomposedValue[index] = -1.0*m_CachedDecomposedValue[index];
00114                 }
00115         }
00116 
00117         InternalMeasureType value = static_cast<InternalMeasureType>(m_CachedValue);
00118 
00119         // Notify observers. This is used for overcoming the limitaion of VNL
00120         // optimizers of not providing callbacks per iteration.
00121         this->ReportIteration( itk::FunctionEvaluationIterationEvent() ); 
00122 
00123         return value;
00124 }
00125   
00126 
00127 
00129 void 
00130 SingleValuedVnlSOMetricAdaptor
00131 ::gradf(  const InternalParametersType   & inparameters,
00132           InternalDerivativeType   & gradient       )
00133 {
00134   if( !m_CostFunction )
00135     {
00136     itkGenericExceptionMacro("Attempt to use a SingleValuedVnlSOMetricAdaptor without any CostFunction plugged in");
00137     }
00138 
00139         ParametersType parameters = ConvertInternalToParameter(inparameters);
00140     
00141   m_CostFunction->GetDerivative( parameters, m_CachedDerivative );
00142   this->ConvertExternalToInternalGradient( m_CachedDerivative, gradient);
00143  
00144   // Notify observers. This is used for overcoming the limitaion of VNL
00145   // optimizers of not providing callbacks per iteration.
00146   // Note that m_CachedDerivative is already loaded in the GetDerivative() above.
00147   m_CachedCurrentParameters = parameters;
00148         this->ReportIteration( itk::GradientEvaluationIterationEvent() ); 
00149  
00150 }
00151   
00152 
00153 
00155 void 
00156 SingleValuedVnlSOMetricAdaptor
00157 ::compute( const InternalParametersType   & x,
00158            InternalMeasureType      * f, 
00159            InternalDerivativeType   * g   ) 
00160 {
00161   // delegate the computation to the CostFunction
00162   MeasureType    measure;
00163 
00164         ParametersType parameters = ConvertInternalToParameter(x);
00165   
00166   m_CostFunction->GetValueAndDerivative( parameters, measure, m_CachedDerivative );
00167 
00168   if( g ) // sometimes Vnl doesn't pass a valid pointer
00169     {
00170     this->ConvertExternalToInternalGradient( m_CachedDerivative, *g );
00171     }
00172 
00173         if( m_NegateCostFunction )
00174         {
00175                 measure = -1.0*measure;
00176         }
00177 
00178         m_CachedValue = measure;
00179   m_CachedCurrentParameters = parameters;
00180         m_CachedDecomposedValue = this->m_CostFunction->GetCurrentDecomposedValue();
00181 
00182         if( m_NegateCostFunction )
00183         {
00184                 m_CachedValue = -1.0*m_CachedValue;
00185 
00186                 for (unsigned int index=0; index < m_CachedDecomposedValue.GetSize(); index++)
00187                 {
00188                         m_CachedDecomposedValue[index] = -1.0*m_CachedDecomposedValue[index];
00189                 }
00190         }
00191 
00192         if( f )
00193   {
00194     *f = static_cast<InternalMeasureType>( m_CachedValue );  
00195   }
00196 
00197         // Notify observers. This is used for overcoming the limitaion of VNL
00198   // optimizers of not providing callbacks per iteration.
00199   // Note that m_CachedDerivative is already loaded in the GetDerivative() above.
00200         this->ReportIteration( itk::FunctionAndGradientEvaluationIterationEvent() ); 
00201  
00202 }
00203   
00204 
00206 void 
00207 SingleValuedVnlSOMetricAdaptor
00208 ::ConvertExternalToInternalGradient( const DerivativeType   & input,
00209                                      InternalDerivativeType & output ) const
00210 {
00211   const unsigned int size = input.size();
00212   output = InternalDerivativeType(size);
00213   for( unsigned int i=0; i<size; i++ ) 
00214     {
00215     if( !m_NegateCostFunction )
00216       {
00217       output[i] = input[i];
00218       }
00219     else
00220       {
00221       output[i] = -input[i];
00222       }
00223     }
00224 }
00225 
00226 
00229 void 
00230 SingleValuedVnlSOMetricAdaptor
00231 ::SetNegateCostFunction( bool flag )
00232 {
00233   m_NegateCostFunction = flag;
00234 }
00235                                    
00238 bool 
00239 SingleValuedVnlSOMetricAdaptor
00240 ::GetNegateCostFunction() const
00241 {
00242   return m_NegateCostFunction;
00243 }
00244 
00247 void 
00248 SingleValuedVnlSOMetricAdaptor
00249 ::ReportIteration( const itk::EventObject & event ) const
00250 {
00251   this->m_Reporter->InvokeEvent( event );
00252 }
00253  
00256 unsigned long 
00257 SingleValuedVnlSOMetricAdaptor
00258 ::AddObserver(const itk::EventObject & event, itk::Command * command) const
00259 {
00260   return m_Reporter->AddObserver( event, command );
00261 }
00262 
00263 
00265 const SingleValuedVnlSOMetricAdaptor::MeasureType &
00266 SingleValuedVnlSOMetricAdaptor
00267 ::GetCachedValue() const
00268 {
00269   return m_CachedValue;
00270 }
00271 
00273 const SingleValuedVnlSOMetricAdaptor::DecomposedMeasureType &
00274 SingleValuedVnlSOMetricAdaptor
00275 ::GetCachedDecomposedValue() const
00276 {
00277   return m_CachedDecomposedValue;
00278 }
00279 
00281 const SingleValuedVnlSOMetricAdaptor::DerivativeType &
00282 SingleValuedVnlSOMetricAdaptor
00283 ::GetCachedDerivative() const
00284 {
00285   return m_CachedDerivative;
00286 }
00287 
00289 const SingleValuedVnlSOMetricAdaptor::ParametersType &
00290 SingleValuedVnlSOMetricAdaptor
00291 ::GetCachedCurrentParameters() const
00292 {
00293   return m_CachedCurrentParameters;
00294 }
00295 
00296 } // end namespace itk
00297 
00298 
00299 
00300 
00301 

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