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: 2005/03/07 12:32:19 $
00007 Version:   $Revision: 1.23 $
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       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   } ; // end of class Iterator 
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 } ; // end of class
00285 
00286 std::ostream& operator<< (std::ostream& os, 
00287                           MultivariateLegendrePolynomial& poly) ;
00288 } // end of namespace itk
00289 #endif

Generated at Wed May 24 23:42:13 2006 for ITK by doxygen 1.3.5 written by Dimitri van Heesch, © 1997-2000