Internal functions
There are various functions that are only used internally, some of which are likely to be deprecated in the near future. These are documented here for completeness.
$H$ recursion and ALFs
The fundamental algorithm is the $H$ recursion, which is the core computation needed for Wigner's $d$ and $π$ matrices, and the spin-weighted spherical harmonics ${}_{s}Y_{\ell,m}$, as well as map2salm
functions.
SphericalFunctions.H!
β MethodH!(H, expiΞ², ββββ, mβ²βββ, H_rec_coeffs)
H!(H, expiΞ², ββββ, mβ²βββ, H_rec_coeffs, Hindex)
Compute the $H$ matrix defined by Gumerov and Duraiswami [8].
This computation forms the basis for computing Wigner's $d$ and $π$ matrices via d_matrices!
and D_matrices!
, the spin-weighted spherical harmonics via sYlm_values!
, and for transforming from values of spin-weighted spherical functions evaluated on a grid to the corresponding mode weights via map2salm
.
Due to symmetries, we only need to compute ~1/4 of the elements of this matrix, so only those elements with $m β₯ |mβ²|$ are computed. The relevant indices of the H
vector are computed based on the Hindex
function β which defaults to WignerHindex
, but could reasonably be WignerDindex
if the input H
vector contains all valid indices. However, it is assumed that the storage scheme used for H
is such that the successive $m$ values are located in successive elements.
If $mβ²βββ < ββββ$, we don't even need 1/4 of the elements, and only values with $|mβ²| β€ mβ²βββ$ will be computed. This is particularly useful for computing spin-weighted spherical harmonics.
Note that the recursion coefficients H_rec_coeffs
should be the quantity returned by H_recursion_coefficients
.
SphericalFunctions.H_recursion_coefficients
β MethodH_recursion_coefficients(ββββ, T)
Pre-compute constants used in Wigner H recursion.
Internally, the $H$ recursion relies on calculation of the Associated Legendre Functions (ALFs), which can also be called on their own:
SphericalFunctions.ALFcompute!
β MethodALFcompute(expiΞ², nmax)
ALFcompute!(PΜ, expiΞ², nmax)
ALFcompute(expiΞ², nmax, recursion_coefficients)
ALFcompute!(PΜ, expiΞ², nmax, recursion_coefficients)
Compute the "fully normalized" Associated Legendre Functions up to some maximum n
value nmax
.
These functions can take a vector PΜ, to store the data, stored in order of increasing m
most rapidly varying and then increasing n
. If not supplied, PΜ will be constructed for you and returned.
The optional recursion_coefficients
argument must be an ALFRecursionCoefficients
, which stores various constant coefficients used in the recursion. This object requires more than 3x the memory and more than 20x the time to compute a single PΜ vector without this argument, but passing it will typically speed up the calculation of each PΜ by a factor of 8x or so. Thus, if you expect to compute PΜ more than a few times, it will take less time to pre-compute those factors, and pass them to this function.
Note that the base real type will be inferred from the (complex) type of expiΞ²
. If present, the base types of PΜ
and recursion_coefficients
must agree.
The function ${}_{s}\lambda_{\ell,m}$ is defined as essentially ${}_{s}Y_{\ell,0}$, and is important internally for computing the ALFs. We have some important utilities for computing it:
SphericalFunctions.Ξ»_recursion_initialize
β FunctionΞ»_recursion_initialize(cosΞΈ, sinΒ½ΞΈ, cosΒ½ΞΈ, s, β, m)
This provides initial values for the recursion to find ${}_{s}\lambda_{\ell,m}$ along indices of increasing $\ell$, due to Kostelec & Rockmore Specifically, this function computes values with $\ell=m$.
\[{}_{s}\lambda_{\ell,m}(\theta) := {}_{s}Y_{\ell,m}(\theta, 0) = (-1)^m\, \sqrt{\frac{2\ell+1}{4\pi}} d^\ell_{-m,s}(\theta)\]
SphericalFunctions.Ξ»_iterator
β TypeΞ»_iterator(ΞΈ, s, m)
Construct an object to iterate over βΞ»ββ values.
The $βΞ»ββ(ΞΈ)$ function is defined as the spin-weighted spherical harmonic evaluated at spherical coordinates $(ΞΈ, Ο)$, with $Ο=0$. In particular, note that it is real-valued. The return type is determined by the type of ΞΈ
(or more precisely, cosΒ½ΞΈ).
This algorithm by Kostelec & Rockmore allows us to iterate over increasing $β$ values, for given fixed $s$ and $m$ values.
Note that this iteration has no inherent bound, so if you try to iterate over all values, you will end up in an infinite loop. Instead, you can zip
this iterator with another:
ΞΈ = 0.1
s = -2
m = 1
Ξ» = Ξ»_iterator(ΞΈ, s, m)
Ξ = max(abs(s), abs(m))
for (β, βΞ»ββ) β zip(Ξ:Ξ+5, Ξ»)
@show (β, βΞ»ββ)
end
Alternatively, you could use Iterates.take(Ξ», 6)
, for example.
Note that the iteration always begins with β = Ξ = max(abs(s), abs(m))
.
SphericalFunctions.AlternatingCountdown
β TypeSimple iterator to count down to 0, with alternating signs
julia> collect(AlternatingCountdown(5))
11-element Vector{Int64}:
5
-5
4
-4
3
-3
2
-2
1
-1
0
βπ
Various d
, D
, and sYlm
functions are important in the main API. Their names and signatures have been tweaked from older versions of this package. The only one with remaining documentation is βπ
, which could probably be replaced by sYlm_values
, except that the default pixelization is golden_ratio_spiral_rotors
, which makes it very convenient for interacting with SSHT
.
SphericalFunctions.βπ
β Functionβπ(s, ββββ, [T=Float64], [RΞΈΟ=golden_ratio_spiral_rotors(s, ββββ, T)])
Construct a matrix of $βYββ(RΞΈΟ)$ values for the input s
and all nontrivial $(\ell, m)$ up to ββββ
.
This is a fast and accurate method for mapping between the vector of spin-weighted spherical-harmonic mode weights $βπββ$ and the vector of function values on the sphere $βπβ±Όβ$, as
\[βπβ±Όβ = βπ\, βπββ,\]
where the right-hand side represents the matrix-vector product. As usual, we assume that the $βπββ$ modes are ordered by increasing $m β [-β:β]$, and $β β [|s|:ββββ]$. The ordering of the $βπβ±Όβ$ values will be determined by the ordering of the argument RΞΈΟ
.
Note that the number of modes need not be the same as the number of points on which the function is evaluated, which would imply that the output matrix is not square. To be able to invert the relationship, however, we need the number of points $βπβ±Όβ$ to be at least as large as the number of modes $βπββ$.
Note that the usefulness of this approach is limited by the fact that the size of this matrix scales as βββββ΄. As such, it is mostly useful only for ββββ of order dozens, rather than β say β the tens of thousands that CMB astronomy or lensing require, for example.
Direct application and inversion of this matrix are used in the "direct" methods of $s$-SHT transformations. See SSHTDirect
for details about the implementation.
Transformation
The newer SSHT
interface is more efficient for most purposes, but this package used to use functions named map2salm
, which is still present, but may be deprecated.
SphericalFunctions.map2salm!
β Methodmap2salm!(salm, map, spin, βmax)
map2salm!(salm, map, plan)
Transform map
values sampled on the sphere to ${}_sa_{\ell, m}$ modes in place.
For details, see map2salm
.
SphericalFunctions.map2salm
β Methodmap2salm(map, spin, βmax)
map2salm(map, plan)
Transform map
values sampled on the sphere to ${}_sa_{\ell, m}$ modes.
The map
array should have size NΟ along its first dimension and NΟ along its second; any number of dimensions may follow. The spin
must be entered explicitly, and βmax
is the highest β value you want in the output.
For repeated applications of this function with different values of map
, it is more efficient to pre-compute plan
using plan_map2salm
. These functions will create a new salm
array on each call. To operate in place on a pre-allocated salm
array, use map2salm!
.
The core of this function follows the method described by Reinecke and Seljebotn.
SphericalFunctions.plan_map2salm
β Methodplan_map2salm(map, spin, βmax)
Precompute values to use in executing map2salm
or map2salm!
.
The arguments to this function exactly mirror those of the first form of map2salm
, and all but the first argument in the first form of map2salm!
. The plan
returned by this function can be passed to the second forms of those functions to avoid some computation and allocation costs.
Note that the plan
object is not thread safe; a separate plan
should be created for each thread that will use one, or locks should be used to ensure that a single plan
is not used at the same time on different threads.