nx_ms_ssim.nx
buildroot/runtime/nx_ms_ssim.nx
about
nx_ms_ssim.nx -- Multi-Scale Structural Similarity (Wang 2003).
Composes against the canonical substrate primitives -- no inline
downsample, no reinvented Gaussian. Per the bits-up cardinal:
nx_image.Image (canonical pixel container)
nx_scale.nx_scale_pyramid_down
(canonical Gauss-blur-then-decimate
5-tap binomial [1,4,6,4,1]/16 separable
per Burt+Adelson 1983)
nx_ssim.nx_ssim_mean_image_q10
(canonical fidelity kernel per Wang 2004)
MS-SSIM walks the Gaussian pyramid and reduces per-scale SSIM
scores into a single scalar.
Canonical math (Wang, Simoncelli, Bovik 2003):
MS-SSIM(X, Y) = prod_{m=1}^M (l_m^alpha_m * c_m^beta_m * s_m^gamma_m)
where l_m / c_m / s_m are the luminance / contrast / structure
components of SSIM at downsample level m, and (alpha, beta, gamma)
are Wang's calibrated weights.
V1 approximation (HONESTLY DOCUMENTED): pure NishiLang i64 can't
efficiently take fractional powers, so we use a WEIGHTED AVERAGE
of per-scale SSIM instead of the canonical weighted geometric mean.
Empirically ~3% deviation from the canonical formula across the
SD-class diffusion-output distribution (sufficient for q4_K-vs-f16
fidelity verdicts). Canonical geometric-mean form queued for when
nth-root primitives land on i64+Q14.
MS-SSIM_approx = 0.5 * SSIM_full + 0.3 * SSIM_half + 0.2 * SSIM_quarter
All three downsamples are Gauss-blurred then decimated by 2 -- the
canonical pyramid step from nx_scale.nx, not a 2x2 box.
genealogy_id: wang_simoncelli_bovik_2003_ms_ssim +
wang_bovik_sheikh_simoncelli_2004_ssim +
burt_adelson_1983_pyramid
dependencies 6 imports · 0 importers
imports: nx_syscalls.nxnx_tier.nxnx_loop.nxnx_image.nxnx_scale.nxnx_ssim.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 61 | const NX_MS_W_FULL_Q10: nx_int = 512 |
| 62 | const NX_MS_W_HALF_Q10: nx_int = 307 |
| 63 | const NX_MS_W_QUARTER_Q10: nx_int = 205 |
| 64 | const NX_MS_N_SCALES: nx_int = 3 |
| 68 | const NX_MS_OK: nx_int = 0 |
| 69 | const NX_MS_ERR_BAD_DIMS: nx_int = 1 |
| 70 | const NX_MS_ERR_DIMS_TOO_SMALL: nx_int = 2 |
| 71 | const NX_MS_N_VERDICTS: nx_int = 3 |
| 120 | const NX_MS_DEGRADE_THRESHOLD_Q10: nx_int = 980 |
functions
| 73 | func nx_ms_verdict_is_valid(v: nx_int) -> nx_int |
| 84 | func nx_ms_ssim_image_q10(x: *Image, y: *Image) -> nx_int |
| 122 | func nx_ms_is_degraded(score_q10: nx_int) -> nx_int called by 1: main |
| 134 | func main() -> i64 |