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 }
00217
00218
bool IsAtEnd()
00219 {
return m_IsAtEnd; }
00220
00221 SimpleForwardIterator&
operator++()
00222 {
00223
for (
unsigned int dim = 0 ; dim < m_Dimension ; dim++)
00224 {
00225
if (m_Index[dim] < static_cast<int>(m_DomainSize[dim] - 1))
00226 {
00227 m_Index[dim] += 1 ;
00228
return *
this ;
00229 }
00230
else
00231 {
00232
if (dim == m_Dimension - 1 )
00233 {
00234 m_IsAtEnd =
true ;
00235
break ;
00236 }
00237
else
00238 {
00239 m_Index[dim] = 0 ;
00240 }
00241 }
00242 }
00243
return *
this ;
00244 }
00245
00246
double Get()
00247 {
return m_MultivariateLegendrePolynomial->
Evaluate(m_Index); }
00248
00249 private:
00250
MultivariateLegendrePolynomial* m_MultivariateLegendrePolynomial;
00251
unsigned int m_Dimension;
00252
DomainSizeType m_DomainSize;
00253
IndexType m_Index;
00254
bool m_IsAtEnd;
00255 } ;
00256
00257
void Print(std::ostream& os) ;
00258
00259
protected:
00260
void PrintSelf(std::ostream& os,
Indent indent)
const;
00261
double LegendreSum(
const double x,
int n,
const CoefficientArrayType& coef,
00262
int offset = 0);
00263
void CalculateXCoef(
double norm_y,
const CoefficientArrayType& coef);
00264
void CalculateYCoef(
double norm_z,
const CoefficientArrayType& coef);
00265
00266
private:
00267
DomainSizeType m_DomainSize;
00268
unsigned int m_Dimension;
00269
unsigned int m_Degree;
00270
unsigned int m_NumberOfCoefficients;
00271
bool m_MultiplicativeBias;
00272
00273
CoefficientArrayType m_CoefficientArray;
00274
CoefficientArrayType m_CachedXCoef;
00275
CoefficientArrayType m_CachedYCoef;
00276
CoefficientArrayType m_CachedZCoef;
00277
DoubleArrayType m_NormFactor;
00278
long m_PrevY ;
00279
long m_PrevZ ;
00280 } ;
00281
00282 std::ostream&
operator<< (std::ostream& os,
00283
MultivariateLegendrePolynomial& poly) ;
00284 }
00285
#endif