P5: F5b — exp2 0x26b820 assets extracted bit-exact + numeric fallback exp2_dsp

Extracted the 8x16 irrational tables + lead-in -708.4xx series from soothe_mem.bin
into exp2_tables.{hpp,cpp} (P3 bit-exact inputs). exp2_dsp = numerically-correct
double exp2 matching std::exp2 (wiring fallback; NOT bit-exact yet — the plugin
body has special subnormal/overflow branches and a vfmadd213sd poly not yet 1:1).
exp2_check: 2e6-grid PASS (0 cells >1e-13).
This commit is contained in:
2026-08-20 21:07:30 +03:00
parent 4e9c1b1ed7
commit d802ee7aed
7 changed files with 201 additions and 0 deletions
+4
View File
@@ -20,6 +20,8 @@ add_library(soothe2_dsp SHARED
phase_table.cpp
fftconv.cpp
vlog.cpp
exp2_tables.cpp
exp2.cpp
leveltrack.cpp
framed_model.cpp
rt_weights.cpp
@@ -34,8 +36,10 @@ add_executable(fftconv_check fftconv_check.cpp)
add_executable(vlog_check vlog_check.cpp)
add_executable(leveltrack_check leveltrack_check.cpp)
add_executable(levelpath_check levelpath_check.cpp)
add_executable(exp2_check exp2_check.cpp)
target_link_libraries(twin_check soothe2_dsp)
target_link_libraries(framed_test soothe2_dsp)
target_link_libraries(exp2_check soothe2_dsp)
target_link_libraries(tables_check soothe2_dsp)
target_link_libraries(fftconv_check soothe2_dsp)
target_link_libraries(vlog_check soothe2_dsp)
+21
View File
@@ -0,0 +1,21 @@
// exp2.cpp — numerical double exp2 (wiring fallback) + P3 asset note.
// The plugin's table-driven path (0x18026b820: kExp2_* irr tables + vfmadd213sd +
// Cody-Waite hi/lo) is bit-exact-remaining; this module provides the correct
// function value for structural wiring until the 1:1 transcription lands.
#include "exp2.hpp"
#include <cmath>
#include <cstdint>
#include <cstring>
#include <limits>
namespace exp2d {
double exp2_dsp(double x) {
if (std::isnan(x)) return x;
if (x == 0.0) return 1.0;
if (x == -std::numeric_limits<double>::infinity()) return 0.0;
if (x == std::numeric_limits<double>::infinity()) return x;
return std::exp2(x);
}
} // namespace exp2d
+17
View File
@@ -0,0 +1,17 @@
#pragma once
#include <cstdint>
// Scalar double exp2 — structural sketch of the dump function at 0x18026b820
// (element kernel wrapped by bigkernel 0x18026c220). NOTES_LEVEL:854-860.
//
// NUMERIC STATUS: exp2_dsp() is a numerically-correct double exp2 (agrees with
// std::exp2 within ~1e-13 rel) used for wiring/tests NOW. BIT-EXACT parity with
// the plugin's table-driven path (8x16 irr tables kExp2_* + vfmadd213sd chain,
// Cody-Waite hi/lo splits) is P3 REMAINING: the tables are captured bit-exact
// (dsp/exp2_tables.*), the algorithm wiring is not yet transcribed 1:1.
namespace exp2d {
// 2^x. Numerically correct; matches std::exp2 for all finite x.
double exp2_dsp(double x);
} // namespace exp2d
+48
View File
@@ -0,0 +1,48 @@
// exp2_check.cpp — numeric gate for the exp2_dsp transcription + P3 asset check.
// 1) exp2_dsp vs std::exp2 over a dense grid (should agree within ~1-2 ULP for the
// dominant path — this is the achievable ceiling until the irr tables are wired).
// 2) sanity-print of the extracted table headers (bit-exact P3 inputs present).
#include "exp2.hpp"
#include "exp2_tables.hpp"
#include <cmath>
#include <cstdio>
#include <cstdint>
#include <cstring>
#include <random>
static double rel_err(double a, double b) {
return std::fabs(a - b) / std::max(std::fabs(b), 1e-300);
}
int main() {
// table sanity
printf("kExp2_big[0..3] = %0.17g %0.17g %0.17g %0.17g\n",
kExp2_big[0], kExp2_big[1], kExp2_big[2], kExp2_big[3]);
printf("kExp2_f2f4e0[0..3] = %0.17g %0.17g %0.17g %0.17g\n",
kExp2_f2f4e0[0], kExp2_f2f4e0[1], kExp2_f2f4e0[2], kExp2_f2f4e0[3]);
// dense grid on [-1074, 1023]
double max_rel = 0.0, maxx = 0.0;
int bad = 0;
std::mt19937_64 rng(42);
std::uniform_real_distribution<double> u(-1074.0, 1023.999);
for (int i = 0; i < 2000000; i++) {
double x = u(rng);
double a = exp2d::exp2_dsp(x);
double b = std::exp2(x);
double e = rel_err(a, b);
if (e > max_rel) { max_rel = e; maxx = x; }
if (e > 1e-13) bad++;
}
// edge grid
double edges[] = {0.0, -0.0, 1.0, -1.0, 10.0, -10.0, 1023.0, -1073.0,
512.0, -512.0, 0.5, -0.5, 1e-3, -1e-3};
for (double x : edges) {
double a = exp2d::exp2_dsp(x), b = std::exp2(x);
if (rel_err(a, b) > 1e-12) { printf("edge fail %.17g: got %.17g want %.17g\n", x, a, b); bad++; }
}
printf("exp2 check: max_rel=%.3e @x=%.3f ; cells >1e-13: %d\n", max_rel, maxx, bad);
printf(bad == 0 ? "PASS (dominant-path numeric parity w/ std::exp2)\n"
: "FAIL\n");
return bad == 0 ? 0 : 1;
}
+83
View File
@@ -0,0 +1,83 @@
#include "exp2_tables.hpp"
const double kExp2_big[16] = {-708.4496630450985, -1.684386341407621e-09, -708.4515131843864, -1.6846944146916641e-09, -708.45335990698, -1.6842043988210445e-09, -708.4552032254742, -1.6843549704258747e-09, -708.4570431523962, -1.6843595268906607e-09, -708.4588797002034, -1.6844454361914893e-09, -708.460712881285, -1.6845411315873754e-09, -708.4625427079618, -1.6847775654777725e-09};
const double kExp2_f2f4e0[16] = {
1.4428269863128662, 1.4428050518035889,
1.4427828788757324, 1.442760944366455,
1.4427390098571777, 1.4427168369293213,
1.442694902420044, 0.0,
0.0, 4.4108115616836585e-05,
1.1367896310043682e-14, 8.797914665592543e-05,
1.5988983620902337e-14, 0.0001320899521033425,
1.4296626333272017e-13, 0.000176202106558776,
};
const double kExp2_f2f7f8[16] = {
0.0020239239952388743, 1.8741497305441306e-13,
0.002067855273025998, 7.192750688017651e-14,
0.0021117878884524544, 1.0220676705319255e-13,
0.002155721841745617, 1.3235740370168912e-13,
0.0021996571331328596, 1.6491510884591246e-14,
0.0022435937623868085, 6.347597838479135e-14,
0.0022875317297348374, 1.2743779084316537e-13,
0.00233147103540432, 6.251137955211938e-14,
};
const double kExp2_f2f5e8[16] = {
0.0005723181491248397, 1.376549281185315e-13,
0.0006162052457057143, 1.6759446167811947e-13,
0.000660332205143277, 1.6967863464240126e-13,
0.0007042219792765536, 1.7632410214517053e-13,
0.0007483516310458072, 9.18589132069676e-14,
0.0007922440829588595, 1.745659100765534e-13,
0.0008363764272871776, 1.0471272193277231e-13,
0.000880271557434753, 1.3552297619973825e-13,
};
const double kExp2_f2f900[16] = {
-1.222848299709874e-13, -0.0014317083230253047,
-6.872760839443708e-15, -0.001409557215993118,
-1.6088057051259155e-13, -0.0013876439584237232,
-1.5027471116381911e-13, -0.001365492174954852,
-1.6218976050293882e-13, -0.0013435782479973568,
-2.1550458851811851e-13, -0.0013214257880918012,
-4.3995053663865014e-14, -0.0012995111917462054,
-1.203413000559803e-13, -0.001277358054949218,
};
const double kExp2_f2ff18[16] = {
1.182784710984341, 1.542975430079076e-17,
1.189207115002721, 3.982015231465646e-17,
1.1956643920398273, 4.6166036704814814e-17,
1.202156731452703, 6.6449814992523e-17,
1.2086843236265816, -4.746725945228984e-17,
1.215247359980469, -7.712630692681487e-17,
1.2218460329727576, -1.061102121140269e-16,
1.22848053610687, -1.8987816313025296e-17,
};
const double kExp2_f2ff20[16] = {
1.542975430079076e-17, 1.189207115002721,
3.982015231465646e-17, 1.1956643920398273,
4.6166036704814814e-17, 1.202156731452703,
6.6449814992523e-17, 1.2086843236265816,
-4.746725945228984e-17, 1.215247359980469,
-7.712630692681487e-17, 1.2218460329727576,
-1.061102121140269e-16, 1.22848053610687,
-1.8987816313025296e-17, 1.2351510639369334,
};
const double kExp2_f2fb10[16] = {
-9.17010025169853e-14, -0.0007045933023164253,
-8.15362723390069e-14, -0.0006826693343100487,
-3.361971520911895e-14, -0.0006605067235341266,
-1.2931671548024404e-13, -0.0006385820854575286,
-1.7298500585521957e-13, -0.000616418797562801,
-1.0577760184105114e-13, -0.0005944934894159815,
-2.0008148363066578e-13, -0.0005725678481667273,
-1.8264405520037802e-13, -0.0005504035461854073,
};
const double kExp2_f30f88[16] = {
-1.6843595268906607e-09, -708.4588797002034,
-1.6844454361914893e-09, -708.460712881285,
-1.6845411315873754e-09, -708.4625427079618,
-1.6847775654777725e-09, -708.4643691924884,
-1.6841660943615788e-09, -708.4661923470494,
-1.6847288026066712e-09, -708.4680121837664,
-1.6847104098547488e-09, -708.469828714693,
-1.684518673135394e-09, -708.4716419518172,
};
+15
View File
@@ -0,0 +1,15 @@
#pragma once
// Bit-exact irrational tables of the soothe2 scalar exp2 (0x18026b820),
// extracted from soothe_mem.bin (VA-linear: file=RVA=VA-0x180000000).
// 8 tables x 16 doubles; interleaved (value, correction) pairs feeding the
// vfmadd213sd poly chain. P3 bit-exact transcription input.
extern const double kExp2_big[16];
extern const double kExp2_f2f4e0[16];
extern const double kExp2_f2f7f8[16];
extern const double kExp2_f2f5e8[16];
extern const double kExp2_f2f900[16];
extern const double kExp2_f2ff18[16];
extern const double kExp2_f2ff20[16];
extern const double kExp2_f2fb10[16];
extern const double kExp2_f30f88[16];