ITK  4.8.0
Insight Segmentation and Registration Toolkit
itkMultivariateLegendrePolynomial.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkMultivariateLegendrePolynomial_h
19 #define itkMultivariateLegendrePolynomial_h
20 
21 #include "itkIntTypes.h"
22 #include "itkIndent.h"
23 #include <vector>
24 #include "itkArray.h"
25 #include "ITKPolynomialsExport.h"
26 
27 namespace itk
28 {
75 class ITKPolynomials_EXPORT MultivariateLegendrePolynomial
76 {
77 public:
79 
80  typedef std::vector< double > DoubleArrayType;
81  typedef std::vector< unsigned long > ULongArrayType;
82  typedef std::vector< long > LongArrayType;
83 
86 
90 
94 
96  MultivariateLegendrePolynomial(unsigned int dimension,
97  unsigned int degree,
98  const DomainSizeType & domainSize);
99 
102 
104  unsigned int GetDimension(void) const
105  { return m_Dimension; }
106 
108  unsigned int GetDegree(void) const
109  { return m_Degree; }
110 
117  unsigned int GetNumberOfCoefficients(void) const
118  { return m_NumberOfCoefficients; }
119 
121  const DomainSizeType & GetDomainSize(void) const
122  { return m_DomainSize; }
123 
129  {
130 public:
131  CoefficientVectorSizeMismatch(int given, int required)
132  {
133  m_Required = required;
134  m_Given = given;
135  }
136 
138  int m_Given;
139  };
140 
145  void SetCoefficients(const CoefficientArrayType & coef)
147 
148  void SetCoefficients(const ParametersType & coef)
150 
152  const CoefficientArrayType & GetCoefficients() const;
153 
156  double Evaluate(IndexType & index)
157  {
158  if ( m_Dimension == 2 )
159  {
160  if ( index[1] != m_PrevY )
161  {
162  // normalized y [-1, 1]
163  double norm_y = m_NormFactor[1]
164  * static_cast< double >( index[1] - 1 );
165  this->CalculateXCoef(norm_y, m_CoefficientArray);
166  m_PrevY = index[1];
167  }
169 
170  // normalized x [-1, 1]
171  double norm_x = m_NormFactor[0]
172  * static_cast< double >( index[0] - 1 );
173 
174  return LegendreSum(norm_x, m_Degree, m_CachedXCoef);
175  }
176  else if ( m_Dimension == 3 )
177  {
178  if ( index[2] != m_PrevZ )
179  {
180  // normalized z [-1, 1]
181  double norm_z = m_NormFactor[2]
182  * static_cast< double >( index[2] - 1 );
183  this->CalculateYCoef(norm_z, m_CoefficientArray);
184  m_PrevZ = index[2];
185  }
186 
187  if ( index[1] != m_PrevY )
188  {
189  // normalized y [-1, 1]
190  double norm_y = m_NormFactor[1]
191  * static_cast< double >( index[1] - 1 );
192  this->CalculateXCoef(norm_y, m_CachedYCoef);
193  m_PrevY = index[1];
194  }
195 
196  // normalized x [-1, 1]
197  double norm_x = m_NormFactor[0]
198  * static_cast< double >( index[0] - 1 );
199  return this->LegendreSum(norm_x, m_Degree, m_CachedXCoef);
200  }
201  return 0;
202  }
203 
205  unsigned int GetNumberOfCoefficients();
206 
208  unsigned int GetNumberOfCoefficients(unsigned int dimension, unsigned int degree);
209 
217  {
218 public:
220  m_MultivariateLegendrePolynomial(polynomial),
221  m_Dimension (m_MultivariateLegendrePolynomial->GetDimension()),
222  m_DomainSize (m_MultivariateLegendrePolynomial->GetDomainSize()),
223  m_IsAtEnd(false)
224  {
225  m_Index.resize(m_Dimension);
226  std::fill(m_Index.begin(), m_Index.end(), 0);
227  }
228 
229  void Begin(void)
230  {
231  m_IsAtEnd = false;
232  for ( unsigned int dim = 0; dim < m_Dimension; dim++ )
233  {
234  m_Index[dim] = 0;
235  }
236  }
237 
238  bool IsAtEnd()
239  { return m_IsAtEnd; }
240 
242  {
243  for ( unsigned int dim = 0; dim < m_Dimension; dim++ )
244  {
245  if ( m_Index[dim] < static_cast< int >( m_DomainSize[dim] - 1 ) )
246  {
247  m_Index[dim] += 1;
248  return *this;
249  }
250  else
251  {
252  if ( dim == m_Dimension - 1 )
253  {
254  m_IsAtEnd = true;
255  break;
256  }
257  else
258  {
259  m_Index[dim] = 0;
260  }
261  }
262  }
263  return *this;
264  }
265 
266  double Get()
267  { return m_MultivariateLegendrePolynomial->Evaluate(m_Index); }
268 
269 private:
271  unsigned int m_Dimension;
274  bool m_IsAtEnd;
275  }; // end of class Iterator
276 
277  void Print(std::ostream & os);
278 
279 protected:
280  void PrintSelf(std::ostream & os, Indent indent) const;
281 
282  double LegendreSum(const double x, int n,
283  const CoefficientArrayType & coef,
284  int offset = 0);
285 
286  void CalculateXCoef(double norm_y, const CoefficientArrayType & coef);
287 
288  void CalculateYCoef(double norm_z, const CoefficientArrayType & coef);
289 
290 private:
292  unsigned int m_Dimension;
293  unsigned int m_Degree;
295 
300 
304 }; // end of class
305 
306  ITKPolynomials_EXPORT std::ostream & operator<<(std::ostream & os,
308 } // end of namespace itk
309 #endif
signed long IndexValueType
Definition: itkIntTypes.h:150
std::ostream & operator<<(std::ostream &os, const Array< TValue > &arr)
Definition: itkArray.h:184
const DomainSizeType & GetDomainSize(void) const
2D and 3D multivariate Legendre Polynomial
Control indentation during Print() invocation.
Definition: itkIndent.h:49
Iterator which only supports forward iteration and Begin(), IsAtEnd(), and Get() method which work ju...