ITK  5.0.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  using DoubleArrayType = std::vector< double >;
81  using ULongArrayType = std::vector< unsigned long >;
82  using LongArrayType = std::vector< long >;
83 
86 
90 
94 
96  MultivariateLegendrePolynomial(unsigned int dimension,
97  unsigned int degree,
98  const DomainSizeType & domainSize);
99 
102 
104  unsigned int GetDimension() const
105  { return m_Dimension; }
106 
108  unsigned int GetDegree() const
109  { return m_Degree; }
110 
117  unsigned int GetNumberOfCoefficients() const
118  { return m_NumberOfCoefficients; }
119 
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);
146 
147  void SetCoefficients(const ParametersType & coef);
148 
150  const CoefficientArrayType & GetCoefficients() const;
151 
154  double Evaluate(IndexType & index)
155  {
156  if ( m_Dimension == 2 )
157  {
158  if ( index[1] != m_PrevY )
159  {
160  // normalized y [-1, 1]
161  double norm_y = m_NormFactor[1]
162  * static_cast< double >( index[1] - 1 );
163  this->CalculateXCoef(norm_y, m_CoefficientArray);
164  m_PrevY = index[1];
165  }
167 
168  // normalized x [-1, 1]
169  double norm_x = m_NormFactor[0]
170  * static_cast< double >( index[0] - 1 );
171 
172  return LegendreSum(norm_x, m_Degree, m_CachedXCoef);
173  }
174  else if ( m_Dimension == 3 )
175  {
176  if ( index[2] != m_PrevZ )
177  {
178  // normalized z [-1, 1]
179  double norm_z = m_NormFactor[2]
180  * static_cast< double >( index[2] - 1 );
181  this->CalculateYCoef(norm_z, m_CoefficientArray);
182  m_PrevZ = index[2];
183  }
184 
185  if ( index[1] != m_PrevY )
186  {
187  // normalized y [-1, 1]
188  double norm_y = m_NormFactor[1]
189  * static_cast< double >( index[1] - 1 );
190  this->CalculateXCoef(norm_y, m_CachedYCoef);
191  m_PrevY = index[1];
192  }
193 
194  // normalized x [-1, 1]
195  double norm_x = m_NormFactor[0]
196  * static_cast< double >( index[0] - 1 );
197  return this->LegendreSum(norm_x, m_Degree, m_CachedXCoef);
198  }
199  return 0;
200  }
201 
203  unsigned int GetNumberOfCoefficients();
204 
206  unsigned int GetNumberOfCoefficients(unsigned int dimension, unsigned int degree);
207 
215  {
216 public:
218  m_MultivariateLegendrePolynomial(polynomial),
219  m_Dimension (m_MultivariateLegendrePolynomial->GetDimension()),
220  m_DomainSize (m_MultivariateLegendrePolynomial->GetDomainSize()),
221  m_IsAtEnd(false)
222  {
223  m_Index.resize(m_Dimension);
224  std::fill(m_Index.begin(), m_Index.end(), 0);
225  }
226 
227  void Begin()
228  {
229  m_IsAtEnd = false;
230  for ( unsigned int dim = 0; dim < m_Dimension; dim++ )
231  {
232  m_Index[dim] = 0;
233  }
234  }
235 
236  bool IsAtEnd() const
237  { return m_IsAtEnd; }
238 
240  {
241  for ( unsigned int dim = 0; dim < m_Dimension; dim++ )
242  {
243  if ( m_Index[dim] < static_cast< int >( m_DomainSize[dim] - 1 ) )
244  {
245  m_Index[dim] += 1;
246  return *this;
247  }
248  else
249  {
250  if ( dim == m_Dimension - 1 )
251  {
252  m_IsAtEnd = true;
253  break;
254  }
255  else
256  {
257  m_Index[dim] = 0;
258  }
259  }
260  }
261  return *this;
262  }
263 
264  double Get()
265  { return m_MultivariateLegendrePolynomial->Evaluate(m_Index); }
266 
267 private:
269  unsigned int m_Dimension;
272  bool m_IsAtEnd;
273  }; // end of class Iterator
274 
275  void Print(std::ostream & os);
276 
277 protected:
278  void PrintSelf(std::ostream & os, Indent indent) const;
279 
280  double LegendreSum(const double x, int n,
281  const CoefficientArrayType & coef,
282  int offset = 0);
283 
284  void CalculateXCoef(double norm_y, const CoefficientArrayType & coef);
285 
286  void CalculateYCoef(double norm_z, const CoefficientArrayType & coef);
287 
288 private:
290  unsigned int m_Dimension;
291  unsigned int m_Degree;
293 
298 
302 }; // end of class
303 
304  ITKPolynomials_EXPORT std::ostream & operator<<(std::ostream & os,
306 } // end of namespace itk
307 #endif
std::ostream & operator<<(std::ostream &os, const Array< TValue > &arr)
Definition: itkArray.h:188
signed long IndexValueType
Definition: itkIntTypes.h:90
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...