| 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, |
| ) |
|
|