ITK
4.1.0
Insight Segmentation and Registration Toolkit
|
00001 /*========================================================================= 00002 * 00003 * Copyright Insight Software Consortium 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0.txt 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 * 00017 *=========================================================================*/ 00018 #ifndef __itkMultivariateLegendrePolynomial_h 00019 #define __itkMultivariateLegendrePolynomial_h 00020 00021 #include "itkIntTypes.h" 00022 #include "itkIndent.h" 00023 #include <vector> 00024 #include "itkArray.h" 00025 00026 namespace itk 00027 { 00074 class ITK_EXPORT MultivariateLegendrePolynomial 00075 { 00076 public: 00077 typedef MultivariateLegendrePolynomial Self; 00078 00079 typedef std::vector< double > DoubleArrayType; 00080 typedef std::vector< unsigned long > ULongArrayType; 00081 typedef std::vector< long > LongArrayType; 00082 00084 typedef DoubleArrayType CoefficientArrayType; 00085 00088 typedef Array< double > ParametersType; 00089 00091 typedef ULongArrayType DomainSizeType; 00092 typedef LongArrayType IndexType; 00093 00095 MultivariateLegendrePolynomial(unsigned int dimension, 00096 unsigned int degree, 00097 const DomainSizeType & domainSize); 00098 00100 virtual ~MultivariateLegendrePolynomial(); 00101 00103 unsigned int GetDimension(void) const 00104 { return m_Dimension; } 00105 00107 unsigned int GetDegree(void) const 00108 { return m_Degree; } 00109 00116 unsigned int GetNumberOfCoefficients(void) const 00117 { return m_NumberOfCoefficients; } 00118 00120 const DomainSizeType & GetDomainSize(void) const 00121 { return m_DomainSize; } 00122 00127 class CoefficientVectorSizeMismatch 00128 { 00129 public: 00130 CoefficientVectorSizeMismatch(int given, int required) 00131 { 00132 m_Required = required; 00133 m_Given = given; 00134 } 00135 00136 int m_Required; 00137 int m_Given; 00138 }; 00139 00144 void SetCoefficients(const CoefficientArrayType & coef) 00145 throw ( CoefficientVectorSizeMismatch ); 00146 00147 void SetCoefficients(const ParametersType & coef) 00148 throw ( CoefficientVectorSizeMismatch ); 00149 00151 const CoefficientArrayType & GetCoefficients(void) const; 00152 00155 double Evaluate(IndexType & index) 00156 { 00157 if ( m_Dimension == 2 ) 00158 { 00159 if ( index[1] != m_PrevY ) 00160 { 00161 // normalized y [-1, 1] 00162 double norm_y = m_NormFactor[1] 00163 * static_cast< double >( index[1] - 1 ); 00164 this->CalculateXCoef(norm_y, m_CoefficientArray); 00165 m_PrevY = index[1]; 00166 } 00168 00169 // normalized x [-1, 1] 00170 double norm_x = m_NormFactor[0] 00171 * static_cast< double >( index[0] - 1 ); 00172 00173 return LegendreSum(norm_x, m_Degree, m_CachedXCoef); 00174 } 00175 else if ( m_Dimension == 3 ) 00176 { 00177 if ( index[2] != m_PrevZ ) 00178 { 00179 // normalized z [-1, 1] 00180 double norm_z = m_NormFactor[2] 00181 * static_cast< double >( index[2] - 1 ); 00182 this->CalculateYCoef(norm_z, m_CoefficientArray); 00183 m_PrevZ = index[2]; 00184 } 00185 00186 if ( index[1] != m_PrevY ) 00187 { 00188 // normalized y [-1, 1] 00189 double norm_y = m_NormFactor[1] 00190 * static_cast< double >( index[1] - 1 ); 00191 this->CalculateXCoef(norm_y, m_CachedYCoef); 00192 m_PrevY = index[1]; 00193 } 00194 00195 // normalized x [-1, 1] 00196 double norm_x = m_NormFactor[0] 00197 * static_cast< double >( index[0] - 1 ); 00198 return this->LegendreSum(norm_x, m_Degree, m_CachedXCoef); 00199 } 00200 return 0; 00201 } 00202 00204 unsigned int GetNumberOfCoefficients(); 00205 00207 unsigned int GetNumberOfCoefficients(unsigned int dimension, unsigned int degree); 00208 00215 class SimpleForwardIterator 00216 { 00217 public: 00218 SimpleForwardIterator (MultivariateLegendrePolynomial *polynomial) 00219 { 00220 m_MultivariateLegendrePolynomial = polynomial; 00221 m_Dimension = m_MultivariateLegendrePolynomial->GetDimension(); 00222 m_DomainSize = m_MultivariateLegendrePolynomial->GetDomainSize(); 00223 m_Index.resize(m_Dimension); 00224 std::fill(m_Index.begin(), m_Index.end(), 0); 00225 } 00226 00227 void Begin(void) 00228 { 00229 m_IsAtEnd = false; 00230 for ( unsigned int dim = 0; dim < m_Dimension; dim++ ) 00231 { 00232 m_Index[dim] = 0; 00233 } 00234 } 00235 00236 bool IsAtEnd() 00237 { return m_IsAtEnd; } 00238 00239 SimpleForwardIterator & operator++() 00240 { 00241 for ( unsigned int dim = 0; dim < m_Dimension; dim++ ) 00242 { 00243 if ( m_Index[dim] < static_cast< int >( m_DomainSize[dim] - 1 ) ) 00244 { 00245 m_Index[dim] += 1; 00246 return *this; 00247 } 00248 else 00249 { 00250 if ( dim == m_Dimension - 1 ) 00251 { 00252 m_IsAtEnd = true; 00253 break; 00254 } 00255 else 00256 { 00257 m_Index[dim] = 0; 00258 } 00259 } 00260 } 00261 return *this; 00262 } 00263 00264 double Get() 00265 { return m_MultivariateLegendrePolynomial->Evaluate(m_Index); } 00266 private: 00267 MultivariateLegendrePolynomial *m_MultivariateLegendrePolynomial; 00268 unsigned int m_Dimension; 00269 DomainSizeType m_DomainSize; 00270 IndexType m_Index; 00271 bool m_IsAtEnd; 00272 }; // end of class Iterator 00273 00274 void Print(std::ostream & os); 00275 00276 protected: 00277 void PrintSelf(std::ostream & os, Indent indent) const; 00278 00279 double LegendreSum(const double x, int n, 00280 const CoefficientArrayType & coef, 00281 int offset = 0); 00282 00283 void CalculateXCoef(double norm_y, const CoefficientArrayType & coef); 00284 00285 void CalculateYCoef(double norm_z, const CoefficientArrayType & coef); 00286 00287 private: 00288 DomainSizeType m_DomainSize; 00289 unsigned int m_Dimension; 00290 unsigned int m_Degree; 00291 unsigned int m_NumberOfCoefficients; 00292 bool m_MultiplicativeBias; 00293 00294 CoefficientArrayType m_CoefficientArray; 00295 CoefficientArrayType m_CachedXCoef; 00296 CoefficientArrayType m_CachedYCoef; 00297 CoefficientArrayType m_CachedZCoef; 00298 00299 DoubleArrayType m_NormFactor; 00300 IndexValueType m_PrevY; 00301 IndexValueType m_PrevZ; 00302 }; // end of class 00303 00304 ITK_EXPORT std::ostream & operator<<(std::ostream & os, 00305 MultivariateLegendrePolynomial & poly); 00306 } // end of namespace itk 00307 #endif 00308