00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkMultivariateLegendrePolynomial_h
00018 #define __itkMultivariateLegendrePolynomial_h
00019
00020 #include "itkIndent.h"
00021 #include <vector>
00022 #include "itkArray.h"
00023
00024 namespace itk {
00025
00070 class MultivariateLegendrePolynomial
00071 {
00072 public:
00073 typedef MultivariateLegendrePolynomial Self ;
00074
00075 typedef std::vector< double > DoubleArrayType ;
00076 typedef std::vector< unsigned long > ULongArrayType ;
00077 typedef std::vector< long > LongArrayType ;
00078
00080 typedef DoubleArrayType CoefficientArrayType ;
00081
00084 typedef Array< double > ParametersType ;
00085
00087 typedef ULongArrayType DomainSizeType ;
00088 typedef LongArrayType IndexType ;
00089
00091 MultivariateLegendrePolynomial( unsigned int dimension,
00092 unsigned int degree,
00093 const DomainSizeType & domainSize );
00095 virtual ~MultivariateLegendrePolynomial();
00096
00098 unsigned int GetDimension(void) const
00099 { return m_Dimension ; }
00100
00102 unsigned int GetDegree(void) const
00103 { return m_Degree ; }
00104
00110 unsigned int GetNumberOfCoefficients(void) const
00111 { return m_NumberOfCoefficients; }
00112
00114 const DomainSizeType & GetDomainSize( void ) const
00115 { return m_DomainSize; }
00116
00118 class CoefficientVectorSizeMismatch
00119 {
00120 public:
00121 CoefficientVectorSizeMismatch(int given, int required)
00122 {
00123 Required = required ;
00124 Given = given ;
00125 }
00126
00127 int Required;
00128 int Given ;
00129 } ;
00130
00135 void SetCoefficients(const CoefficientArrayType& coef)
00136 throw (CoefficientVectorSizeMismatch) ;
00137
00138 void SetCoefficients(const ParametersType& coef)
00139 throw (CoefficientVectorSizeMismatch) ;
00140
00142 const CoefficientArrayType& GetCoefficients(void) const;
00143
00146 double Evaluate(IndexType& index)
00147 {
00148 if (m_Dimension == 2)
00149 {
00150 if (index[1] != m_PrevY)
00151 {
00152
00153 double norm_y = m_NormFactor[1] *
00154 static_cast<double>( index[1] - 1 );
00155 this->CalculateXCoef(norm_y, m_CoefficientArray) ;
00156 m_PrevY = index[1] ;
00157 }
00158
00159
00160 double norm_x = m_NormFactor[0] *
00161 static_cast<double>( index[0] - 1 );
00162
00163 return LegendreSum(norm_x, m_Degree, m_CachedXCoef) ;
00164 }
00165 else if (m_Dimension == 3)
00166 {
00167 if (index[2] != m_PrevZ )
00168 {
00169
00170 double norm_z = m_NormFactor[2] *
00171 static_cast<double>( index[2] - 1 );
00172 this->CalculateYCoef(norm_z, m_CoefficientArray) ;
00173 m_PrevZ = index[2] ;
00174 }
00175
00176 if (index[1] != m_PrevY)
00177 {
00178
00179 double norm_y = m_NormFactor[1] *
00180 static_cast<double>( index[1] - 1 );
00181 this->CalculateXCoef(norm_y, m_CachedYCoef) ;
00182 m_PrevY = index[1] ;
00183 }
00184
00185
00186 double norm_x = m_NormFactor[0] *
00187 static_cast<double>( index[0] - 1 );
00188 return this->LegendreSum(norm_x, m_Degree, m_CachedXCoef) ;
00189 }
00190 return 0 ;
00191 }
00192
00194 unsigned int GetNumberOfCoefficients();
00195
00197 unsigned int GetNumberOfCoefficients(unsigned int dimension, unsigned int degree) ;
00198
00201 class SimpleForwardIterator
00202 {
00203 public:
00204 SimpleForwardIterator (MultivariateLegendrePolynomial* polynomial)
00205 {
00206 m_MultivariateLegendrePolynomial = polynomial ;
00207 m_Dimension = m_MultivariateLegendrePolynomial->GetDimension() ;
00208 m_DomainSize = m_MultivariateLegendrePolynomial->GetDomainSize() ;
00209 m_Index.resize(m_Dimension) ;
00210 std::fill(m_Index.begin(), m_Index.end(), 0) ;
00211 }
00212
00213 void Begin( void )
00214 {
00215 m_IsAtEnd = false ;
00216 for (unsigned int dim = 0 ; dim < m_Dimension ; dim++)
00217 {
00218 m_Index[dim] = 0 ;
00219 }
00220 }
00221
00222 bool IsAtEnd()
00223 { return m_IsAtEnd; }
00224
00225 SimpleForwardIterator& operator++()
00226 {
00227 for (unsigned int dim = 0 ; dim < m_Dimension ; dim++)
00228 {
00229 if (m_Index[dim] < static_cast<int>(m_DomainSize[dim] - 1))
00230 {
00231 m_Index[dim] += 1 ;
00232 return *this ;
00233 }
00234 else
00235 {
00236 if (dim == m_Dimension - 1 )
00237 {
00238 m_IsAtEnd = true ;
00239 break ;
00240 }
00241 else
00242 {
00243 m_Index[dim] = 0 ;
00244 }
00245 }
00246 }
00247 return *this ;
00248 }
00249
00250 double Get()
00251 { return m_MultivariateLegendrePolynomial->Evaluate(m_Index); }
00252
00253 private:
00254 MultivariateLegendrePolynomial* m_MultivariateLegendrePolynomial;
00255 unsigned int m_Dimension;
00256 DomainSizeType m_DomainSize;
00257 IndexType m_Index;
00258 bool m_IsAtEnd;
00259 } ;
00260
00261 void Print(std::ostream& os) ;
00262
00263 protected:
00264 void PrintSelf(std::ostream& os, Indent indent) const;
00265 double LegendreSum(const double x, int n, const CoefficientArrayType& coef,
00266 int offset = 0);
00267 void CalculateXCoef(double norm_y, const CoefficientArrayType& coef);
00268 void CalculateYCoef(double norm_z, const CoefficientArrayType& coef);
00269
00270 private:
00271 DomainSizeType m_DomainSize;
00272 unsigned int m_Dimension;
00273 unsigned int m_Degree;
00274 unsigned int m_NumberOfCoefficients;
00275 bool m_MultiplicativeBias;
00276
00277 CoefficientArrayType m_CoefficientArray;
00278 CoefficientArrayType m_CachedXCoef;
00279 CoefficientArrayType m_CachedYCoef;
00280 CoefficientArrayType m_CachedZCoef;
00281 DoubleArrayType m_NormFactor;
00282 long m_PrevY ;
00283 long m_PrevZ ;
00284 } ;
00285
00286 std::ostream& operator<< (std::ostream& os,
00287 MultivariateLegendrePolynomial& poly) ;
00288 }
00289 #endif