From c01ff025bb7858879c4f47d50fe7df5dd6c13bb2 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 4 Oct 2026 12:12:36 +0200 Subject: [PATCH] Gate test: restore the affine gate's detail ball and add FogField.InsideFog to the field list [affine-gate-loses-fog-culls] [interval-gate-detail-unpinned] Deleting the affine gate's detail ball (51a4034c) gave up 6 of 5933 provable culls inside the fog (first: (b) inside the fog [affine]); the gate never gives up a provable cull, and a 1.4% probe saving does not buy breaking that. The detail ball is back in the affine gate, and the gate test now includes the fog interior, the only field where the interval gate's detail ball decides, so saturating either gate's detail ball fails the test. Co-Authored-By: Claude Sonnet 5.5 --- .../cultmath/tests/CultMath.Tests/NoiseBoundTests.cs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/cultmath/tests/CultMath.Tests/NoiseBoundTests.cs b/packages/cultmath/tests/CultMath.Tests/NoiseBoundTests.cs index 4075e953..78a3b795 100644 --- a/packages/cultmath/tests/CultMath.Tests/NoiseBoundTests.cs +++ b/packages/cultmath/tests/CultMath.Tests/NoiseBoundTests.cs @@ -938,7 +938,7 @@ public sealed class NoiseBoundTests /// empty (its upper density 0) must be proved empty gated too. A gate that errs toward giving up /// (the reach inflated, a gradient or Hessian term overstated) loosens the bound exactly there and /// costs only culling, which no enclosure test sees; a gate that errs the other way only costs probes, - /// which the cost contract (IntervalSkipHalvesEvaluations) sees. Over seeded slices of both wells at + /// which the cost contract (IntervalSkipHalvesEvaluations) sees. Over seeded slices of both wells and the fog interior at /// warp 0 and the Aetheria warp, N = 8, in both modes, no slice the ungated bound proves empty is /// left open by the gated one, and at least 200 are proved empty. /// @@ -949,7 +949,7 @@ public sealed class NoiseBoundTests var (proved, lost) = (0, new List()); foreach (var mode in new[] { BoundMode.Interval, BoundMode.Affine }) foreach (var warp in new[] { 0.0f, FogField.AetheriaWarp }) - foreach (var field in new[] { FogField.DeepWell(warp, mode), FogField.Wells(warp, mode) }) + foreach (var field in new[] { FogField.DeepWell(warp, mode), FogField.Wells(warp, mode), FogField.InsideFog(warp, mode) }) for (var t = 0; t < 1500; t++) { var tile = field.DrawTile(random, 8); @@ -1796,11 +1796,6 @@ public sealed class NoiseBoundTests return low ? new float2(-1.0f, min(-1.0f + e, 1.0f)) : new float2(max(1.0f - e, -1.0f), 1.0f); } - // The affine gate takes the detail octave at its full range: its best-case ball never decided a probe - // on the gate test's slices or the deep wells, and a gate that skips it proves the same slices with - // fewer probes. (The interval gate keeps its detail ball: inside the fog, row (b), it decides.) - private static readonly float2 DetailRange = new(-0.5f, 0.5f); - private static float2 Clip(float2 range) => new(max(range.x, -1.0f), min(range.y, 1.0f)); /// @@ -1823,7 +1818,7 @@ public sealed class NoiseBoundTests foreach (var low in new[] { true, false }) { var coverage = Noise.CoverageBound(BestForm(slice.Coverage0.Reach, low), BestForm(slice.Coverage1.Reach, low), tile.Time); - provable |= Compose(s, fade, iv_add(coverage, DetailRange)).y <= 0.0f; + provable |= Compose(s, fade, iv_add(coverage, iv_scale(BestForm(slice.Detail.Reach, low), 0.5f))).y <= 0.0f; } if (!provable)