ITK  4.4.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 
26 namespace itk
27 {
75 {
76 public:
78 
79  typedef std::vector< double > DoubleArrayType;
80  typedef std::vector< unsigned long > ULongArrayType;
81  typedef std::vector< long > LongArrayType;
82 
85 
89 
93 
95  MultivariateLegendrePolynomial(unsigned int dimension,
96  unsigned int degree,
97  const DomainSizeType & domainSize);
98 
101 
103  unsigned int GetDimension(void) const
104  { return m_Dimension; }
105 
107  unsigned int GetDegree(void) const
108  { return m_Degree; }
109 
116  unsigned int GetNumberOfCoefficients(void) const
117  { return m_NumberOfCoefficients; }
118 
120  const DomainSizeType & GetDomainSize(void) const
121  { return m_DomainSize; }
122 
128  {
129 public:
130  CoefficientVectorSizeMismatch(int given, int required)
131  {
132  m_Required = required;
133  m_Given = given;
134  }
135 
137  int m_Given;
138  };
139 
144  void SetCoefficients(const CoefficientArrayType & coef)
146 
147  void SetCoefficients(const ParametersType & coef)
149 
151  const CoefficientArrayType & GetCoefficients(void) const;
152 
155  double Evaluate(IndexType & index)
156  {
157  if ( m_Dimension == 2 )
158  {
159  if ( index[1] != m_PrevY )
160  {
161  // normalized y [-1, 1]
162  double norm_y = m_NormFactor[1]
163  * static_cast< double >( index[1] - 1 );
164  this->CalculateXCoef(norm_y, m_CoefficientArray);
165  m_PrevY = index[1];
166  }
168 
169  // normalized x [-1, 1]
170  double norm_x = m_NormFactor[0]
171  * static_cast< double >( index[0] - 1 );
172 
173  return LegendreSum(norm_x, m_Degree, m_CachedXCoef);
174  }
175  else if ( m_Dimension == 3 )
176  {
177  if ( index[2] != m_PrevZ )
178  {
179  // normalized z [-1, 1]
180  double norm_z = m_NormFactor[2]
181  * static_cast< double >( index[2] - 1 );
182  this->CalculateYCoef(norm_z, m_CoefficientArray);
183  m_PrevZ = index[2];
184  }
185 
186  if ( index[1] != m_PrevY )
187  {
188  // normalized y [-1, 1]
189  double norm_y = m_NormFactor[1]
190  * static_cast< double >( index[1] - 1 );
191  this->CalculateXCoef(norm_y, m_CachedYCoef);
192  m_PrevY = index[1];
193  }
194 
195  // normalized x [-1, 1]
196  double norm_x = m_NormFactor[0]
197  * static_cast< double >( index[0] - 1 );
198  return this->LegendreSum(norm_x, m_Degree, m_CachedXCoef);
199  }
200  return 0;
201  }
202 
204  unsigned int GetNumberOfCoefficients();
205 
207  unsigned int GetNumberOfCoefficients(unsigned int dimension, unsigned int degree);
208 
216  {
217 public:
219  {
220  m_MultivariateLegendrePolynomial = polynomial;
221  m_Dimension = m_MultivariateLegendrePolynomial->GetDimension();
222  m_DomainSize = m_MultivariateLegendrePolynomial->GetDomainSize();
223  m_Index.resize(m_Dimension);
224  std::fill(m_Index.begin(), m_Index.end(), 0);
225  }
226 
227  void Begin(void)
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()
237  { return m_IsAtEnd; }
238 
239  SimpleForwardIterator & operator++()
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 ITK_EXPORT std::ostream & operator<<(std::ostream & os,
306 } // end of namespace itk
307 #endif
308