From 3ac7250aa92569caefee45869c0c21174578936d Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sat, 3 Oct 2026 11:42:57 +0200 Subject: [PATCH] CultMath intervals r3: the analytic body, LOD-far, one shipped void, (c) against its ceiling MarchTile reports a body start where the gated bound over the rest of the grid is a positive point and appends the rest unprobed; MarchLod takes one closed-form Beer-Lambert step there. AnalyticBodyMatchesFineMarch pins it against the ungated field and the fixed-step product, and pins that no (a)-(d) tile reports a body. VoidField takes a focal length; LOD-far (Rh 4000, S 50, f 467) joins the enclosure test, which now asserts it sampled weights in (0, 1) and at 0. The void grid ends at Rc + 6/K. The doc derives the one shipped void (198, 50) and records the [w(z1), 1] deviation. (c) is held to 0.90 of its probe-free ceiling. Co-Authored-By: Claude Opus 5.5 --- .../tests/CultMath.Tests/NoiseBoundTests.cs | 276 +++++++++++++++--- 1 file changed, 231 insertions(+), 45 deletions(-) diff --git a/packages/cultmath/tests/CultMath.Tests/NoiseBoundTests.cs b/packages/cultmath/tests/CultMath.Tests/NoiseBoundTests.cs index 30ec1e95..301979f5 100644 --- a/packages/cultmath/tests/CultMath.Tests/NoiseBoundTests.cs +++ b/packages/cultmath/tests/CultMath.Tests/NoiseBoundTests.cs @@ -250,11 +250,12 @@ public sealed class NoiseBoundTests /// /// intervals-enclose for the composition the site and Aetheria use: over 2,000 seeded tile slices - /// (Aetheria's wells, inside the fog, the void at every grid point; N in {1, 4, 8, 16}; a camera drawn - /// per tile) the bound composed from the envelope over the slice's box, its fade, and the noise ball - /// enlarged by the warp encloses the density at 64 points of the slice, each sampled through the field's - /// own warp, with no tolerance. The void's footprint-truncated density (octave weights) is checked - /// against the same bound. + /// (Aetheria's wells, inside the fog, the void at every grid point, the shipped void and LOD-far; + /// N in {1, 4, 8, 16}; a camera drawn per tile) the bound composed from the envelope over the slice's + /// box, its fade, and the noise ball enlarged by the warp encloses the density at 64 points of the + /// slice, each sampled through the field's own warp, with no tolerance. The void's footprint-truncated density (octave weights) is checked + /// against the same bound; a quarter of the slices are LOD-far's, where the weights are strictly + /// between 0 and 1 and at 0, and the test asserts it sampled both. /// [Fact] public void EnvelopeBoundEnclosesDensity() @@ -266,10 +267,13 @@ public sealed class NoiseBoundTests foreach (var offset in VoidField.CameraOffsets) foreach (var ramp in VoidField.Ramps) fields.Add(new VoidField(rh, ramp, offset.Fraction, offset.Name)); + fields.Add(VoidField.Shipped()); + fields.Add(VoidField.LodFar()); var counts = new Counts(); + var (partial, zero) = (0, 0); for (var t = 0; t < 2000; t++) { - var field = t % 2 == 0 ? fields[(t / 2) % 2] : fields[2 + random.Next(fields.Count - 2)]; + var field = t % 2 == 0 ? fields[(t / 2) % 2] : t % 4 == 1 ? fields[^1] : fields[2 + random.Next(fields.Count - 2)]; var tile = field.DrawTile(random, sizes[random.Next(sizes.Length)]); var near = field.Grid[0]; var far = field.Grid[^1]; @@ -282,13 +286,20 @@ public sealed class NoiseBoundTests var z = i < 2 ? (i == 0 ? z0 : z1) : Uniform(random, z0, z1); var density = field.Density(tile, m, z, lod: false, counts); Assert.True(Inside(density, bound), $"{field.Name}: bound {bound} over [{z0:R}, {z1:R}] misses density {density:R} at slope {m}, depth {z:R}"); - if (field is VoidField) + if (field is VoidField voidField) { + var (wc, wd) = voidField.Weights(z); + partial += (wc > 0.0f && wc < 1.0f) || (wd > 0.0f && wd < 1.0f) ? 1 : 0; + zero += wd == 0.0f ? 1 : 0; var truncated = field.Density(tile, m, z, lod: true, counts); Assert.True(Inside(truncated, bound), $"{field.Name}: bound {bound} misses the truncated density {truncated:R} at slope {m}, depth {z:R}"); } } } + + // The truncated check is not vacuous: some samples carry an octave weight strictly inside (0, 1) + // and some a fine weight of 0 (LOD-far reaches both). + Assert.True(partial > 0 && zero > 0, $"octave weights in (0, 1) at {partial} samples and fine weight 0 at {zero}"); } // ---- The Lipschitz constant ---- @@ -899,19 +910,32 @@ public sealed class NoiseBoundTests } /// - /// (e) The void, the shipped scene: a cloud volume everywhere, carved by one negative pseudo-Gaussian - /// sphere. Authored knobs: hollow radius Rh (density exactly 0 inside) and ramp width S (the density - /// rises to full over [Rh, Rh + S]). The brush (1 - (d / Rc)^2)^e with CARVE = 1.5 reaches full at Rc, - /// so Rc = Rh + S, and Rh = Rc sqrt(1 - CARVE^(-1/e)) gives e = -ln CARVE / ln(1 - (Rh / Rc)^2): - /// density = K max(0, 1 - CARVE (1 - (d' / Rc)^2)^e), exactly 0 for d' <= Rh and K for d' >= Rc, - /// K = 1/30. The noise displaces the wall: fade = smoothstep(Rh - S, Rh, d), d' = d + A fade n(warp(p)), - /// A = 20, F0 = 0.01 (wavelengths 100 and 25), warp D = 10. The sun orbits the origin at radius 175 with - /// period 72 s and rests on the hollow's bottom (c_v = sun + (0, Rh - 12.5, 0)); the camera looks at - /// sun + (0, 60, 0) and, shipped, sits 120 behind the sun along the orbit tangent and 45 above it. The - /// footprint-truncated field (lod) weights octave i by w_i(z) = 1 - smoothstep(l_i / 2m, l_i / m, - /// z theta), m = 4, theta = 1 / f; the bound takes each weight over [w_i(z1), 1], which holds both the - /// truncated and the full field. The dense grid is the fixed-step reference's: cells of min(10, S / 4) - /// out to |camera - c_v| + Rc + 5 / K, past where every ray has gone opaque. + /// (e) The void: a cloud volume everywhere, carved by one negative pseudo-Gaussian sphere. Authored + /// knobs: hollow radius Rh (density exactly 0 inside) and ramp width S (the density rises to full over + /// [Rh, Rh + S]); everything else is derived from them. The brush (1 - (d / Rc)^2)^e with CARVE = 1.5 + /// reaches full at Rc, so Rc = Rh + S, and Rh = Rc sqrt(1 - CARVE^(-1/e)) gives + /// e = -ln CARVE / ln(1 - (Rh / Rc)^2): density = K max(0, 1 - CARVE (1 - (d' / Rc)^2)^e), exactly 0 for + /// d' <= Rh and K for d' >= Rc, K = 1/30. The noise displaces the wall: fade = + /// smoothstep(Rh - S, Rh, d), d' = d + A fade n(warp(p)), A = 20, F0 = 0.01 (wavelengths 100 and 25), + /// warp D = 10. The sun orbits the origin at radius 175 with period 72 s and rests on the hollow's + /// bottom (c_v = sun + (0, Rh - 12.5, 0)); the camera looks at sun + (0, 60, 0) and, shipped, sits 120 + /// behind the sun along the orbit tangent and 45 above it. + /// + /// The one shipped void (ruling operator-shipped-void) is Shipped(): (Rh, S) = (198, 50), so Rc = 248 + /// and e = -ln 1.5 / ln(1 - (198 / 248)^2), which the constructor derives; no other void is shipped. + /// + /// The footprint-truncated field (lod) weights octave i by w_i(z) = 1 - smoothstep(l_i / 2m, l_i / m, + /// z theta), m = 4, theta = 1 / f. Deviation from the spec's [w_i(z1), w_i(z0)]: the bound takes each + /// weight over [w_i(z1), 1], because one Bound serves the full field (w = 1) and the truncated one + /// (w in [w_i(z1), w_i(z0)], w decreasing in z); [w_i(z1), 1] contains both and iv_mul is monotone in + /// its interval argument, so the composed interval encloses both fields. The slack is only in far + /// tiles, whose step the footprint already sets. At f = 935 every weight is 1 inside every grid; + /// LodFar() (f = 467) reaches weights in (0, 1) and at 0. + /// + /// The dense grid is the fixed-step reference's: cells of min(10, S / 4) out to + /// |camera - c_v| + Rc + 6 / K. The density is provably K only from d >= Rc + A 1.5 (the free noise + /// interval), so 6 / K leaves at least 4.9 of optical depth past it and every ray goes opaque before + /// the grid ends. /// internal sealed class VoidField : Scenario { @@ -940,8 +964,9 @@ public sealed class NoiseBoundTests private float Theta => 1.0f / Focal; [System.Diagnostics.CodeAnalysis.SetsRequiredMembers] - public VoidField(float hollowRadius, float ramp, float cameraFraction, string camera) + public VoidField(float hollowRadius, float ramp, float cameraFraction, string camera, float focal = 935.0f) { + Focal = focal; HollowRadius = hollowRadius; Ramp = ramp; CarveRadius = hollowRadius + ramp; @@ -949,13 +974,23 @@ public sealed class NoiseBoundTests RampStart = hollowRadius - ramp; FixedStep = min(10.0f, ramp / 4.0f); CameraFraction = cameraFraction; - Name = $"(e) void Rh={hollowRadius:R} camera={camera} S={ramp:R}"; + Name = $"(e) void Rh={hollowRadius:R} camera={camera} S={ramp:R}" + (focal == 935.0f ? "" : $" f={focal:R}"); var reach = cameraFraction < 0.0f ? length(new float2(120.0f, 45.0f - (hollowRadius - 12.5f))) : cameraFraction * hollowRadius; - Grid = Cells(FixedStep, reach + CarveRadius + 5.0f / K); + Grid = Cells(FixedStep, reach + CarveRadius + 6.0f / K); } public static VoidField Shipped() => new(198.0f, 50.0f, -1.0f, "shipped"); + /// + /// The configuration that reaches the octave weights: Rh = 4000, S = 50, the low camera, f = 467 + /// (1080 rows at a 98 degree vertical field of view). The fine weight is below 1 past z = 1460 and 0 + /// past 2920, the coarse below 1 past 5840, and the grid reaches about 7990. Printed, not asserted. + /// + public static VoidField LodFar() => new(4000.0f, 50.0f, 0.94f, "low", 467.0f); + + /// The coarse and fine octave weights at depth z (1 for the full field). + public (float Coarse, float Fine) Weights(float z) => (Weight(CoarseWavelength, z * Theta), Weight(FineWavelength, z * Theta)); + private sealed class VoidTile : Tile { public float3 Cavity; // c_v in the camera frame @@ -1048,6 +1083,26 @@ public sealed class NoiseBoundTests return Profile(d + fade * (coverage + detail) * Amplitude); } + /// + /// The field with no envelope gate: both noise terms always evaluated, the profile applied to the + /// displaced distance. Density's shortcuts go through Compose; this does not, so it is the value a + /// wrong Compose cannot also corrupt. Not counted. + /// + public float Exact(Tile t, float2 slope, float z, bool lod) + { + var tile = (VoidTile)t; + var counts = new Counts(); + var (x, y) = (slope.x * z, slope.y * z); + var (dx, dy, dz) = (x - tile.Cavity.x, y - tile.Cavity.y, z - tile.Cavity.z); + var d = sqrt(dx * dx + dy * dy + dz * dz); + var fade = smoothstep(RampStart, HollowRadius, d); + var p = tile.World(new float3(x, y, z)); + var wc = lod ? Weight(CoarseWavelength, z * Theta) : 1.0f; + var wd = lod ? Weight(FineWavelength, z * Theta) : 1.0f; + var n = Noise.Coverage(p, tile.Time, counts) * wc + Noise.Detail(p, counts) * 0.5f * wd; + return Profile(d + fade * n * Amplitude); + } + public override float2 Bound(Tile t, float z0, float z1, bool gated, Counts counts) { var tile = (VoidTile)t; @@ -1092,8 +1147,15 @@ public sealed class NoiseBoundTests /// doubles the next range; otherwise a range of more than one cell halves, and a single cell is dense. /// It starts with the whole grid, runs to the grid's end (a pre-pass knows no ray's transmittance) and /// yields the dense cells in order. Its probes are counted once per tile. + /// + /// The body (ruling operator-analytic-wall-body): when a single dense cell's own bound is a positive + /// point (the cell is provably constant), one more probe over [grid[j], grid end]; if that is a + /// positive point too, every point of every ray of the tile over the rest of the grid has exactly that + /// density, so BodyStart = j, BodyDensity = its value, and every remaining cell is appended dense + /// without probing (adding cells is always sound, so the mask keeps its meaning). BodyStart is -1 when + /// no body is proven. /// - private static List MarchTile(Scenario field, Tile tile, Counts probes) + private static (List Dense, int BodyStart, float BodyDensity) MarchTile(Scenario field, Tile tile, Counts probes) { var grid = field.Grid; var cells = grid.Length - 1; @@ -1103,7 +1165,8 @@ public sealed class NoiseBoundTests while (j < cells) { var end = Math.Min(j + span, cells); - if (field.Bound(tile, grid[j], grid[end], gated: true, probes).y <= 0.0f) + var bound = field.Bound(tile, grid[j], grid[end], gated: true, probes); + if (bound.y <= 0.0f) { j = end; span = Math.Min(span * 2, cells); @@ -1114,19 +1177,35 @@ public sealed class NoiseBoundTests } else { + if (bound.x == bound.y && bound.x > 0.0f) + { + var rest = field.Bound(tile, grid[j], grid[cells], gated: true, probes); + if (rest.x == rest.y && rest.x > 0.0f) + { + dense.AddRange(Enumerable.Range(j, cells - j)); + return (dense, j, rest.x); + } + } + dense.Add(j); j++; } } - return dense; + return (dense, -1, 0.0f); } + // The body's one closed-form Beer-Lambert step from z to the grid's end, at the density the field's + // pointwise envelope gives at z (one envelope evaluation; no probe in the main pass). + private static float BodyFactor(Scenario field, Tile tile, float2 slope, float z, bool lod, Counts counts) => + exp(-(field.Density(tile, slope, z, lod, counts) * field.Extinction) * ((field.Grid[^1] - z) * sqrt(slope.x * slope.x + slope.y * slope.y + 1.0f))); + // The footprint-aware march, the void's shipped one: steps of LodStep(z) inside the unmasked runs only, - // octave weights applied. - private static float MarchLod(VoidField field, Tile tile, float2 slope, List cells, Counts counts, ref long steps) + // octave weights applied; at the body's start, one analytic step to the grid's end, and stop. + private static float MarchLod(VoidField field, Tile tile, float2 slope, List cells, int bodyStart, Counts counts, ref long steps, ref long bodySteps) { var grid = field.Grid; + var body = bodyStart >= 0 ? grid[bodyStart] : float.PositiveInfinity; var transmittance = 1.0f; var k = 0; while (k < cells.Count && transmittance >= 0.02f) @@ -1137,7 +1216,15 @@ public sealed class NoiseBoundTests end++; while (z < grid[end] && transmittance >= 0.02f) { - var next = min(z + field.LodStep(z), grid[end]); + if (z >= body) + { + transmittance *= BodyFactor(field, tile, slope, z, lod: true, counts); + steps++; + bodySteps++; + return transmittance; + } + + var next = min(min(z + field.LodStep(z), grid[end]), z < body ? body : grid[end]); transmittance *= Integrate(field, tile, slope, z, next, lod: true, counts); steps++; z = next; @@ -1158,6 +1245,8 @@ public sealed class NoiseBoundTests public long DenseSteps; public long MaskedSteps; public long LodSteps; + public long BodySteps; + public long BodyTiles; public long Unfinished; public float MaxDifference; public float MaxLodDifference; @@ -1186,8 +1275,10 @@ public sealed class NoiseBoundTests for (var t = 0; t < tiles; t++) { var tile = field.DrawTile(random, n); - var cells = MarchTile(field, tile, stats.Probes); + var (cells, bodyStart, _) = MarchTile(field, tile, stats.Probes); + Assert.True(field is VoidField || bodyStart < 0, $"{field.Name}: a body reported at cell {bodyStart}; only the void's density can be provably constant"); stats.Tiles++; + stats.BodyTiles += bodyStart >= 0 ? 1 : 0; for (var j = 0; j < n; j++) for (var i = 0; i < n; i++) { @@ -1204,7 +1295,7 @@ public sealed class NoiseBoundTests stats.Unfinished++; if (lod) { - var marched = MarchLod((VoidField)field, tile, slope, cells, stats.Lod, ref stats.LodSteps); + var marched = MarchLod((VoidField)field, tile, slope, cells, bodyStart, stats.Lod, ref stats.LodSteps, ref stats.BodySteps); stats.MaxLodDifference = MathF.Max(stats.MaxLodDifference, MathF.Abs(dense - marched)); } } @@ -1223,19 +1314,103 @@ public sealed class NoiseBoundTests $"IV-REPORT {label}: steps/px ref {s.PerRay(s.DenseSteps):F2}, masked {s.PerRay(s.MaskedSteps):F2}, LOD {s.PerRay(s.LodSteps):F2} ({(double)s.DenseSteps / s.LodSteps:F2}x fewer); " + $"snoise/px ref {s.PerRay(s.Dense.Snoise):F2}, masked {s.PerRay(s.Masked.Snoise):F2}, LOD {s.PerRay(s.Lod.Snoise):F2}; " + $"cost/px ref {s.PerRay(s.Dense.Cost):F2}, masked {s.PerRay(s.Masked.Cost + s.Probes.Cost):F2}, LOD {s.PerRay(s.Lod.Cost + s.Probes.Cost):F2} incl. probes (ref/LOD {s.LodRatio:F2}x, ref/masked {s.Ratio:F2}x); " - + $"probes/tile env {(double)s.Probes.Envelope / s.Tiles:F1} snoise {(double)s.Probes.Snoise / s.Tiles:F2}; max |dT| masked {s.MaxDifference:R}, LOD {s.MaxLodDifference:R}; unfinished rays {s.Unfinished}"); + + $"probes/tile env {(double)s.Probes.Envelope / s.Tiles:F1} snoise {(double)s.Probes.Snoise / s.Tiles:F2}; body tiles {s.BodyTiles}/{s.Tiles}, analytic steps/px {s.PerRay(s.BodySteps):F2}; " + + $"max |dT| masked {s.MaxDifference:R}, LOD {s.MaxLodDifference:R}; unfinished rays {s.Unfinished}"); /// - /// The proving ground (docs/cultmath-interval-ground-cut.md, "Pass 3"). Scenarios (a) height fog, - /// (b) inside the fog, (c) Aetheria's wells and (d) r1's uniform slab, each over 64 tiles at - /// N in {1, 4, 8, 16} and warp in {0, D}: the tile march integrates exactly the dense march's cells, so - /// the transmittance agrees within 1e-3 (a difference would be a skipped cell that was not empty), and - /// its combined cost must be at most half the dense march's for (a) and (c) at N = 8. (e) the void: the - /// grid over hollow radius, camera offset and ramp width (32 tiles at N = 8) and the shipped point - /// (200 tiles), three marches each; at the shipped point the masked fixed-step march agrees with the - /// reference exactly, the footprint-aware march within 0.02, and it must take at most half the - /// reference's steps per pixel. A shortfall in (a), (c) or (e) skips naming saving-2x-scenarios; the - /// fields, the grids and the envelope cost are not tuned toward it. + /// The analytic body's soundness pin (ruling operator-analytic-wall-body). Over 2,000 seeded tiles of + /// the (e) grid, the shipped void and LOD-far at N in {1, 4, 8, 16}, wherever the pre-pass reports a + /// body start b: (1) the gated bound over [grid[b], grid end] is a positive point equal to the reported + /// density, every cell from b to the end is in the mask, and at 64 random (pixel, sub-pixel, cell >= b, + /// depth in cell) points the full and the truncated Density and the ungated Exact field all equal it + /// exactly, no tolerance; (2) the one closed-form factor exp(-density ext L) over the body equals the + /// fixed-step product of the body cells' Integrate factors (no early-out, same cells) within 1e-4 + /// relative. (3) No tile of (a)-(d), at either warp, reports a body: their bounds are never a positive + /// point. + /// + [Fact] + public void AnalyticBodyMatchesFineMarch() + { + var random = new System.Random(0xB0D1); + int[] sizes = { 1, 4, 8, 16 }; + var voids = new List(); + foreach (var rh in VoidField.HollowRadii) + foreach (var offset in VoidField.CameraOffsets) + foreach (var ramp in VoidField.Ramps) + voids.Add(new VoidField(rh, ramp, offset.Fraction, offset.Name)); + voids.Add(VoidField.Shipped()); + voids.Add(VoidField.LodFar()); + var counts = new Counts(); + var bodies = new Dictionary(); + for (var t = 0; t < 2000; t++) + { + var field = t % 4 == 0 ? voids[^2] : t % 4 == 1 ? voids[^1] : voids[random.Next(voids.Count)]; + var tile = field.DrawTile(random, sizes[random.Next(sizes.Length)]); + var (cells, b, density) = MarchTile(field, tile, counts); + if (b < 0) + continue; + bodies[field.Name] = bodies.GetValueOrDefault(field.Name) + 1; + var grid = field.Grid; + var last = grid.Length - 1; + var rest = field.Bound(tile, grid[b], grid[last], gated: true, counts); + Assert.True(rest.x == rest.y && rest.x > 0.0f && rest.x == density, $"{field.Name}: body at cell {b} with density {density:R}, but the bound over the rest is {rest}"); + Assert.Equal(Enumerable.Range(b, last - b), cells.Skip(cells.Count - (last - b))); + for (var i = 0; i < 64; i++) + { + var slope = tile.PixelSlope(random.Next(tile.N), random.Next(tile.N), random.NextSingle(), random.NextSingle()); + var c = random.Next(b, last); + var z = Uniform(random, grid[c], grid[c + 1]); + foreach (var lod in new[] { false, true }) + { + var pointwise = field.Density(tile, slope, z, lod, counts); + var exact = field.Exact(tile, slope, z, lod); + Assert.True(pointwise == density && exact == density, $"{field.Name}: body from cell {b} claims {density:R}; at slope {slope}, depth {z:R} (cell {c}, lod {lod}) Density is {pointwise:R} and the ungated field {exact:R}"); + } + } + + var ray = tile.PixelSlope(random.Next(tile.N), random.Next(tile.N), random.NextSingle(), random.NextSingle()); + var product = 1.0; + for (var c = b; c < last; c++) + product *= Integrate(field, tile, ray, grid[c], grid[c + 1], lod: true, counts); + var tau = density * field.Extinction * ((grid[last] - grid[b]) * sqrt(ray.x * ray.x + ray.y * ray.y + 1.0f)); + var analytic = Math.Exp(-(double)tau); + Assert.True(Math.Abs(analytic - product) <= 1.0e-4 * product, $"{field.Name}: the analytic body factor {analytic:R} differs from the fixed-step product {product:R} over cells {b}..{last}"); + } + + output.WriteLine("IV-REPORT analytic body: tiles with a body " + string.Join(", ", bodies.OrderBy(kv => kv.Key).Select(kv => $"{kv.Key} {kv.Value}"))); + Assert.True(bodies.ContainsKey(VoidField.Shipped().Name) && bodies.ContainsKey(VoidField.LodFar().Name), "no body proven at the shipped void or at LOD-far"); + + var scenarios = new (float Warp, Func Make)[] + { + (FogField.AetheriaWarp, FogField.HeightFog), (FogField.AetheriaWarp, FogField.InsideFog), + (FogField.AetheriaWarp, FogField.Wells), (SlabField.SlabWarp, SlabField.Create), + }; + foreach (var (warp, make) in scenarios) + foreach (var w in new[] { 0.0f, warp }) + { + var field = make(w); + for (var t = 0; t < 250; t++) + { + var (_, b, _) = MarchTile(field, field.DrawTile(random, sizes[random.Next(sizes.Length)]), counts); + Assert.True(b < 0, $"{field.Name} warp {w:R}: a body reported at cell {b}"); + } + } + } + + /// + /// The proving ground (docs/cultmath-interval-ground-cut.md, "Pass 3" and "Pass 4"). Scenarios + /// (a) height fog, (b) inside the fog, (c) Aetheria's wells and (d) r1's uniform slab, each over 64 + /// tiles at N in {1, 4, 8, 16} and warp in {0, D}: the tile march integrates exactly the dense march's + /// cells, so the transmittance agrees within 1e-3 (a difference would be a skipped cell that was not + /// empty), and no (a)-(d) tile reports a body. (e) the void: the grid over hollow radius, camera offset + /// and ramp width (32 tiles at N = 8), LOD-far (32 tiles) and the one shipped void (200 tiles), three + /// marches each, the footprint-aware one taking the analytic body step. Contracts at N = 8, the lower + /// of warp 0 and D: (a) at least 2x combined cost; (c) at least 0.90 of its probe-free ceiling + /// (ruling operator-wells-contract-vs-ceiling: the ceiling is what intervals control, the fog band's + /// cost is the field's); (e) at the shipped void the masked fixed-step march agrees with the reference + /// exactly, the footprint-aware march within 0.02, and it takes at most half the reference's steps per + /// pixel. A shortfall skips naming saving-2x-scenarios and every shortfall; the fields, the grids and + /// the envelope cost are not tuned toward it. /// [Fact] public void IntervalSkipHalvesEvaluations() @@ -1259,7 +1434,7 @@ public sealed class NoiseBoundTests if (key == "d") output.WriteLine($"IV-REPORT (d) N={n} warp={w:R}: ungated dense snoise/ray {3.0 * stats.PerRay(stats.DenseSteps):F2} (three per dense sample, as r1 counted)"); if (n == 8) - ratios[key] = Math.Min(ratios.GetValueOrDefault(key, double.MaxValue), stats.Ratio); + ratios[key] = Math.Min(ratios.GetValueOrDefault(key, double.MaxValue), key == "c" ? stats.Ratio / stats.Ceiling : stats.Ratio); } foreach (var rh in VoidField.HollowRadii) @@ -1270,6 +1445,9 @@ public sealed class NoiseBoundTests ReportVoid($"{field.Name} N=8", Run(field, 8, 32, 0x701D, lod: true)); } + var lodFar = VoidField.LodFar(); + ReportVoid($"{lodFar.Name} N=8 (LOD far)", Run(lodFar, 8, 32, 0x701D, lod: true)); + var shipped = VoidField.Shipped(); var headline = Run(shipped, 8, 200, 0x5417, lod: true); ReportVoid($"{shipped.Name} N=8 (headline, 200 tiles)", headline); @@ -1277,7 +1455,15 @@ public sealed class NoiseBoundTests Assert.True(headline.MaxLodDifference <= 0.02f, $"the footprint-aware march differs from the reference by {headline.MaxLodDifference:R}"); var steps = (double)headline.DenseSteps / headline.LodSteps; - if (ratios["a"] < 2.0 || ratios["c"] < 2.0 || steps < 2.0) - Assert.Skip($"saving-2x-scenarios: at N = 8, (a) saves {ratios["a"]:F2}x and (c) {ratios["c"]:F2}x combined cost (the lower of warp 0 and D); (e) takes {steps:F2}x fewer steps per pixel at the shipped point; the contract is 2x each"); + var shortfalls = new List(); + if (ratios["a"] < 2.0) + shortfalls.Add($"(a) saves {ratios["a"]:F2}x combined cost, under 2x"); + if (ratios["c"] < 0.90) + shortfalls.Add($"(c) reaches {ratios["c"]:F2} of its probe-free ceiling, under 0.90"); + if (steps < 2.0) + shortfalls.Add($"(e) takes {steps:F2}x fewer steps per pixel at the shipped void, under 2x"); + output.WriteLine($"IV-REPORT contracts at N=8 (lower of warp 0 and D): (a) {ratios["a"]:F2}x cost, (c) {ratios["c"]:F2} of ceiling, (e) {steps:F2}x fewer steps/px"); + if (shortfalls.Count > 0) + Assert.Skip("saving-2x-scenarios: " + string.Join("; ", shortfalls)); } }