-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlegendre.h
108 lines (97 loc) · 2.78 KB
/
legendre.h
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
//==================================================================
/**
* legendre.h -- C++ functions to evaluate Legendre polynomials
*
* Copyright (C) 2019 by James A. Chappell
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* condition:
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
//=================================================================
/*
* legendre.h: Version 0.03
* Created by James A. Chappell <[email protected]>
* http://www.storage-b.com/math-numerical-analysis/18
* Created 29 September 2005
*
* History:
* 29-sep-2005 created
* 14-nov-2014 templates
* 01-nov-2019 deduced types
*/
//==============
#ifndef __LEGENDRE_H__
#define __LEGENDRE_H__
/*
* Function calculates Legendre Polynomials Pn(x)
*/
namespace Storage_B
{
namespace Legendre
{
// n = 0
template <class T> inline auto P0(const T& x)
{
return static_cast<T>(1);
}
// n = 1
template <class T> inline auto P1(const T& x)
{
return x;
}
// n = 2
template <class T> inline auto P2(const T& x)
{
return ((static_cast<T>(3) * x*x) - static_cast<T>(1)) /
static_cast<T>(2);
}
/*
* Pn(x)
*/
template <class T> inline auto Pn(unsigned int n, const T& x)
{
switch(n)
{
case 0:
return P0<T>(x);
case 1:
return P1<T>(x);
case 2:
return P2<T>(x);
default:
break;
}
/* We could simply do this:
return (static_cast<T>(((2 * n) - 1)) * x * Pn(n - 1, x) -
(static_cast<T>(n - 1)) * Pn(n - 2, x)) / static_cast<T>(n);
but it could be slow for large n */
auto pnm1(P2<T>(x));
auto pnm2(P1<T>(x));
T pn;
for (auto m = 3u ; m <= n ; ++m)
{
pn = ((static_cast<T>((2 * m) - 1)) * x * pnm1
- (static_cast<T>(m - 1) * pnm2)) / static_cast<T>(m);
pnm2 = pnm1;
pnm1 = pn;
}
return pn;
}
}
}
#endif