spectral: vectors instead of new[]; vlaw: extract law + vlaw_check target
- spectral.cpp: window_/buf_/tmp_buf_/fir_buf_/fir_freq_ as std::vector (no exception-leak in ctor, destructor = default) - framed_model.hpp: extract vlaw_cut/vlaw_mask inline (BLOCKMAP:314 softplus) - dsp/vlaw_check.cpp: unit test for law (monotonic, zero-level, delta, ref, comb-neutral) — PASS - CMake: add vlaw_check target - Guard: corpus --compare d=+0.000, fn529fe0_check PASS, twin_check PASS
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
#include "framed_model.hpp"
|
||||
|
||||
// Unit check for the VLAW detector law (BLOCKMAP:314 softplus proxy):
|
||||
// cut = alpha * ln1p(lvl/beta) + c [+ delta]
|
||||
// mask = 10^(-cut/20)
|
||||
// Reference values hand-computed from the dual-calibrated constants
|
||||
// (alpha=3.2193, beta=0.4927, c=0.5423, delta=6.9177 — README.md:26).
|
||||
int main() {
|
||||
int fail = 0;
|
||||
|
||||
// --- law monotonicity: higher level -> stronger cut -> smaller mask ---
|
||||
double m0 = vlaw_mask(0.01, 3.2193, 0.4927, 0.5423, 0.0);
|
||||
double m1 = vlaw_mask(1.0, 3.2193, 0.4927, 0.5423, 0.0);
|
||||
double m2 = vlaw_mask(10.0, 3.2193, 0.4927, 0.5423, 0.0);
|
||||
bool mono = (m0 > m1) && (m1 > m2);
|
||||
std::printf("vlaw monotonic: m(0.01)=%.4f m(1)=%.4f m(10)=%.4f (%s)\n",
|
||||
m0, m1, m2, mono ? "OK" : "MISMATCH");
|
||||
if (!mono) fail = 1;
|
||||
|
||||
// --- zero level: cut = c => mask = 10^(-c/20) ---
|
||||
double mz = vlaw_mask(0.0, 3.2193, 0.4927, 0.5423, 0.0);
|
||||
double ez = std::pow(10.0, -0.5423 / 20.0);
|
||||
bool zok = std::fabs(mz - ez) < 1e-9;
|
||||
std::printf("vlaw zero-level: mask=%.6f expect=%.6f (%s)\n",
|
||||
mz, ez, zok ? "OK" : "MISMATCH");
|
||||
if (!zok) fail = 1;
|
||||
|
||||
// --- delta branch adds cut -> deeper mask ---
|
||||
double md = vlaw_mask(1.0, 3.2193, 0.4927, 0.5423, 6.9177);
|
||||
bool dok = md < m1;
|
||||
std::printf("vlaw delta: mask+delta=%.4f < %.4f (%s)\n",
|
||||
md, m1, dok ? "OK" : "MISMATCH");
|
||||
if (!dok) fail = 1;
|
||||
|
||||
// --- numeric reference: lvl=1.0, dual params ---
|
||||
// cut = 3.2193 * ln(1 + 1/0.4927) + 0.5423
|
||||
double cut_ref = 3.2193 * std::log1p(1.0 / 0.4927) + 0.5423;
|
||||
double mref = std::pow(10.0, -cut_ref / 20.0);
|
||||
bool rok = std::fabs(m1 - mref) < 1e-9;
|
||||
std::printf("vlaw ref: mask=%.6f expect=%.6f cut=%.4f (%s)\n",
|
||||
m1, mref, cut_ref, rok ? "OK" : "MISMATCH");
|
||||
if (!rok) fail = 1;
|
||||
|
||||
// --- comb neutrality: alpha=0.05 beta=5.0 c=0 -> mask ~ 1 for lvl=0 ---
|
||||
double mc = vlaw_mask(0.0, 0.05, 5.0, 0.0, 0.0);
|
||||
bool cok = std::fabs(mc - 1.0) < 1e-9;
|
||||
std::printf("vlaw comb-neutral: mask(0)=%.6f expect=1.0 (%s)\n",
|
||||
mc, cok ? "OK" : "MISMATCH");
|
||||
if (!cok) fail = 1;
|
||||
|
||||
std::printf("vlaw_check %s\n", fail ? "FAIL" : "PASS");
|
||||
return fail;
|
||||
}
|
||||
Reference in New Issue
Block a user