-
Notifications
You must be signed in to change notification settings - Fork 0
/
associatedLegendre.m
135 lines (100 loc) · 4.29 KB
/
associatedLegendre.m
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
% Associated Legendre functions
%
% p = associatedLegendre(degree,x) instantiates an object to compute
% associated Legendre functions.
%
% p.setup(x) computes and stores the values of the associated Legendre
% function at the points x.
%
% P = p.get(n) for n<=degree returns the values P of the associated
% Legendre functions of degree n in a length(x) x (2*n+1) matrix.
% P(:,m+n+1) holds the values of the polynomial of order m.
%
% P = p.get(n,m) returns the values of the associated Legendre function of
% degree n and order m at the points x.
%
% Note: the polynomials are normalised as in Equation (3.2) in
% Ganesh and Hawkins, Numerical Algorithms (2006) 43:25-60.
%
% See also: derivativeLegendre.
%
% Stuart C. Hawkins - 20 April 2021
% Copyright 2019-2022 Stuart C. Hawkins
%
% This file is part of TMATROM3
%
% TMATROM3 is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% TMATROM3 is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with TMATROM3. If not, see <http://www.gnu.org/licenses/>.
classdef associatedLegendre < handle
properties
degree
data
end
methods
%-----------------------------------------
% constructor
%-----------------------------------------
function self = associatedLegendre(degree,x)
self.degree = degree;
self.data = [];
% call setup method to compute the Legendre function values
self.setup(x);
end
%-----------------------------------------
% setup
%-----------------------------------------
% This computes the associated Legendre function values at the
% points x and stores them for later use.
function setup(self,x)
for n = 0:self.degree
% get Schmidt seminormalised polynomial values
schmidt = legendre(n,x,'sch').';
% setup sparse matrix to implement normalisation as per (3.2) in
% Ganesh and Hawkins, Numerical Algorithms (2006) 43:25-60
if n==0
lambda = sqrt(1/(4*pi));
else
% negative m scaling
scalem = sqrt((2*n+1)/(8*pi)) * ones(n,1);
% positive m scaling
scalep = sqrt((2*n+1)/(8*pi)) * [sqrt(2);ones(n,1)];
% polynomial for m and -m both come from the m column
% in Schmidt... lamda is of the form [M,P] where M does
% scaling for -m and P does scaling for m.
lambda = [fliplr(spdiags(scalem,-1,n+1,n)), ...
spdiags((-1).^(0:n).'.*scalep,0,n+1,n+1)];
end
% post multiply by lambda to implement normalisation
self.data{n+1} = schmidt * lambda;
end
end
%-----------------------------------------
% get
%-----------------------------------------
function val = get(self,varargin)
if nargin==2
% n = varargin{1}
val = self.data{varargin{1}+1};
elseif nargin == 3
% n = varargin{1}
% m = varargin{2}
tmp = self.data{varargin{1}+1};
% Note: the (n,m) entry is in the (n+m+1)th column of
% tmp
val = tmp(:,varargin{1}+1+varargin{2});
else
error('self.get() method takes two or three parameters')
end
end
end
end