/usr/include/InsightToolkit/Numerics/itkMultivariateLegendrePolynomial.h is in libinsighttoolkit3-dev 3.20.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 | /*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: itkMultivariateLegendrePolynomial.h
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef __itkMultivariateLegendrePolynomial_h
#define __itkMultivariateLegendrePolynomial_h
#include "itkIndent.h"
#include <vector>
#include "itkArray.h"
namespace itk {
/** \class MultivariateLegendrePolynomial
* \brief 2D and 3D multivariate Legendre Polynomial
*
* In 2D,
* \f[
* f(x_{vector}, parameter_{vector}) =
* \sum_i^l \left(
* \sum_j^{l-i} \left( parameter_ {ij} * P_i(x) *P_j(y)) \right) \right)
* \f]
* where P_i() denoting a Legendre polynomial of degree i
* and l it the degree of the polynomial
*
* In 3D,
* \f[
* f(x_{vector}, parameter_{vector}) =
* \sum_i^l \left( \sum_j^{l-i} \left( \sum_k^{l-i-j} \left(
* parameter_{ijk} * P_i(x) * P_j(y) * P_k(z) \right) \right) \right)
* \f]
*
* The size of the parameter vector for 2D is
* \f$\frac{(l+1)\cdot(1+2)}{2}\f$,
* and for 3D is \f$\frac{(l+1)*(l+2)*(l+3){3!}\f$
*
* To get the size of the parameter vector, users can use one of the
* two GetNumberOfCoefficients() member functions
*
* To get function result, users can use the operator() or its
* SimpleForwardIterator's Get() method.
*
* This is a part of the bias correction methods and implemenations
* that was initially developed and implemented
* by Martin Styner, Univ. of North Carolina at Chapel Hill, and his
* colleagues.
*
* \note For more details. refer to the following articles.
* "Parametric estimate of intensity inhomogeneities applied to MRI"
* Martin Styner, G. Gerig, Christian Brechbuehler, Gabor Szekely,
* IEEE TRANSACTIONS ON MEDICAL IMAGING; 19(3), pp. 153-165, 2000,
* (http://www.ia.unc.edu/~styner/docs/tmi00.pdf)
*
* "Evaluation of 2D/3D bias correction with 1+1ES-optimization"
* Martin Styner, Prof. Dr. G. Gerig (IKT, BIWI, ETH Zuerich), TR-197
* (http://www.ia.unc.edu/~styner/docs/StynerTR97.pdf)
*/
class ITK_EXPORT MultivariateLegendrePolynomial
{
public:
typedef MultivariateLegendrePolynomial Self;
typedef std::vector< double > DoubleArrayType;
typedef std::vector< unsigned long > ULongArrayType;
typedef std::vector< long > LongArrayType;
/** Internal coefficient storage type. */
typedef DoubleArrayType CoefficientArrayType;
/** Same as CoefficientArray
* This type definition will be used by EnergyFunction object. */
typedef Array< double > ParametersType;
/** The size of the domain. */
typedef ULongArrayType DomainSizeType;
typedef LongArrayType IndexType;
/** Constructor. */
MultivariateLegendrePolynomial( unsigned int dimension,
unsigned int degree,
const DomainSizeType & domainSize );
/** Destructor. */
virtual ~MultivariateLegendrePolynomial();
/** Gets the dimension. */
unsigned int GetDimension(void) const
{ return m_Dimension; }
/** Gets the degree (the degree of Legendre polynomials). */
unsigned int GetDegree(void) const
{ return m_Degree; }
/** Returns the number of coefficients of the polynomial
* This number is computed from the degree of the polynomial
* the SetCoefficients() method expects an array of this
* size, an exception is thrown otherwise
* \sa SetCoefficients
*/
unsigned int GetNumberOfCoefficients(void) const
{ return m_NumberOfCoefficients; }
/** Gets each dimesion's size. */
const DomainSizeType & GetDomainSize( void ) const
{ return m_DomainSize; }
/** \class CoefficientVectorSizeMismatch Exception object. */
class CoefficientVectorSizeMismatch
{
public:
CoefficientVectorSizeMismatch(int given, int required)
{
m_Required = required;
m_Given = given;
}
int m_Required;
int m_Given;
};
/** \brief Sets the Legendre polynomials' parameters.
* \warning The number of coefficients provided should
* match the number returned by GetNumberOfCoefficients()
* otherwise an exception is thrown. */
void SetCoefficients(const CoefficientArrayType& coef)
throw (CoefficientVectorSizeMismatch);
void SetCoefficients(const ParametersType& coef)
throw (CoefficientVectorSizeMismatch);
/** \brief Gets Legendre polynomials' coefficients. */
const CoefficientArrayType& GetCoefficients(void) const;
/** In the case which the bias field is 2D, it returns bias value at
* the point which is specified by the index */
double Evaluate(IndexType& index)
{
if (m_Dimension == 2)
{
if (index[1] != m_PrevY)
{
// normalized y [-1, 1]
double norm_y = m_NormFactor[1] *
static_cast<double>( index[1] - 1 );
this->CalculateXCoef(norm_y, m_CoefficientArray);
m_PrevY = index[1];
}
// normalized x [-1, 1]
double norm_x = m_NormFactor[0] *
static_cast<double>( index[0] - 1 );
return LegendreSum(norm_x, m_Degree, m_CachedXCoef);
}
else if (m_Dimension == 3)
{
if (index[2] != m_PrevZ )
{
// normalized z [-1, 1]
double norm_z = m_NormFactor[2] *
static_cast<double>( index[2] - 1 );
this->CalculateYCoef(norm_z, m_CoefficientArray);
m_PrevZ = index[2];
}
if (index[1] != m_PrevY)
{
// normalized y [-1, 1]
double norm_y = m_NormFactor[1] *
static_cast<double>( index[1] - 1 );
this->CalculateXCoef(norm_y, m_CachedYCoef);
m_PrevY = index[1];
}
// normalized x [-1, 1]
double norm_x = m_NormFactor[0] *
static_cast<double>( index[0] - 1 );
return this->LegendreSum(norm_x, m_Degree, m_CachedXCoef);
}
return 0;
}
/** Gets the number of coefficients. */
unsigned int GetNumberOfCoefficients();
/** Gets the number of coefficients. */
unsigned int GetNumberOfCoefficients(unsigned int dimension, unsigned int degree);
/** \class SimpleForwardIterator
* \brief Iterator which only supports forward iteration and
* Begin(), IsAtEnd(), and Get() method which work just like as
* SimpleImageRegionIterator.
*/
class SimpleForwardIterator
{
public:
SimpleForwardIterator (MultivariateLegendrePolynomial* polynomial)
{
m_MultivariateLegendrePolynomial = polynomial;
m_Dimension = m_MultivariateLegendrePolynomial->GetDimension();
m_DomainSize = m_MultivariateLegendrePolynomial->GetDomainSize();
m_Index.resize(m_Dimension);
std::fill(m_Index.begin(), m_Index.end(), 0);
}
void Begin( void )
{
m_IsAtEnd = false;
for (unsigned int dim = 0; dim < m_Dimension; dim++)
{
m_Index[dim] = 0;
}
}
bool IsAtEnd()
{ return m_IsAtEnd; }
SimpleForwardIterator& operator++()
{
for (unsigned int dim = 0; dim < m_Dimension; dim++)
{
if (m_Index[dim] < static_cast<int>(m_DomainSize[dim] - 1))
{
m_Index[dim] += 1;
return *this;
}
else
{
if (dim == m_Dimension - 1 )
{
m_IsAtEnd = true;
break;
}
else
{
m_Index[dim] = 0;
}
}
}
return *this;
}
double Get()
{ return m_MultivariateLegendrePolynomial->Evaluate(m_Index); }
private:
MultivariateLegendrePolynomial* m_MultivariateLegendrePolynomial;
unsigned int m_Dimension;
DomainSizeType m_DomainSize;
IndexType m_Index;
bool m_IsAtEnd;
}; // end of class Iterator
void Print(std::ostream& os);
protected:
void PrintSelf(std::ostream& os, Indent indent) const;
double LegendreSum(const double x, int n,
const CoefficientArrayType& coef,
int offset = 0);
void CalculateXCoef(double norm_y, const CoefficientArrayType& coef);
void CalculateYCoef(double norm_z, const CoefficientArrayType& coef);
private:
DomainSizeType m_DomainSize;
unsigned int m_Dimension;
unsigned int m_Degree;
unsigned int m_NumberOfCoefficients;
bool m_MultiplicativeBias;
CoefficientArrayType m_CoefficientArray;
CoefficientArrayType m_CachedXCoef;
CoefficientArrayType m_CachedYCoef;
CoefficientArrayType m_CachedZCoef;
DoubleArrayType m_NormFactor;
long m_PrevY;
long m_PrevZ;
}; // end of class
std::ostream& operator<< (std::ostream& os,
MultivariateLegendrePolynomial& poly);
} // end of namespace itk
#endif
|