torch_harmonics.InverseRealSHT#

class torch_harmonics.InverseRealSHT(
nlat,
nlon,
lmax=None,
mmax=None,
grid='equiangular',
norm='ortho',
csphase=True,
)[source]#

Bases: Module

Defines a module for computing the inverse (real-valued) SHT. Precomputes Legendre Gauss nodes, weights and associated Legendre polynomials on these nodes.

Given complex spherical harmonic coefficients \(\hat{f}_l^m\), the inverse scalar SHT reconstructs the real-valued signal on the sphere via Legendre synthesis followed by an inverse FFT:

\[f(\theta, \lambda) = \sum_{l=0}^{l_{\max}-1} \sum_{m=0}^{m_{\max}-1} \hat{f}_l^m\, Y_l^m(\theta, \lambda)\]

See also

Spherical harmonic transforms

User guide with the full mathematical derivation, normalization conventions, grid types, and worked examples.

Parameters:
  • nlat (int) – Number of latitude points

  • nlon (int) – Number of longitude points

  • lmax (int) – Maximum spherical harmonic degree

  • mmax (int) – Maximum spherical harmonic order

  • grid (str) – Grid type ("equiangular", "legendre-gauss", "lobatto", "equiangular-trapezoidal"), by default "equiangular"

  • norm (str) – Normalization convention ("ortho", "schmidt", "unnorm"), by default "ortho".

  • csphase (bool) – Whether to include the Condon–Shortley phase factor \((-1)^m\), by default True.

Examples

>>> import torch
>>> import torch_harmonics as th
>>> nlat, nlon = 128, 256
>>> isht = th.InverseRealSHT(nlat, nlon).cuda()
>>> coeffs = torch.randn(1, 128, 129, dtype=torch.cfloat, device="cuda")
>>> signal = isht(coeffs)   # shape (1, 128, 256), real
>>> signal.shape
torch.Size([1, 128, 256])

Note

This module uses cuFFT (via torch.fft.irfft()) to compute the longitudinal inverse Fourier transform efficiently. When running in float16 or bfloat16 precision, cuFFT requires the transformed dimension (nlon) to be a power of two. If your grid does not satisfy this constraint and the module is called inside a torch.autocast context, guard it with torch.autocast(device_type="cuda", enabled=False):

with torch.autocast(device_type="cuda", dtype=torch.float16):
    # ... other half-precision work ...
    with torch.autocast(device_type="cuda", enabled=False):
        signal = isht(coeffs.to(torch.cfloat))

Note

The inverse real FFT (C2R transform) expects the DC component (\(m = 0\)) and, when nlon is even, the Nyquist component (\(m = N_\lambda / 2\)) to be purely real. This routine zeros out the imaginary parts of these components before calling the transform.

Raises:

ValueError – If the grid type is unknown

References

[2], [3]

forward(x)[source]#

Compute the inverse (real) spherical harmonic transform.

Parameters:

x (torch.Tensor) – Complex spherical harmonic coefficients of shape (..., lmax, mmax).

Returns:

Real-valued signal on the sphere of shape (..., nlat, nlon).

Return type:

torch.Tensor