Memoized version of Legendre computation called DynamicLegendre

This commit is contained in:
Paolo Cignoni 2009-10-14 16:09:30 +00:00
parent 01f772d7f8
commit 8d8ed1efa8
1 changed files with 73 additions and 1 deletions

View File

@ -37,7 +37,7 @@ namespace math {
template <typename ScalarType>
class Legendre {
private :
protected :
/**
* Legendre Polynomial three term Recurrence Relation
@ -164,6 +164,78 @@ public :
}
};
template <typename ScalarType, int MAX_L>
class DynamicLegendre : public Legendre<ScalarType>
{
private:
ScalarType matrix[MAX_L][MAX_L]; //dynamic table
ScalarType _x; //table is conserved only across consistent x invocations
ScalarType _sin_theta;
void generate(ScalarType cos_theta, ScalarType sin_theta)
{
//generate all 'l's with m = 0
matrix[0][0] = 1;
matrix[0][1] = cos_theta;
for (unsigned l = 2; l < MAX_L; ++l)
{
matrix[0][l] = legendre_next(l-1, matrix[0][l-1], matrix[0][l-2], cos_theta);
}
for(unsigned l = 1; l < MAX_L; ++l)
{
for (unsigned m = 1; m <= l; ++m)
{
if (l == m) matrix[m][m] = legendre_P_m_m(m, sin_theta);
else if (l == m + 1) matrix[m][l] = legendre_P_m_mplusone(m, matrix[m][m], cos_theta);
else{
matrix[m][l] = legendre_next(l-1, m, matrix[m][l-1], matrix[m][l-2], cos_theta);
}
}
}
_x = cos_theta;
}
public :
DynamicLegendre() : _x(2), _sin_theta(2) {}
double AssociatedPolynomial(unsigned l, unsigned m, ScalarType x)
{
assert (m <= l && x <= 1 && x >= -1);
if (x != _x){
_sin_theta = Sqrt(1.0 - x * x);
generate(x, _sin_theta);
}
return matrix[m][l];
}
double AssociatedPolynomial(unsigned l, unsigned m, ScalarType cos_theta, ScalarType sin_theta)
{
assert (m <= l && cos_theta <= 1 && cos_theta >= -1 && sin_theta <= 1 && sin_theta >= -1);
if (cos_theta != _x){
_sin_theta = sin_theta;
generate(cos_theta, _sin_theta);
}
return matrix[m][l];
}
double Polynomial(unsigned l, ScalarType x)
{
assert (x <= 1 && x >= -1);
if (x != _x){
_sin_theta = Sqrt(1.0 - x * x);
generate(x, _sin_theta);
}
return matrix[0][l];
}
};
}} //vcg::math namespace
#endif