From 97de733f1be45c608a6ee6fda70afffaade273c8 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Wed, 14 Oct 2026 06:53:08 +0200 Subject: [PATCH] cultmath: pin SNOISE_THIRD (536.9152) and re-pin SNOISE_HESSIAN (55.642143) on the analytic Hessian MeasureThird on the tied kernel: refined 488.1047, x 1.10 = 536.9152, witness (-168.3755, -3.8205261, -109.16948). MeasureHessian with the analytic Hessian: refined 50.58377, x 1.10 = 55.642143, witness (-13.7920685, -9.672134, 61.563934); the central-difference value 56.050385 carried the quotient's roundoff. README bullet for the span primitives. CultMath.glsl and the fixture are not yet regenerated. Co-Authored-By: Claude Opus 5.5 --- packages/cultmath/README.md | 9 +++++++++ packages/cultmath/shaders/CultMath.Affine.hlsl | 4 ++-- packages/cultmath/src/CultMath/math.Affine.cs | 9 +++++---- packages/cultmath/src/CultMath/math.Span.cs | 5 +++-- .../cultmath/tests/CultMath.Tests/NoiseBoundTests.cs | 4 ++-- .../org.gamecult.cultmath/Shaders/CultMath.Affine.hlsl | 4 ++-- 6 files changed, 23 insertions(+), 12 deletions(-) diff --git a/packages/cultmath/README.md b/packages/cultmath/README.md index 24662be7..1a26571b 100644 --- a/packages/cultmath/README.md +++ b/packages/cultmath/README.md @@ -78,6 +78,15 @@ shader semantics. then `CultMath.Phacelle.glsl` only if it calls `cultmath_phacelle` and `CultMath.Cycles.glsl` only if it calls a `cultmath_cycles_` function, then its own shader source. +- Span primitives (`math.Span.cs`, `cultmath_*` in HLSL and GLSL): `snoise_hessian`, + the analytic Hessian of `snoise(float3)` on the same lattice, hash and tie order as + `snoise_grad` (a symmetric `float3x3`; GLSL `mat3`), and `integral_clamp_linear(a, + b, lo, hi, t0, t1)`, the closed-form integral over `[t0, t1]` of `clamp(a + b t, + lo, hi)`. Three measured bounds describe `snoise`: `SNOISE_LIPSCHITZ` (gradient + length, `NoiseBoundTests.MeasureLipschitz`), `SNOISE_HESSIAN` (Hessian spectral + norm, `MeasureHessian`) and `SNOISE_THIRD` (third-derivative operator norm, + `MeasureThird`); each is 1.10 times a seeded maximum refined by ascent, and a + fast test pins it. They are empirical with a margin, not proofs. - `Voronoi.SampleTones`, a C# batch surface that calls the Rust `cultmath-core` native kernel when `cultmath_core` is available and falls back to the managed parity path otherwise. diff --git a/packages/cultmath/shaders/CultMath.Affine.hlsl b/packages/cultmath/shaders/CultMath.Affine.hlsl index 8727081e..09616940 100644 --- a/packages/cultmath/shaders/CultMath.Affine.hlsl +++ b/packages/cultmath/shaders/CultMath.Affine.hlsl @@ -10,11 +10,11 @@ // An upper bound on the spectral norm of the Hessian of cultmath_snoise(float3); provenance in // math.Affine.cs (SNOISE_HESSIAN). -static const float CULTMATH_SNOISE_HESSIAN = 56.050385; +static const float CULTMATH_SNOISE_HESSIAN = 55.642143; // An upper bound on the operator norm of the third-derivative tensor of cultmath_snoise(float3), the // next order after CULTMATH_SNOISE_HESSIAN; provenance in math.Span.cs (SNOISE_THIRD). -static const float CULTMATH_SNOISE_THIRD = 1.0; +static const float CULTMATH_SNOISE_THIRD = 536.9152; float3 cultmath_af_point(float value) { return float3(value, 0.0, 0.0); } float3 cultmath_af_symbol(float x0, float a) { return float3(x0, a, 0.0); } diff --git a/packages/cultmath/src/CultMath/math.Affine.cs b/packages/cultmath/src/CultMath/math.Affine.cs index 8c4ce94a..acb73251 100644 --- a/packages/cultmath/src/CultMath/math.Affine.cs +++ b/packages/cultmath/src/CultMath/math.Affine.cs @@ -21,9 +21,10 @@ public static partial class math // plain function of float values, so it mirrors into the HLSL common subset. // An upper bound on the spectral norm of the Hessian of snoise(float3). Provenance: - // NoiseBoundTests.MeasureHessian (slow, explicit) takes the largest Hessian norm (central - // differences of snoise_grad, largest absolute eigenvalue) over 1e6 seeded points, refines the 1e4 - // largest by ascent, and multiplies the refined maximum by 1.10; + // NoiseBoundTests.MeasureHessian (slow, explicit) takes the largest Hessian norm (snoise_hessian, + // largest absolute eigenvalue) over 1e6 seeded points, refines the 1e4 largest by ascent, and + // multiplies the refined maximum by 1.10 (50.5838 measured, 55.642143 pinned; the central + // differences of snoise_grad it replaced read 50.955 here, their roundoff at h = 1e-3); // NoiseBoundTests.HessianConstantPinsSampledCurvature pins this value against a fast re-measure and // the ascent from MeasureHessian's witness. Empirical with a margin, not a proof. Random balls // cannot see a constant 20% low, so the defence is those two curvature tests plus @@ -32,7 +33,7 @@ public static partial class math // whole 289^3 hash period found a realised maximum of 50.58, and bounding each corner's gradient // independently over every hash configuration gives 52.22 (Soul pass s1). A change to the snoise // kernel must re-run MeasureHessian and re-pin it. SNOISE_THIRD (math.Span.cs) is the next-order pin. - public const float SNOISE_HESSIAN = 56.050385f; + public const float SNOISE_HESSIAN = 55.642143f; /// The point form (x, 0, 0): the value x at every eps. Exact. public static float3 af_point(float value) => new(value, 0.0f, 0.0f); diff --git a/packages/cultmath/src/CultMath/math.Span.cs b/packages/cultmath/src/CultMath/math.Span.cs index 4adc1139..364bd04b 100644 --- a/packages/cultmath/src/CultMath/math.Span.cs +++ b/packages/cultmath/src/CultMath/math.Span.cs @@ -10,9 +10,10 @@ public static partial class math // refines the 1e4 largest by ascent over the point, and multiplies the maximum by 1.10; it prints // the witness start. NoiseBoundTests.ThirdConstantPinsSampled pins the value against a fast // re-measure and the ascent from that witness. Measured on the tied kernel (snoise_grad's order), - // not on any pre-tie splice. Empirical with a margin, not a proof. A change to the snoise kernel + // not on any pre-tie splice. Measured 488.1047 (a dense sweep of 20,000 directions at the witness + // found 99.9998% of the tensor norm there). Empirical with a margin, not a proof. A change to the snoise kernel // must re-run MeasureThird and re-pin it. - public const float SNOISE_THIRD = 1.0f; + public const float SNOISE_THIRD = 536.9152f; // Analytic Hessian of snoise(float3): the symmetric matrix of second partial derivatives, same // lattice, hash and tie order as snoise_grad, whose kernel it differentiates once more. Every local diff --git a/packages/cultmath/tests/CultMath.Tests/NoiseBoundTests.cs b/packages/cultmath/tests/CultMath.Tests/NoiseBoundTests.cs index f0e6d084..312770ba 100644 --- a/packages/cultmath/tests/CultMath.Tests/NoiseBoundTests.cs +++ b/packages/cultmath/tests/CultMath.Tests/NoiseBoundTests.cs @@ -605,7 +605,7 @@ public sealed class NoiseBoundTests } // The start MeasureHessian printed as its witness. - private static readonly float3 HessianWitness = new(-245.19885f, -53.01323f, -91.47363f); + private static readonly float3 HessianWitness = new(-13.7920685f, -9.672134f, 61.563934f); /// /// Pins SNOISE_HESSIAN: no Hessian norm over 1e5 seeded points exceeds it, and the ascent from @@ -780,7 +780,7 @@ public sealed class NoiseBoundTests } // The start MeasureThird printed as its witness. - private static readonly float3 ThirdWitness = new(0.0f, 0.0f, 0.0f); + private static readonly float3 ThirdWitness = new(-168.3755f, -3.8205261f, -109.16948f); /// /// Pins SNOISE_THIRD: no third-derivative norm over 1e5 seeded points exceeds it, and the ascent from diff --git a/packages/cultmath/unity/org.gamecult.cultmath/Shaders/CultMath.Affine.hlsl b/packages/cultmath/unity/org.gamecult.cultmath/Shaders/CultMath.Affine.hlsl index 8727081e..09616940 100644 --- a/packages/cultmath/unity/org.gamecult.cultmath/Shaders/CultMath.Affine.hlsl +++ b/packages/cultmath/unity/org.gamecult.cultmath/Shaders/CultMath.Affine.hlsl @@ -10,11 +10,11 @@ // An upper bound on the spectral norm of the Hessian of cultmath_snoise(float3); provenance in // math.Affine.cs (SNOISE_HESSIAN). -static const float CULTMATH_SNOISE_HESSIAN = 56.050385; +static const float CULTMATH_SNOISE_HESSIAN = 55.642143; // An upper bound on the operator norm of the third-derivative tensor of cultmath_snoise(float3), the // next order after CULTMATH_SNOISE_HESSIAN; provenance in math.Span.cs (SNOISE_THIRD). -static const float CULTMATH_SNOISE_THIRD = 1.0; +static const float CULTMATH_SNOISE_THIRD = 536.9152; float3 cultmath_af_point(float value) { return float3(value, 0.0, 0.0); } float3 cultmath_af_symbol(float x0, float a) { return float3(x0, a, 0.0); }