multigeom.geometry.metric_field#

Local metric field on a two-dimensional slice of image space (paper Fig. 5).

At a reference image x₀ let v₁, v₂ be the two leading eigenvectors of a
metric M(x₀) (M = G, the multi-scale Fisher, or M = J, the Fisher
information) of the reference encoder, with eigenvalues λ₁ ≥ λ₂. The
perturbed images are

    x(a, b) = clip(x₀ + a ε₁ v₁ + b ε₂ v₂, −1, 1),     a, b ∈ {−h, …, h},

on an n × n grid (n = 2h + 1). At every grid point the metric of each
encoder is projected onto the fixed reference plane V = [v₁, v₂] ∈ ℝ^{P×2}:

    M₂(a, b) = Vᵀ M(x(a, b)) V ∈ ℝ^{2×2},

evaluated from the truncated eigendecomposition M ≈ U diag(λ) Uᵀ returned by
`multigeom.geometry.estimator` / `multigeom.geometry.fisher`, i.e. M₂ = (VᵀU) diag(λ)
(VᵀU)ᵀ. No P × P matrix is formed.

Step rule. The paper scales the perturbations "by the principal eigenvalues
at the reference image". The default rule is therefore

    ε_i = step_size · √λ_i          ("sqrt_lambda"),

so the grid extends further along the direction the metric weights more. The
alternative "fixed" rule uses ε₁ = ε₂ = step_size (pixel-space units; v_i
have unit Euclidean norm, so a·ε₁ is the Euclidean length of the step).

Ellipse convention. A 2 × 2 PSD matrix M₂ with eigenpairs (μ_max, u_max),
(μ_min, u_min) is drawn as the image of the unit circle under M₂^{1/2}:

    width  = 2 √μ_max,   height = 2 √μ_min,
    angle  = direction of u_max in degrees, measured from the v₁ axis.

The long axis points along the most informative direction of the plane and
its length grows with the information. This is the convention of the original
analysis, and it keeps a small projected metric (e.g. a model whose leading
directions lie outside the reference plane) visible as a small ellipse rather
than an unbounded one. It is the inverse of the iso-distance ellipse
{u : uᵀ M₂ u = 1}, whose semi-axes are 1/√μ.

Everything here is CPU/GPU agnostic and has no dependency on `diffusers`.

Functions

canonical_sign(v)

Flip v so that its largest-magnitude entry is positive (eigenvector signs are arbitrary; this makes the grid orientation reproducible).

ellipse_grid(matrices)

Apply ellipse_params over an [n, n, 2, 2] grid → [n, n, 3].

ellipse_params(M2)

(width, height, angle in degrees) of the M₂^{1/2} ellipse (module docstring).

grid_coefficients(grid_size)

Integer grid coefficients {−h, …, h} for an odd grid_size = 2h + 1.

perturbation_grid(x0, v1, v2, eps1, eps2, coeffs)

Images x(a, b) = clip(x₀ + a ε₁ v₁ + b ε₂ v₂, −1, 1) on the grid.

point_seed(seed, img_idx, i, j, grid_size)

Deterministic seed for grid point (i, j) of image img_idx.

project_metric(eigvals, eigvecs, V)

M₂ = Vᵀ (U diag(λ) Uᵀ) V for a truncated eigendecomposition.

step_sizes(lam1, lam2, rule, step_size)

(ε₁, ε₂) for the given step rule (see module docstring).