1
// Copyright (C) 2003-2008 Anders Logg
3
// This file is part of FFC.
5
// FFC is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU Lesser General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
10
// FFC is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
// GNU Lesser General Public License for more details.
15
// You should have received a copy of the GNU Lesser General Public License
16
// along with FFC. If not, see <http://www.gnu.org/licenses/>.
18
// Modified by Benjamin Kehlet 2011-2012
20
// First added: 2012-08-20
21
// Last changed: 2012-09-05
27
//-----------------------------------------------------------------------------
28
Legendre::Legendre(unsigned int n) : n(n), cache_x(0.0), cache(n + 1)
30
cache[0] = 1.0; //constant value
32
// eval to initialize cache
35
//-----------------------------------------------------------------------------
36
double Legendre::operator() (double x)
40
//-----------------------------------------------------------------------------
41
double Legendre::ddx(double x)
45
//-----------------------------------------------------------------------------
46
double Legendre::d2dx(double x)
50
//-----------------------------------------------------------------------------
51
double Legendre::eval(unsigned int nn, double x)
53
//recursive formula, BETA page 254
54
//return ( (2.0*nn-1.0)*x*eval(nn-1, x) - (nn-1.0)*eval(nn-2, x) ) / nn;
66
for (unsigned int i = 2; i <= n; ++i)
69
cache[i] = ( (2.0*ii-1.0)*x*cache[i-1] - (ii-1.0)*cache[i-2] ) / ii;
76
//-----------------------------------------------------------------------------
77
double Legendre::ddx(unsigned int n, double x)
85
// Avoid division by zero
86
if (std::abs(x - 1.0) < EPSILON)
89
if (std::abs(x + 1.0) < EPSILON)
92
// Formula, BETA page 254
94
return nn * (x*eval(n, x) - eval(n-1, x)) / (x*x - 1.0);
96
//-----------------------------------------------------------------------------
97
double Legendre::d2dx(unsigned int, double x)
103
// Special case n = 1
107
// Avoid division by zero
108
if (std::abs(x - 1.0) < EPSILON)
110
if (std::abs(x + 1.0) < EPSILON)
113
// Formula, BETA page 254
114
const double nn = double(n);
115
return (2.0*x*ddx(n, x) - nn*(nn+1)*eval(n, x)) / (1.0-x*x);
117
//-----------------------------------------------------------------------------