From 35406653b6915e3f23ae788ff98b3ae77b6bc2a0 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Fri, 16 Oct 2026 23:30:31 +0200 Subject: [PATCH] GravityField: the band potential's promise is the float32 bound measured, 1.8e-6; the sweep covers the taus above the seam Co-Authored-By: Claude Opus 5.5 --- Assets/Scripts/ServerShared/GravityField.cs | 4 ++-- tests/Aetheria.Shared.Tests/WellLawTests.cs | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Assets/Scripts/ServerShared/GravityField.cs b/Assets/Scripts/ServerShared/GravityField.cs index 0eb3797de..084aa1f45 100644 --- a/Assets/Scripts/ServerShared/GravityField.cs +++ b/Assets/Scripts/ServerShared/GravityField.cs @@ -28,10 +28,10 @@ public static class GravityField /// A ring member of a bodyless node reaches RingReach x its distance: whole out to the ring's diameter. public const float RingReach = 4f; - /// The band is summed as a series for tau above this. Measured (map B54): float32 within 1.0e-6 per unit strength everywhere with SeriesTerms terms; the closed form is float32-clean only to about 0.45. + /// The band is summed as a series for tau above this. float32 error per unit strength against the double integral is at most 1.8e-6 anywhere (worst 1.7e-6 just above the seam, where the series has not reached float32 resolution); the closed form is float32-clean only to about 0.45. public const float SeriesFrom = .4f; - /// The series branch's length: its ratio is below 1/1.4, so 40 terms reach float32's floor. + /// The series branch's length: its ratio is below 1/1.4, so the truncated tail is below 1.4e-6 at the seam and falls geometrically above it. public const int SeriesTerms = 40; /// S(t) as polynomial coefficients in t, lowest first: t^Order sum_j C(Order-1+j, j) (1-t)^j. diff --git a/tests/Aetheria.Shared.Tests/WellLawTests.cs b/tests/Aetheria.Shared.Tests/WellLawTests.cs index 6ac526eda..3acbcb87d 100644 --- a/tests/Aetheria.Shared.Tests/WellLawTests.cs +++ b/tests/Aetheria.Shared.Tests/WellLawTests.cs @@ -82,13 +82,14 @@ public sealed class WellLawTests : IDisposable // The band's potential is the integral of its pull, in single precision, on both sides of the series threshold: tau = // (a^2 + eps^2) / (b^2 - a^2) is swept from 0.05 to 10 (every (a, b) where that tau has a real softening), and the - // potential stays within 1.2e-6 per unit strength of the double-precision Simpson integral of the pull. A closed form kept - // past tau 0.45 or a series cut short misses this by 1e-5 to 1e-3. + // potential stays within 1.8e-6 per unit strength of the double-precision Simpson integral of the pull. A closed form kept + // past tau 0.6 or a series cut short misses this by 1e-5 to 1e-3. Both branches are within the bound between tau 0.3 and 0.6, + // so the exact seam (SeriesFrom 0.4) inside that interval is pinned by the committed shader being the generated one, not here. [Fact] public void TheBandPotentialIsExactInSinglePrecision() { var checkedCases = 0; - foreach (var tau in new[] { .05, .3, .39, .41, .6, .7, 1, 1.5, 2.5, 10 }) + foreach (var tau in new[] { .05, .3, .35, .39, .41, .45, .5, .55, .6, .7, 1, 1.5, 2.5, 10 }) foreach (var (a, b) in new[] { (1000.0, 1500.0), (40.0, 60.0), (11.0, 22.0), (0.0, 1525.0), (150.0, 4000.0) }) { var e2 = tau * (b * b - a * a) - a * a; @@ -104,7 +105,7 @@ public sealed class WellLawTests : IDisposable return x / (x * x + e2) * (1 - S(t)); }, r, b, 8000); var actual = GravityField.Potential(eps, (float) a, (float) b, (float) r); - Assert.InRange(actual, oracle - 1.2e-6, oracle + 1.2e-6); + Assert.InRange(actual, oracle - 1.8e-6, oracle + 1.8e-6); checkedCases++; } }