Wigner's $๐”‡$ and $d$ matrices

Wigner's $๐”‡$ matrices โ€” and to a lesser extent, the related $d$ matrices โ€” are extremely important in the theory of rotations. Each element is, itself, a special function of the rotation group: in particular, an eigenfunction of the left- and right-Lie derivatives, and thus a spin-weighted spherical function. Collectively, they describe how spin-weighted spherical functions transform under rotation. But their accurate and efficient computation is surprisingly subtle. This package implements the current state-of-the-art techniques for their fast and accurate computation, based on the $H$ recursion.

The actual computations can be done with the D_matrices function:

using Quaternionic
using SphericalFunctions

R = randn(RotorF64)
โ„“โ‚˜โ‚โ‚“ = 8
๐”‡ = D_matrices(R, โ„“โ‚˜โ‚โ‚“)

However, the matrices can take up a lot of memory. So for maximum efficiency when calling this function repeatedly with different R values, it is best to pre-allocate the necessary memory with the D_prep function, and the pass that in as an argument to D_matrices!:

D_storage = D_prep(โ„“โ‚˜โ‚โ‚“)
๐”‡ = D_matrices!(D_storage, R)

(Beware that, as noted in the documentation for D_matrices!, the output ๐”‡ is just a reference to part of the D_storage object, so you should not reuse D_storage until you have copied or otherwise finished using ๐”‡.)

The output ๐”‡ is a (linear!) vector of Complex numbers with the same base type as R. The ordering of the elements is described in the documentation for D_matrices. It is also possible to efficiently view slices of this vector as a series of individual matrices using a D_iterator:

for (โ„“, Dหก) in zip(0:โ„“โ‚˜โ‚โ‚“, D_iterator(๐”‡, โ„“โ‚˜โ‚โ‚“))
    # Do something with the matrix Dหก[โ„“+mโ€ฒ+1, โ„“+m+1]
end

For the $d$ matrices, we have almost the same interface, except that instead of the input quaternion R we only need the angle ฮฒ (or its complex angle expiฮฒ, which can be computed directly in some cases), and the output is real-valued:

using Quaternionic
using SphericalFunctions

ฮฒ = ฯ€ * rand(Float64)
โ„“โ‚˜โ‚โ‚“ = 8
d = d_matrices(ฮฒ, โ„“โ‚˜โ‚โ‚“)

Again, for repeated calls, it is best to pre-allocate storage:

d_storage = d_prep(โ„“โ‚˜โ‚โ‚“)
d = d_matrices!(d_storage, ฮฒ)

The output d is a vector of numbers of the same type as ฮฒ, ordered in the same way as the output of D_matrices. And similarly, we can iterate over the individual matrices using a d_iterator.

Docstrings

SphericalFunctions.D_matrices โ€” Function
D_matrices(R, โ„“โ‚˜โ‚โ‚“)
D_matrices(ฮฑ, ฮฒ, ฮณ, โ„“โ‚˜โ‚โ‚“)

Compute Wigner's ๐”‡ matrices $\mathfrak{D}^{(\ell)}_{m',m}(\beta)$ for all $\ell \leq \ell_\mathrm{max}$.

See D_matrices! for details about the input and output values.

This function only appropriate when you need to evaluate the matrices for a single value of R or ฮฑ, ฮฒ, ฮณ because it allocates large arrays and performs many calculations that could be reused. If you need to evaluate the matrices for many values of R or ฮฑ, ฮฒ, ฮณ, you should pre-allocate the storage with D_prep, and then call D_matrices! with the result instead.

source
SphericalFunctions.D_matrices! โ€” Function
D_matrices!(D_storage, R)
D_matrices!(D_storage, ฮฑ, ฮฒ, ฮณ)
D_matrices!(D, R, โ„“โ‚˜โ‚โ‚“)
D_matrices!(D, ฮฑ, ฮฒ, ฮณ, โ„“โ‚˜โ‚โ‚“)

Compute Wigner's ๐”‡ matrices $\mathfrak{D}^{(\ell)}_{m',m}(\beta)$ for all $\ell \leq \ell_\mathrm{max}$.

In all cases, the result is returned in a 1-dimensional array ordered as

[
    ๐”‡หกโ‚˜โ‚š,โ‚˜(R)
    for โ„“ โˆˆ 0:โ„“โ‚˜โ‚โ‚“
    for mp โˆˆ -โ„“:โ„“
    for m โˆˆ -โ„“:โ„“
]

When the first argument is D, it will be modified, so it must be at least as large as that array. When the first argument is D_storage, it should be the quantity returned by D_prep, and the result will be written into the D field of that tuple. Both of these options โ€” especially the latter โ€” reduce the number of allocations needed on each call to the corresponding functions, which should increase the speed significantly. Note that the D or D_storage arguments must have types compatible with the type of R or ฮฑ, ฮฒ, ฮณ.

Warn

When using the D_storage argument (which is recommended), the returned quantity D will be an alias of D_storage[1]. If you want to retain that data after the next call to D_matrices!, you should copy it with copy(D).

The ฮฑ, ฮฒ, ฮณ arguments are Euler angles as described in the documentation of Quaternionic.from_euler_angles.

See also D_matrices for a simpler function call when you only need to evaluate the matrices for a single value of R or ฮฑ, ฮฒ, ฮณ.

Examples

using Quaternionic, SphericalFunctions
โ„“โ‚˜โ‚โ‚“ = 8
T = Float64
R = Rotor{T}(1, 2, 3, 4)  # Will be normalized automatically
D_storage = D_prep(โ„“โ‚˜โ‚โ‚“, T)
D = D_matrices!(D_storage, R)
source
SphericalFunctions.D_prep โ€” Function
D_prep(โ„“โ‚˜โ‚โ‚“, [T=Float64])

Construct storage space and pre-compute recursion coefficients to compute Wigner's $\mathfrak{D}$ matrix in place.

This returns the D_storage arguments needed by D_matrices!.

source
SphericalFunctions.D_iterator โ€” Type
D_iterator(D, โ„“โ‚˜โ‚โ‚“, [โ„“โ‚˜แตขโ‚™])

Construct an Iterator that returns sub-matrices of D, each of which consists of elements $(โ„“,-โ„“,-โ„“)$ through $(โ„“,โ„“,โ„“)$, for $โ„“$ from โ„“โ‚˜แตขโ‚™ through โ„“โ‚˜โ‚โ‚“. By default, โ„“โ‚˜แตขโ‚™ is 0.

Note that the returned objects are views into the original D data โ€” meaning that you may alter their values.

Because the result is a matrix restricted to a particular $โ„“$ value, you can index the $(โ„“, mโ€ฒ, m)$ element as [โ„“+mโ€ฒ+1, โ„“+m+1]. For example, you might use this as something like

for (โ„“, Dหก) in zip(โ„“โ‚˜แตขโ‚™:โ„“โ‚˜โ‚โ‚“, D_iterator(D, โ„“โ‚˜โ‚โ‚“))
    for mโ€ฒ in -โ„“:โ„“
        for m in -โ„“:โ„“
            Dหก[โ„“+mโ€ฒ+1, โ„“+m+1] = <...>
        end
    end
end

Also note that no bounds checking is done, either at instantiation time or during iteration. You are responsible for ensuring that the size of D and the values of โ„“โ‚˜โ‚โ‚“ and โ„“โ‚˜แตขโ‚™ make sense.

source
SphericalFunctions.d_matrices โ€” Function
d_matrices(ฮฒ, โ„“โ‚˜โ‚โ‚“)
d_matrices(expiฮฒ, โ„“โ‚˜โ‚โ‚“)

Compute Wigner's $d^{(\ell)}$ matrices with elements $d^{(\ell)}_{m',m}(\beta)$ for all $\ell \leq \ell_\mathrm{max}$. The $d$ matrices are sometimes called the "reduced" Wigner matrices, in contrast to the full $\mathfrak{D}$ matrices.

See d_matrices! for details about the input and output values.

This function only appropriate when you need to evaluate the matrices for a single value of ฮฒ or expiฮฒ because it allocates large arrays and performs many calculations that could be reused. If you need to evaluate the matrices for many values of ฮฒ or expiฮฒ, you should pre-allocate the storage with d_prep, and then call d_matrices! with the result instead.

source
SphericalFunctions.d_matrices! โ€” Function
d_matrices!(d_storage, ฮฒ)
d_matrices!(d_storage, expiฮฒ)
d_matrices!(d, ฮฒ, โ„“โ‚˜โ‚โ‚“)
d_matrices!(d, expiฮฒ, โ„“โ‚˜โ‚โ‚“)

Compute Wigner's $d^{(\ell)}$ matrices with elements $d^{(\ell)}_{m',m}(\beta)$ for all $\ell \leq \ell_\mathrm{max}$. The $d$ matrices are sometimes called the "reduced" Wigner matrices, in contrast to the full $\mathfrak{D}$ matrices.

In all cases, the result is returned in a 1-dimensional array ordered as

[
    dหกโ‚˜โ‚š,โ‚˜(ฮฒ)
    for โ„“ โˆˆ 0:โ„“โ‚˜โ‚โ‚“
    for mp โˆˆ -โ„“:โ„“
    for m โˆˆ -โ„“:โ„“
]

When the first argument is d, it will be modified, so it must be at least as large as that array. When the first argument is d_storage, it should be the quantity returned by d_prep, and the result will be written into the d field of that tuple. Both of these options โ€” especially the latter โ€” reduce the number of allocations needed on each call to the corresponding functions, which should increase the speed significantly.

Warn

When using the d_storage argument (which is recommended), the returned quantity d will be an alias of d_storage[1]. If you want to retain that data after the next call to d_matrices!, you should copy it with copy(d).

See also d_matrices for a simpler function call when you only need to evaluate the matrices for a single value of ฮฒ or expiฮฒ.

Examples

using SphericalFunctions
โ„“โ‚˜โ‚โ‚“ = 8
T = Float64
ฮฒ = T(1)/8
d_storage = d_prep(โ„“โ‚˜โ‚โ‚“, T)
d = d_matrices!(d_storage, ฮฒ)
source
SphericalFunctions.d_prep โ€” Function
d_prep(โ„“โ‚˜โ‚โ‚“, [T=Float64])

Construct space and pre-compute recursion coefficients to compute Wigner's $d$ matrix in place.

This returns the d_storage arguments needed by d_matrices!.

source
SphericalFunctions.d_iterator โ€” Type
d_iterator(d, โ„“โ‚˜โ‚โ‚“, [โ„“โ‚˜แตขโ‚™])

Construct an Iterator that returns sub-matrices of d, each of which consists of elements $(โ„“,-โ„“,-โ„“)$ through $(โ„“,โ„“,โ„“)$, for $โ„“$ from โ„“โ‚˜แตขโ‚™ through โ„“โ‚˜โ‚โ‚“. By default, โ„“โ‚˜แตขโ‚™ is 0.

Note that the returned objects are views into the original d data โ€” meaning that you may alter their values.

Because the result is a matrix restricted to a particular $โ„“$ value, you can index the $(โ„“, mโ€ฒ, m)$ element as [โ„“+mโ€ฒ+1, โ„“+m+1]. For example, you might use this as something like

for (โ„“, dหก) in zip(โ„“โ‚˜แตขโ‚™:โ„“โ‚˜โ‚โ‚“, d_iterator(d, โ„“โ‚˜โ‚โ‚“))
    for mโ€ฒ in -โ„“:โ„“
        for m in -โ„“:โ„“
            dหก[โ„“+mโ€ฒ+1, โ„“+m+1] = <...>
        end
    end
end

Also note that no bounds checking is done, either at instantiation time or during iteration. You are responsible for ensuring that the size of d and the values of โ„“โ‚˜โ‚โ‚“ and โ„“โ‚˜แตขโ‚™ make sense.

source