Skip to content

Commit a8940ee

Browse files
committed
Use shifted Arnoldi method for finding just 1 eval/vec closest to guess
1 parent 1a7c6e3 commit a8940ee

1 file changed

Lines changed: 44 additions & 18 deletions

File tree

Kernel/SpinWeightedSpheroidalHarmonics.m

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@
9999
,{nUp+nDown+1,nUp+nDown+1}];
100100

101101

102+
(* Mma ought to provide a sparse identity matrix but... *)
103+
SparseIdentityMatrix[n_Integer?NonNegative]:=SparseArray[{{x_,x_}->1},{n,n}];
104+
105+
102106
(* ::Subsection::Closed:: *)
103107
(*Continued fraction*)
104108

@@ -132,12 +136,22 @@
132136
(*Spherical expansion method*)
133137

134138

135-
Options[SWSHEigenvalueSpectral] = {"NumTerms" -> Automatic};
139+
Options[SWSHEigenvalueSpectral] = {"InitialGuess" -> Automatic, "NumTerms" -> Automatic};
136140

137141

138-
SWSHEigenvalueSpectral[s_, l_, m_, \[Gamma]_, OptionsPattern[]]:=
139-
Module[{nDown, nUp, Matrix, Eigens, lmin},
140-
(* FIXME: Improve the estimate of nmax. It should depend on the accuarcy sought. *)
142+
SWSHEigenvalueSpectral[s_, l_, m_, \[Gamma]_, opts:OptionsPattern[]]:=
143+
Module[{nDown, nUp, AMatrix, lmin, AGuess},
144+
Switch[OptionValue["InitialGuess"],
145+
Automatic,
146+
(* NOTE this is currently an initial value of A, not \[Lambda] *)
147+
AGuess = l(l+1) - s(s+1);,
148+
_?NumericQ,
149+
AGuess = OptionValue["InitialGuess"];,
150+
_,
151+
Message[SpinWeightedSpheroidalEigenvalue::optx, Method -> {"SphericalExpansion", opts}];
152+
Return[$Failed];
153+
];
154+
(* FIXME: Improve the estimate of nmax. It should depend on the accuracy sought. *)
141155
Switch[OptionValue["NumTerms"],
142156
Automatic,
143157
nUp = Ceiling[Abs[3/2\[Gamma]]]+5;
@@ -151,13 +165,13 @@
151165
lmin=Max[Abs[s],Abs[m]];
152166
nDown = Min[nUp, l-lmin];
153167

154-
Matrix=SparseSWSHMatrix[s,l,m,\[Gamma],nDown,nUp];
155-
156-
(* To choose the eigenvalue corrsponding to the desired l, we assume that the real
157-
part of eigenvalue is a monotonic function of l. *)
158-
Eigens=-Sort[Quiet[Eigenvalues[Matrix],Eigenvalues::arhm]];
159-
160-
Eigens[[-(nDown+1)]]-s(s+1)
168+
AMatrix = SparseSWSHMatrix[s,l,m,\[Gamma],nDown,nUp];
169+
(* Because the matrix built up above has an annoying convention... *)
170+
(* After this step, the eigenvalues are A's *)
171+
AMatrix = -AMatrix - s(s+1)*SparseIdentityMatrix[nUp+nDown+1];
172+
(* The above manipulation can be absorbed into the shift below, and flipping the sign of the eigenvalue *)
173+
(* Do we want to do that? *)
174+
Eigenvalues[AMatrix, -1, Method->{"Arnoldi", "Shift"->AGuess}][[1]]
161175
];
162176

163177

@@ -326,11 +340,21 @@
326340
(*Spherical expansion method*)
327341

328342

329-
Options[SWSHSSpectral] = {"NumTerms" -> Automatic};
343+
Options[SWSHSSpectral] = {"InitialGuess"->Automatic, "NumTerms" -> Automatic};
330344

331345

332346
SWSHSSpectral[s_Integer, l_Integer, m_Integer, \[Gamma]_, opts:OptionsPattern[]] :=
333-
Module[{lmin, nUp, nDown, A, esys,evec,eval,sign,pos},
347+
Module[{lmin, nUp, nDown, AMatrix, evec,sign,AGuess},
348+
Switch[OptionValue["InitialGuess"],
349+
Automatic,
350+
(* NOTE this is currently an initial value of A, not \[Lambda] *)
351+
AGuess = l(l+1) - s(s+1);,
352+
_?NumericQ,
353+
AGuess = OptionValue["InitialGuess"];,
354+
_,
355+
Message[SpinWeightedSpheroidalEigenvalue::optx, Method -> {"SphericalExpansion", opts}];
356+
Return[$Failed];
357+
];
334358
(* FIXME: Improve the estimate of nmax. It should depend on the accuracy sought. *)
335359
Switch[OptionValue["NumTerms"],
336360
Automatic,
@@ -345,11 +369,13 @@
345369
lmin = Max[Abs[s],Abs[m]];
346370
nDown = Min[l-lmin,nUp];
347371

348-
A = SparseSWSHMatrix[s,l,m,\[Gamma],nDown,nUp];
349-
esys = Quiet[Eigensystem[A], Eigenvalues::arhm];
350-
eval = -Sort[esys[[1]]][[-(nDown+1)]];
351-
pos = Position[esys[[1]], -eval][[1]];
352-
evec = First[esys[[2,pos]]];
372+
AMatrix = SparseSWSHMatrix[s,l,m,\[Gamma],nDown,nUp];
373+
(* Because the matrix built up above has an annoying convention... *)
374+
(* After this step, the eigenvalues are A's *)
375+
AMatrix = -AMatrix - s(s+1)*SparseIdentityMatrix[nUp+nDown+1];
376+
(* The above manipulation can be absorbed into the shift below, and flipping the sign of the eigenvalue *)
377+
(* Do we want to do that? *)
378+
evec = Eigenvectors[AMatrix, -1, Method->{"Arnoldi", "Shift"->AGuess}][[1]];
353379

354380
sign=Sign[evec[[Min[l-lmin+1,(nUp+nDown)/2+1]]]];
355381
SpinWeightedSpheroidalHarmonicSFunction[s, l, m, \[Gamma], {"SphericalExpansion", sign*evec, nDown, nUp}]

0 commit comments

Comments
 (0)