torch_harmonics.ResampleS2#

class torch_harmonics.ResampleS2(
nlat_in,
nlon_in,
nlat_out,
nlon_out,
grid_in='equiangular',
grid_out='equiangular',
mode='bilinear',
)[source]#

Bases: Module

Resampling module for signals on the 2-sphere \(S^2\).

This module resamples a spherical signal from one grid resolution (and type) to another. Interpolation is performed independently along latitudes and longitudes, with proper handling of periodicity in \(\lambda\) and pole expansion when the output grid extends beyond the input latitude range.

Two interpolation modes are available:

  • "bilinear" – Standard bilinear (linear-linear) interpolation. For two neighbouring grid values \(f_0\) and \(f_1\) with interpolation weight \(t \in [0, 1]\), the interpolated value is

    \[f(t) = (1 - t)\, f_0 + t\, f_1\]

    This is applied first along the latitudinal (\(\theta\)) and then along the longitudinal (\(\lambda\)) direction.

  • "bilinear-spherical" – Spherical linear interpolation (slerp) for fields whose values are angles (e.g.directions or phases, in radians). Neighbouring samples are interpolated along the shorter arc of the circle rather than along a straight line in value space:

    \[f(t) = f_0 + t \cdot \mathrm{wrap}_\pi(f_1 - f_0), \qquad \mathrm{wrap}_\pi(\delta) \in (-\pi, \pi]\]

    This is the two-dimensional closed form of slerp; see the _slerp_shortest_arc helper in this module for the derivation. Since \(\mathrm{wrap}_\pi\) is the identity whenever \(|f_1 - f_0| \le \pi\), this mode is identical to "bilinear" except across a \(2\pi\) phase wrap – precisely the discontinuity it exists to handle. Interpolating \(f_0 = 3\) and \(f_1 = -3\) (nearly the same direction, either side of the branch cut) gives \(\pi\) here, whereas "bilinear" gives \(0\), the opposite direction.

    The result is expressed as a continuous lift from \(f_0\) and is not re-wrapped, so it stays adjacent to \(f_0\) and may leave \((-\pi, \pi]\). Apply torch.remainder() afterwards if a canonical range is required.

Parameters:
  • nlat_in (int) – Number of latitude points in the input grid

  • nlon_in (int) – Number of longitude points in the input grid

  • nlat_out (int) – Number of latitude points in the output grid

  • nlon_out (int) – Number of longitude points in the output grid

  • grid_in (str, optional) – Input grid type ("equiangular", "legendre-gauss", "lobatto"), by default "equiangular"

  • grid_out (str, optional) – Output grid type ("equiangular", "legendre-gauss", "lobatto"), by default "equiangular"

  • mode (str, optional) – Interpolation mode ("bilinear", "bilinear-spherical"), by default "bilinear". See above for a description of each mode.

Examples

>>> import torch
>>> import torch_harmonics as th
>>> resample = th.ResampleS2(64, 128, 128, 256)
>>> x = torch.randn(1, 64, 128)
>>> y = resample(x)
>>> y.shape
torch.Size([1, 128, 256])
forward(x)[source]#

Resample a spherical signal onto the output grid.

Parameters:

x (torch.Tensor) – Input signal of shape (..., nlat_in, nlon_in). Resampling acts on the last two (spatial) dimensions; any leading batch/channel dimensions are preserved.

Returns:

Resampled signal of shape (..., nlat_out, nlon_out).

Return type:

torch.Tensor