|
99 | 99 | ,{nUp+nDown+1,nUp+nDown+1}]; |
100 | 100 |
|
101 | 101 |
|
| 102 | +(* Mma ought to provide a sparse identity matrix but... *) |
| 103 | +SparseIdentityMatrix[n_Integer?NonNegative]:=SparseArray[{{x_,x_}->1},{n,n}]; |
| 104 | + |
| 105 | + |
102 | 106 | (* ::Subsection::Closed:: *) |
103 | 107 | (*Continued fraction*) |
104 | 108 |
|
|
132 | 136 | (*Spherical expansion method*) |
133 | 137 |
|
134 | 138 |
|
135 | | -Options[SWSHEigenvalueSpectral] = {"NumTerms" -> Automatic}; |
| 139 | +Options[SWSHEigenvalueSpectral] = {"InitialGuess" -> Automatic, "NumTerms" -> Automatic}; |
136 | 140 |
|
137 | 141 |
|
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. *) |
141 | 155 | Switch[OptionValue["NumTerms"], |
142 | 156 | Automatic, |
143 | 157 | nUp = Ceiling[Abs[3/2\[Gamma]]]+5; |
|
151 | 165 | lmin=Max[Abs[s],Abs[m]]; |
152 | 166 | nDown = Min[nUp, l-lmin]; |
153 | 167 |
|
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]] |
161 | 175 | ]; |
162 | 176 |
|
163 | 177 |
|
|
326 | 340 | (*Spherical expansion method*) |
327 | 341 |
|
328 | 342 |
|
329 | | -Options[SWSHSSpectral] = {"NumTerms" -> Automatic}; |
| 343 | +Options[SWSHSSpectral] = {"InitialGuess"->Automatic, "NumTerms" -> Automatic}; |
330 | 344 |
|
331 | 345 |
|
332 | 346 | 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 | + ]; |
334 | 358 | (* FIXME: Improve the estimate of nmax. It should depend on the accuracy sought. *) |
335 | 359 | Switch[OptionValue["NumTerms"], |
336 | 360 | Automatic, |
|
345 | 369 | lmin = Max[Abs[s],Abs[m]]; |
346 | 370 | nDown = Min[l-lmin,nUp]; |
347 | 371 |
|
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]]; |
353 | 379 |
|
354 | 380 | sign=Sign[evec[[Min[l-lmin+1,(nUp+nDown)/2+1]]]]; |
355 | 381 | SpinWeightedSpheroidalHarmonicSFunction[s, l, m, \[Gamma], {"SphericalExpansion", sign*evec, nDown, nUp}] |
|
0 commit comments