File size: 1,440 Bytes
c30b460 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | from __future__ import annotations
import numpy as np
from .silverstein import df2, solve_kappa
def diamond(eigenvalues: np.ndarray, kappa: float, vector: np.ndarray) -> float:
eig = np.asarray(eigenvalues, dtype=np.float64)
vec = np.asarray(vector, dtype=np.float64)
weights = eig / (eig + kappa) ** 2
return float(np.sum(vec**2 * weights))
def denoiser_variance_prediction(
eigenvalues: np.ndarray,
noise_variance: float,
n_samples: int,
probe_index: int,
location: np.ndarray,
) -> float:
eig = np.asarray(eigenvalues, dtype=np.float64)
if not 0 <= probe_index < eig.size:
raise IndexError("probe_index out of bounds")
kappa = solve_kappa(eig, noise_variance, n_samples)
probe = np.zeros_like(eig)
probe[probe_index] = 1.0
denominator = float(n_samples) - df2(eig, kappa)
if denominator <= 0:
raise ValueError("n_samples must exceed df2(kappa)")
return (kappa**2 / denominator) * diamond(eig, kappa, probe) * diamond(
eig, kappa, location
)
def denoiser_anisotropy_profile(
eigenvalues: np.ndarray, noise_variance: float, n_samples: int, location: np.ndarray
) -> np.ndarray:
eig = np.asarray(eigenvalues, dtype=np.float64)
return np.array(
[
denoiser_variance_prediction(eig, noise_variance, n_samples, idx, location)
for idx in range(eig.size)
],
dtype=np.float64,
)
|