-
Notifications
You must be signed in to change notification settings - Fork 4
/
sdsumk.m
220 lines (198 loc) · 6.65 KB
/
sdsumk.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
function [err,F,G,N,NA,th]=sdsumk(ZTH,ZL,nth,cb,xver)
% [err,F,G,N,NA,th]=SDSUMK(TH,L,nth,cb,xver)
%
% Sums eigenvalue-weighted squared eigenfunctions on the
% DOUBLE-POLAR CAP or the complementary LATITUDINAL BELT.
% Sums Shannon number terms as well as all of the terms.
% Also compares the full unweighted sum to N/A.
%
% INPUT:
%
% TH Cap radius, in degrees (scalar)
% L Bandwidth (scalar)
% nth Number of spatial sampling points
% cb 1 Double-cap, cap eigenvalue weighted
% 2 Latitudinal belt, belt eigenvalue weighted
% 3 Double-cap, (1-cap eigenvalue) weighted
% 4 Latitudinal belt, (1-belt eigenvalue) weighted
% xver 0 No excessive validation & verification (default)
% 1 With excessive validation & verification
%
% OUTPUT:
%
% F The eigenvalue-weighted sum to the Shannon number
% G The eigenvalue-weighted sum over all functions
% N The Shannon number that ends up being used
% th The colatitudes at which F and G are evaluated
%
% Finally, a bit of a professional routine.
% Should replace SDSUMALL, SDSUMALL2
%
% Last modified by fjsimons-at-alum.mit.edu, 16.08.2005
defval('ZTH',3);
defval('ZL', 45);
defval('nth',720);
defval('cb',1);
defval('xver',0);
% Define tolerance
tol=1e-10;
for ondex=1:length(ZTH)
TH=ZTH(ondex);
L=ZL(ondex);
% Calculate the Shannon number for the DOUBLE CAP
Nor=(L+1)^2*(1-cos(TH*pi/180));
switch cb
case {2 4}
% Calculate the Shannon number for the LATITUDINAL BELT
Nor=(L+1)^2-Nor;
case {1 3}
otherwise
error('Specify valid case!')
end
% Whatever it is, round it to the nearest integer
N=round(Nor);
% Calculate N/A, always the same for identical L
NA=(L+1)^2/4/pi;
disp(sprintf('L = %3.3i ; TH = %2.2i ; N = %3.3i ; N/A = %8.3f',...
L,TH,N,NA))
% If we've done it before, don't redo it
fnpl=sprintf('%s/SDSUMK-%i-%i-%i-%i-%i.mat',...
fullfile(getenv('IFILES'),'WIECZOREK'),...
TH,L,N,nth,cb);
if exist(fnpl,'file')~=2 | 1==1
% Figure out order to sum them in, get expanded eigenvalues
% Both 1 and 3 map to 1, the caps, and 2 and 4 to 2, the belt
[lrnk,mrnk,lval,VV,Vsum]=sdelm(TH,L,mod(cb+1,2)+1,1);
% If the sum is wrong, and we mean, really wrong, not due to rounding
if round(Vsum)~=N & abs(Nor-Vsum)>tol
error('Shannon number must equal sum of eigenvalues')
end
% Must have all the pairs of orders to be longitudinally independent
if N~=0
if mrnk(N)~=0 & ... % Not zero
lrnk(N)==lrnk(N+1) & ... % Same degree
[mrnk(N)==-mrnk(N+1)] % Just switched signs
N=N+1;
disp(sprintf(...
'Shannon number updated to %i to avoid degenerate split',N))
end
end
% Calculate all the caps tapers for all orders, at one longitude only
% This is always the same and in the same order
G=0; G2=0;
for index=0:L
[E{index+1},Vg,th,C,T,V{index+1}]=...
grunbaum2(TH,L,index,nth,1);
% Calculate full unweighted sum
G=G+sum(E{index+1}.^2,2);
% Excessive verification starts here
if xver==1
% Reculculate using the standard way
[E2{index+1},V2{index+1},th,C2,n1,n2,T2]=...
sdwcap2(TH,L,index,nth,-1,1);
% Calculate full unweighted sum
G2=G2+sum(E2{index+1}.^2,2);
% The localization matrices should commute, do they?
DT=mean(mean(abs(T*T2-T2*T)));
if DT<tol
disp(sprintf('Commutation works to within %8.3e',DT))
else
warning(sprintf('Commutation troubled: %8.3e > %1.0e',DT,tol))
end
% The eigenvalues should be nearly identical
DV=mean(abs(V{index+1}-V2{index+1}));
if DV<tol
disp(sprintf('Eigenvalues identical within %8.3e',DV))
else
warning(sprintf('Eigenvalue troubled: %8.3e > %1.0e',DV,tol))
end
% The spectral eigenfunction matrices should be identical as long
% as the eigenvalue is not too near zero; error if N1 is not N2
N1=sum(V{index+1}>tol);
N2=sum(V2{index+1}>tol);
if N1>0
D=E{index+1}(:,1:N1)-E2{index+1}(:,1:N2);
DE=mean(mean(abs(D)));
if DE<tol
disp(sprintf(...
'Significant eigenfunctions to %8.3e',DE))
else
warning(sprintf(...
'Significant eigenfunctions troubled: %8.3e > %1.0e',DE,tol))
end
end
end
% Switch eigenvalue from cap to belt, 1-cap or 1-belt
switch cb
case {1 4}
% Cap ordering/Cap eigenvalue & Belt ordering/1-Belt eigenvalue
V{index+1}=V{index+1};
case {2 3}
% Belt ordering/Belt eigenvalue & Cap ordering/1-Cap eigenvalue
V{index+1}=1-V{index+1};
end
end % Sum over orders
if xver==1
% Make sure that the full unweighted sum reduces to N/A
if any(abs(G2-NA)>tol)
warning(sprintf(...
'Unweighted sum off N/A by %8.3f for L= %i and TH= %i',...
max(abs(G2-NA)),L,TH))
else
disp(sprintf(...
'Unweighted sum within N/A by %8.3e for L= %i and TH= %i',...
max(abs(G2-NA)),L,TH))
end
end
% Make sure that the full unweighted sum reduces to N/A
if any(abs(G-NA)>tol)
warning(sprintf(...
'Unweighted sum off N/A by %8.3f for L= %i and TH= %i',...
max(abs(G-NA)),L,TH))
err=mean(abs(G(:)-NA));
return
else
disp(sprintf(...
'Unweighted sum within N/A by %8.3e for L= %i and TH= %i',...
max(abs(G-NA)),L,TH))
end
err=mean(abs(G(:)-NA));
if N~=0
% No point in keeping G here, is there, thus reassign
% So we don't need to sum with the longitudinal part
smrnk=mrnk(1:N); rmrnk=mrnk(N+1:end);
slrnk=lrnk(1:N); rlrnk=lrnk(N+1:end);
% And sum only the unique lrnk abs(m) combinations
% But now these are sorted upwards
sift=unique([slrnk abs(smrnk)],'rows');
seft=unique([rlrnk abs(rmrnk)],'rows');
slrnk=sift(:,1); rlrnk=seft(:,1);
smrnk=sift(:,2); rmrnk=seft(:,2);
% Calculate cumulative sums weighted by eigenvalue!
F=0; GG=0;
% Now calculate the sum only to the Shannon number N
for index=1:length(smrnk)
% Sum the eigenvalue-weighted square of the lrnk'th sequential
% eigenfunctions of the mrnk'th order
rnkm=smrnk(index)+1;
rnkl=slrnk(index);
% Sum cumulatively with the eigenvalue fixed above
F=F+(E{rnkm}(:,rnkl)).^2*V{rnkm}(rnkl);
GG=GG+sum(E{rnkm}(:,rnkl).^2,2);
end
G=F;
% And keep going all the way by adding the remaining ones
% Really could have done this in the first loop, but who cares?
for index=1:size(seft,1)
rnkm=seft(index,2)+1;
rnkl=seft(index,1);
% Sum cumulatively with the eigenvalue fixed above
G=G+(E{rnkm}(:,rnkl)).^2*V{rnkm}(rnkl);
GG=GG+sum(E{rnkm}(:,rnkl).^2,2);
end
eval(sprintf('save %s F G N th',fnpl))
end
else
eval(sprintf('load %s',fnpl))
end
end