-
Notifications
You must be signed in to change notification settings - Fork 0
/
derivativeLegendre.m
144 lines (109 loc) · 4.68 KB
/
derivativeLegendre.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
136
137
138
139
140
141
142
143
144
% Derivative of the associated Legendre functions
%
% p = derivativeLegendre(degree,x) instantiates an object to compute
% derivatives of the associated Legendre functions.
%
% p.setup(x) computes and stores the values of the derivative of the
% associated Legendre function at the points x.
%
% P = p.get(n) for n<=degree returns the values P of the derivative 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 derivative 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.
%
% Note: this code uses derivative_legendre.m downloaded from [1].
%
% See also: associatedLegendre, derivative_legendre.
%
% References:
%
% [1] https://www.mathworks.com/matlabcentral/fileexchange/46930-first-derivative-of-normal-associated-legendre-polynomials
%
% 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 derivativeLegendre < handle
properties
degree
data
end
methods
%-----------------------------------------
% constructor
%-----------------------------------------
function self = derivativeLegendre(degree,x)
self.degree = degree;
self.data = [];
self.setup(x);
end
%-----------------------------------------
% setup
%-----------------------------------------
% This computes the derivative of 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
if n>0
schmidt = squeeze(legendre_derivative(n,x,'sch')).';
else
schmidt = zeros(2*n+1,length(x));
end
% 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('get takes two or three parameters')
end
end
end
end