00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
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
00120
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
00145
00146
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
00162 MeasureType measure;
00163
00164 ParametersType parameters = ConvertInternalToParameter(x);
00165
00166 m_CostFunction->GetValueAndDerivative( parameters, measure, m_CachedDerivative );
00167
00168 if( g )
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
00198
00199
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 }
00297
00298
00299
00300
00301