healpix_analyse.minkowski#

Differentiable Minkowski functionals for 2D images [B, N, N].

The three 2D Minkowski functionals are:

W0 – Area : fraction of “active” pixels W1 – Perimeter : normalised boundary length W2 – Euler characteristic : topological invariant (components − holes)

All operations are differentiable; gradients flow back through img and optionally through threshold (when it is a learned tensor).

Functions#

minkowski_functionals(→ dict[str, torch.Tensor])

Compute the three 2D Minkowski functionals in a differentiable manner.

minkowski_curves(→ dict[str, torch.Tensor])

Compute Minkowski functionals at multiple thresholds (Minkowski curves).

build_healpix_adjacency(→ tuple[torch.Tensor, ...)

Pre-compute the edge and triangle adjacency for a HEALPix map.

minkowski_functionals_healpix(→ dict[str, torch.Tensor])

Differentiable Minkowski functionals for HEALPix maps.

minkowski_curves_healpix(→ dict[str, torch.Tensor])

Minkowski curves for HEALPix maps — functionals at multiple thresholds.

Module Contents#

healpix_analyse.minkowski.minkowski_functionals(img: torch.Tensor, threshold: float | torch.Tensor | None = None, temperature: float | torch.Tensor = 20.0) → dict[str, torch.Tensor][source]#

Compute the three 2D Minkowski functionals in a differentiable manner.

Parameters:
  • img (torch.Tensor, shape [B, N, N]) – Batch of square 2D images with values in [0, 1].

  • threshold (float | torch.Tensor | None) – Optional soft threshold applied via a sigmoid before computation. Accepted shapes — see _as_threshold() for full details:

    • None – no thresholding; img used as soft membership

    • float – scalar, same threshold for the whole batch

    • Tensor [] – scalar tensor (may carry requires_grad)

    • Tensor [B] – one threshold per image in the batch

    • Tensor [B,N,N]– per-pixel spatial threshold (e.g. learned)

    • Any tensor broadcastable onto [B, N, N]

  • temperature (float | torch.Tensor) – Sharpness of the sigmoid threshold. Higher → closer to hard binary.

Returns:

dict[str, Tensor] – Keys 'W0', 'W1', 'W2', each of shape [B]. Fully differentiable w.r.t. both img and threshold.

Notes

Mathematical definitions (pixel-complex formulation):

\[ \begin{align}\begin{aligned}W_0 = \frac{1}{N^2} \sum_{i,j} f_{ij}\\W_1 = \frac{1}{N^2} \sum_{i,j} |\nabla f|_1\\W_2 = \frac{Q_1 - Q_h - Q_v + Q_f}{N^2}\end{aligned}\end{align} \]

where \(Q_1\) = pixel sum, \(Q_h\) / \(Q_v\) = horizontal / vertical adjacent-pair products (soft AND), \(Q_f\) = 2×2 block product (4-connectivity formula, Hadwiger 1957).

healpix_analyse.minkowski.minkowski_curves(img: torch.Tensor, thresholds: torch.Tensor, temperature: float | torch.Tensor = 20.0) → dict[str, torch.Tensor][source]#

Compute Minkowski functionals at multiple thresholds (Minkowski curves).

Useful for cosmological field analysis, texture description, or as rich topological feature vectors for machine learning.

Parameters:
  • img (torch.Tensor, shape [B, N, N]) – Batch of square 2D images.

  • thresholds (torch.Tensor) –

    • Shape [T] – same threshold grid for every image in the batch.

    • Shape [B, T] – a different threshold grid per image (e.g. per-sample learned thresholds).

  • temperature (float | torch.Tensor) – Sigmoid sharpness. Scalar or broadcastable onto [B, T, N, N].

Returns:

dict[str, Tensor] – Keys 'W0', 'W1', 'W2', each of shape [B, T]. Fully differentiable w.r.t. both img and thresholds.

healpix_analyse.minkowski.build_healpix_adjacency(level: int, cell_ids=None, nest: bool = True, device=None) → tuple[torch.Tensor, torch.Tensor][source]#

Pre-compute the edge and triangle adjacency for a HEALPix map.

This is a one-time setup call. Pass the returned tensors to minkowski_functionals_healpix() and minkowski_curves_healpix(). The computation uses healpy and is not differentiable, but the Minkowski functions that consume the output are differentiable.

Parameters:
  • level (int) – Grid4Earth/HEALPix level. The internal resolution is nside = 2**level.

  • cell_ids (array-like or None) – Global HEALPix pixel indices of the map. None = full sky (all 12 * nside² pixels).

  • nest (bool) – True for NESTED ordering (default), False for RING.

  • device (torch.device or None) – Target device for the returned tensors.

Returns:

  • edges (LongTensor [E, 2]) – Unique pairs of adjacent local pixel indices (i < j). “Adjacent” = sharing a boundary in the HEALPix tessellation (up to 8 neighbours per pixel).

  • triangles (LongTensor [F, 3]) – Unique triples of mutually adjacent local indices (i < j < k). Used to compute the Euler characteristic.

Notes

The Euler characteristic formula on the pixel complex is:

\[\chi = Q_1 - Q_{\text{edges}} + Q_{\text{triangles}}\]

For the full sphere with all pixels active this recovers \(\chi(\mathbb{S}^2) = 2\) (Euler characteristic of the sphere).

healpix_analyse.minkowski.minkowski_functionals_healpix(img: torch.Tensor, edges: torch.Tensor, triangles: torch.Tensor, threshold: float | torch.Tensor | None = None, temperature: float | torch.Tensor = 20.0) → dict[str, torch.Tensor][source]#

Differentiable Minkowski functionals for HEALPix maps.

Analogue of minkowski_functionals() for the spherical pixel graph instead of a 2D regular grid.

Parameters:
  • img (torch.Tensor, shape [..., Npix]) – Batch of HEALPix maps. Any number of leading dimensions is accepted.

  • edges (LongTensor [E, 2]) – Adjacent pixel-pair indices from build_healpix_adjacency().

  • triangles (LongTensor [F, 3]) – Adjacent pixel-triple indices from build_healpix_adjacency().

  • threshold (float | torch.Tensor | None) – Soft threshold applied via sigmoid. Accepted shapes (with B = product of leading dims of img):

    • None – no thresholding

    • float – scalar

    • Tensor [] – scalar tensor (may carry requires_grad)

    • Tensor [B] – one threshold per sample

    • Tensor [B, Npix] – spatial (pixel-wise) threshold

    • Any tensor broadcastable on [B, Npix]

  • temperature (float | torch.Tensor) – Sigmoid sharpness.

Returns:

dict[str, Tensor] – Keys 'W0', 'W1', 'W2', each of shape [...] (same leading dims as img). Fully differentiable w.r.t. img and threshold.

Notes

Formulas on the pixel graph:

\[ \begin{align}\begin{aligned}W_0 = \frac{1}{N_{\text{pix}}} \sum_i f_i\\W_1 = \frac{1}{N_{\text{pix}}} \sum_{(i,j)\in E} |f_i - f_j|\\W_2 = \frac{Q_1 - Q_E + Q_F}{N_{\text{pix}}}\end{aligned}\end{align} \]

where \(Q_1\), \(Q_E\), \(Q_F\) are the sums of soft-AND over vertices, edges, and triangular faces respectively.

healpix_analyse.minkowski.minkowski_curves_healpix(img: torch.Tensor, edges: torch.Tensor, triangles: torch.Tensor, thresholds: torch.Tensor, temperature: float | torch.Tensor = 20.0) → dict[str, torch.Tensor][source]#

Minkowski curves for HEALPix maps — functionals at multiple thresholds.

Parameters:
  • img (torch.Tensor, shape [..., Npix])

  • edges (LongTensor [E, 2])

  • triangles (LongTensor [F, 3])

  • thresholds (Tensor [T] or [B, T]) –

    • [T] – same grid for every sample in the batch

    • [B, T] – one grid per sample (B = product of leading dims)

  • temperature (float | torch.Tensor)

Returns:

dict[str, Tensor] – Keys 'W0', 'W1', 'W2', each of shape [..., T]. Differentiable w.r.t. img and thresholds.