Main Page   Groups   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Concepts

itkMultivariateLegendrePolynomial.h

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003 Program:   Insight Segmentation & Registration Toolkit
00004 Module:    $RCSfile: itkMultivariateLegendrePolynomial.h,v $
00005 Language:  C++
00006 Date:      $Date: 2003/09/10 14:29:38 $
00007 Version:   $Revision: 1.22 $
00008 
00009 Copyright (c) Insight Software Consortium. All rights reserved.
00010 See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
00011 
00012 This software is distributed WITHOUT ANY WARRANTY; without even 
00013 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
00014 PURPOSE.  See the above copyright notices for more information.
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         // normalized y [-1, 1]
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       // normalized x [-1, 1]
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         // normalized z [-1, 1]  
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         // normalized y [-1, 1]
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       // normalized x [-1, 1]
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   } ; // end of class Iterator 
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 } ; // end of class
00281 
00282 std::ostream& operator<< (std::ostream& os, 
00283                           MultivariateLegendrePolynomial& poly) ;
00284 } // end of namespace itk
00285 #endif

Generated at Wed Mar 30 00:04:23 2005 for ITK by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2000