ITK  6.0.0
Insight Toolkit
itkMultivariateLegendrePolynomial.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright NumFOCUS
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 * https://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
27namespace itk
28{
77class ITKPolynomials_EXPORT MultivariateLegendrePolynomial
78{
79public:
81
82 using DoubleArrayType = std::vector<double>;
83 using ULongArrayType = std::vector<unsigned long>;
84 using LongArrayType = std::vector<long>;
85
88
92
96
98 MultivariateLegendrePolynomial(unsigned int dimension, unsigned int degree, const DomainSizeType & domainSize);
99
102
104 unsigned int
106 {
107 return m_Dimension;
108 }
109
111 unsigned int
112 GetDegree() const
113 {
114 return m_Degree;
115 }
116
123 unsigned int
125 {
126 return m_NumberOfCoefficients;
127 }
128
130 const DomainSizeType &
132 {
133 return m_DomainSize;
134 }
135
142 {
143 public:
144 CoefficientVectorSizeMismatch(const size_t given, const size_t required)
145 : m_Required{ required }
146 , m_Given{ given }
147 {}
148
150 size_t m_Given;
151 };
152
157 void
159
160 void
161 SetCoefficients(const ParametersType & coefficients);
162
166
169 double
171 {
172 if (m_Dimension == 2)
173 {
174 if (index[1] != m_PrevY)
175 {
176 // normalized y [-1, 1]
177 double norm_y = m_NormFactor[1] * static_cast<double>(index[1] - 1);
178 this->CalculateXCoef(norm_y, m_CoefficientArray);
179 m_PrevY = index[1];
180 }
183 // normalized x [-1, 1]
184 double norm_x = m_NormFactor[0] * static_cast<double>(index[0] - 1);
185
186 return LegendreSum(norm_x, m_Degree, m_CachedXCoef);
187 }
188 else if (m_Dimension == 3)
189 {
190 if (index[2] != m_PrevZ)
191 {
192 // normalized z [-1, 1]
193 double norm_z = m_NormFactor[2] * static_cast<double>(index[2] - 1);
194 this->CalculateYCoef(norm_z, m_CoefficientArray);
195 m_PrevZ = index[2];
196 }
197
198 if (index[1] != m_PrevY)
199 {
200 // normalized y [-1, 1]
201 double norm_y = m_NormFactor[1] * static_cast<double>(index[1] - 1);
202 this->CalculateXCoef(norm_y, m_CachedYCoef);
203 m_PrevY = index[1];
204 }
205
206 // normalized x [-1, 1]
207 double norm_x = m_NormFactor[0] * static_cast<double>(index[0] - 1);
208 return this->LegendreSum(norm_x, m_Degree, m_CachedXCoef);
209 }
210 return 0;
211 }
212
214 unsigned int
215 GetNumberOfCoefficients(unsigned int dimension, unsigned int degree);
216
225 {
226 public:
228 : m_MultivariateLegendrePolynomial(polynomial)
229 , m_Dimension(m_MultivariateLegendrePolynomial->GetDimension())
230 , m_DomainSize(m_MultivariateLegendrePolynomial->GetDomainSize())
231 , m_IsAtEnd(false)
232 {
233 m_Index.resize(m_Dimension);
234 std::fill(m_Index.begin(), m_Index.end(), 0);
235 }
238 void
240 {
241 m_IsAtEnd = false;
242 for (unsigned int dim = 0; dim < m_Dimension; ++dim)
243 {
244 m_Index[dim] = 0;
245 }
246 }
247
248 bool
249 IsAtEnd() const
250 {
251 return m_IsAtEnd;
252 }
253
256 {
257 for (unsigned int dim = 0; dim < m_Dimension; ++dim)
258 {
259 if (m_Index[dim] < static_cast<int>(m_DomainSize[dim] - 1))
260 {
261 m_Index[dim] += 1;
262 return *this;
263 }
264 else
265 {
266 if (dim == m_Dimension - 1)
267 {
268 m_IsAtEnd = true;
269 break;
270 }
271 else
272 {
273 m_Index[dim] = 0;
274 }
275 }
276 }
277 return *this;
278 }
279
280 double
282 {
283 return m_MultivariateLegendrePolynomial->Evaluate(m_Index);
284 }
285
286 private:
288 unsigned int m_Dimension;
292 }; // end of class Iterator
293
294 void
295 Print(std::ostream & os) const;
296
297protected:
298 void
299 PrintSelf(std::ostream & os, Indent indent) const;
300
301 double
302 LegendreSum(const double x, int n, const CoefficientArrayType & coef, int offset = 0);
303
304 void
305 CalculateXCoef(double norm_y, const CoefficientArrayType & coef);
306
307 void
308 CalculateYCoef(double norm_z, const CoefficientArrayType & coef);
309
310private:
311 DomainSizeType m_DomainSize{};
312 unsigned int m_Dimension{};
313 unsigned int m_Degree{};
314 unsigned int m_NumberOfCoefficients{};
315
316 CoefficientArrayType m_CoefficientArray{};
317 CoefficientArrayType m_CachedXCoef{};
318 CoefficientArrayType m_CachedYCoef{};
319 CoefficientArrayType m_CachedZCoef{};
320
321 DoubleArrayType m_NormFactor{};
322 IndexValueType m_PrevY{};
323 IndexValueType m_PrevZ{};
324}; // end of class
325
326ITKPolynomials_EXPORT std::ostream &
327 operator<<(std::ostream & os, const MultivariateLegendrePolynomial & poly);
328} // end of namespace itk
329#endif
Control indentation during Print() invocation.
Definition: itkIndent.h:50
CoefficientVectorSizeMismatch(const vcl_size_t given, const vcl_size_t required)
Iterator which only supports forward iteration and Begin(), IsAtEnd(), and Get() method which work ju...
2D and 3D multivariate Legendre Polynomial
void Print(std::ostream &os) const
void SetCoefficients(const ParametersType &coefficients)
const CoefficientArrayType & GetCoefficients() const
Gets Legendre polynomials' coefficients.
void CalculateXCoef(double norm_y, const CoefficientArrayType &coef)
void PrintSelf(std::ostream &os, Indent indent) const
unsigned int GetNumberOfCoefficients(unsigned int dimension, unsigned int degree)
void CalculateYCoef(double norm_z, const CoefficientArrayType &coef)
void SetCoefficients(const CoefficientArrayType &coefficients)
Sets the Legendre polynomials' parameters.
MultivariateLegendrePolynomial(unsigned int dimension, unsigned int degree, const DomainSizeType &domainSize)
double LegendreSum(const double x, int n, const CoefficientArrayType &coef, int offset=0)
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
ITKCommon_EXPORT std::ostream & operator<<(std::ostream &out, typename AnatomicalOrientation::CoordinateEnum value)
long IndexValueType
Definition: itkIntTypes.h:93