FA-69631 / Orbital propagation / Open access
Stumpff functions for universal variables: Near-zero C series has the wrong linear sign · case 01
Near-parabolic orbits get a slightly wrong C.
ROOT CAUSE
The series is 1/2+z/24.
VERIFIED REPAIR
Use 1/2 - z/24 + z^2/720.
Unsuccessful approach: Using z/12 changes the curvature coefficient.
Case contract
Input z. For z>1e-6: C=(1-cos s)/z, S=(s-sin s)/s^3 with s=sqrt z; for z<-1e-6: C=(cosh s-1)/(-z), S=(sinh s-s)/s^3 with s=sqrt(-z); otherwise series C=1/2-z/24+z^2/720, S=1/6-z/120+z^2/5040. Return [C,S] rounded to 10.
Why this case matters
Orbit determination and mission planning chain many small conversions; one wrong branch or unit silently moves a spacecraft by kilometres.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
z=x
if z>1e-6:
s=math.sqrt(z)
c=(1-math.cos(s))/z; S=(s-math.sin(s))/s**3
elif z<-1e-6:
s=math.sqrt(-z)
c=(math.cosh(s)-1)/(-z); S=(math.sinh(s)-s)/s**3
else:
c=1/2+z/24+z*z/720; S=1/6-z/120+z*z/5040
return [round(c,10),round(S,10)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('stumpff functions for universal variables 1e-07', 1e-07, [0.4999999958, 0.1666666658]), ('stumpff functions for universal variables 4.0', 4.0, [0.3540367091, 0.1363378216]), ('stumpff functions for universal variables 0.5', 0.5, [0.4795108058, 0.1625492603]), ('stumpff functions for universal variables 30.0', 30.0, [0.0102526963, 0.0377242152]), ('stumpff functions for universal variables 0.0', 0.0, [0.5, 0.1666666667]), ('stumpff functions for universal variables -1e-07', -1e-07, [0.5000000042, 0.1666666675]), ('stumpff functions for universal variables -0.5', -0.5, [0.521183673, 0.1708832825])], [('stumpff functions for universal variables -1e-07', -1e-07, [0.5000000042, 0.1666666675]), ('stumpff functions for universal variables 1e-07', 1e-07, [0.4999999958, 0.1666666658]), ('stumpff functions for universal variables 0.0', 0.0, [0.5, 0.1666666667]), ('stumpff functions for universal variables -0.5', -0.5, [0.521183673, 0.1708832825]), ('stumpff functions for universal variables -4.0', -4.0, [0.6905489228, 0.203357551]), ('stumpff functions for universal variables -25.0', -25.0, [2.928397941, 0.5536256846]), ('stumpff functions for universal variables 9.8696', 9.8696, [0.2026424576, 0.1013212062])], [('stumpff functions for universal variables 1e-07', 1e-07, [0.4999999958, 0.1666666658]), ('stumpff functions for universal variables -0.5', -0.5, [0.521183673, 0.1708832825]), ('stumpff functions for universal variables -4.0', -4.0, [0.6905489228, 0.203357551]), ('stumpff functions for universal variables -25.0', -25.0, [2.928397941, 0.5536256846]), ('stumpff functions for universal variables 9.8696', 9.8696, [0.2026424576, 0.1013212062]), ('stumpff functions for universal variables 0.05', 0.05, [0.4979201358, 0.1662504957]), ('stumpff functions for universal variables -0.05', -0.05, [0.5020868087, 0.1670838297])], [('stumpff functions for universal variables -1e-07', -1e-07, [0.5000000042, 0.1666666675]), ('stumpff functions for universal variables 9.8696', 9.8696, [0.2026424576, 0.1013212062]), ('stumpff functions for universal variables 0.05', 0.05, [0.4979201358, 0.1662504957]), ('stumpff functions for universal variables -0.05', -0.05, [0.5020868087, 0.1670838297]), ('stumpff functions for universal variables 2e-06', 2e-06, [0.4999999167, 0.16666665]), ('stumpff functions for universal variables -3e-06', -3e-06, [0.500000125, 0.1666666917]), ('stumpff functions for universal variables 4.0', 4.0, [0.3540367091, 0.1363378216])], [('stumpff functions for universal variables 1e-07', 1e-07, [0.4999999958, 0.1666666658]), ('stumpff functions for universal variables 2e-06', 2e-06, [0.4999999167, 0.16666665]), ('stumpff functions for universal variables -3e-06', -3e-06, [0.500000125, 0.1666666917]), ('stumpff functions for universal variables 4.0', 4.0, [0.3540367091, 0.1363378216]), ('stumpff functions for universal variables 0.5', 0.5, [0.4795108058, 0.1625492603]), ('stumpff functions for universal variables 30.0', 30.0, [0.0102526963, 0.0377242152]), ('stumpff functions for universal variables 0.0', 0.0, [0.5, 0.1666666667])]]
for label, args, expected in fixtures[N-1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| stumpff functions for universal variables 1e-07 | [0.5000000042, 0.1666666658] | [0.4999999958, 0.1666666658] | Failed |
| stumpff functions for universal variables 4.0 | [0.3540367091, 0.1363378216] | [0.3540367091, 0.1363378216] | Passed |
| stumpff functions for universal variables 0.5 | [0.4795108058, 0.1625492603] | [0.4795108058, 0.1625492603] | Passed |
| stumpff functions for universal variables 30.0 | [0.0102526963, 0.0377242152] | [0.0102526963, 0.0377242152] | Passed |
| stumpff functions for universal variables 0.0 | [0.5, 0.1666666667] | [0.5, 0.1666666667] | Passed |
| stumpff functions for universal variables -1e-07 | [0.4999999958, 0.1666666675] | [0.5000000042, 0.1666666675] | Failed |
| stumpff functions for universal variables -0.5 | [0.521183673, 0.1708832825] | [0.521183673, 0.1708832825] | Passed |
SHA-256 / fb4c97fd11191003d3727f380a6067cc6245a186265faf4c0ba3ad0942e7e901
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
z=x
if z>1e-6:
s=math.sqrt(z)
c=(1-math.cos(s))/z; S=(s-math.sin(s))/s**3
elif z<-1e-6:
s=math.sqrt(-z)
c=(math.cosh(s)-1)/(-z); S=(math.sinh(s)-s)/s**3
else:
c=1/2-z/12+z*z/720; S=1/6-z/120+z*z/5040
return [round(c,10),round(S,10)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('stumpff functions for universal variables 1e-07', 1e-07, [0.4999999958, 0.1666666658]), ('stumpff functions for universal variables 4.0', 4.0, [0.3540367091, 0.1363378216]), ('stumpff functions for universal variables 0.5', 0.5, [0.4795108058, 0.1625492603]), ('stumpff functions for universal variables 30.0', 30.0, [0.0102526963, 0.0377242152]), ('stumpff functions for universal variables 0.0', 0.0, [0.5, 0.1666666667]), ('stumpff functions for universal variables -1e-07', -1e-07, [0.5000000042, 0.1666666675]), ('stumpff functions for universal variables -0.5', -0.5, [0.521183673, 0.1708832825])], [('stumpff functions for universal variables -1e-07', -1e-07, [0.5000000042, 0.1666666675]), ('stumpff functions for universal variables 1e-07', 1e-07, [0.4999999958, 0.1666666658]), ('stumpff functions for universal variables 0.0', 0.0, [0.5, 0.1666666667]), ('stumpff functions for universal variables -0.5', -0.5, [0.521183673, 0.1708832825]), ('stumpff functions for universal variables -4.0', -4.0, [0.6905489228, 0.203357551]), ('stumpff functions for universal variables -25.0', -25.0, [2.928397941, 0.5536256846]), ('stumpff functions for universal variables 9.8696', 9.8696, [0.2026424576, 0.1013212062])], [('stumpff functions for universal variables 1e-07', 1e-07, [0.4999999958, 0.1666666658]), ('stumpff functions for universal variables -0.5', -0.5, [0.521183673, 0.1708832825]), ('stumpff functions for universal variables -4.0', -4.0, [0.6905489228, 0.203357551]), ('stumpff functions for universal variables -25.0', -25.0, [2.928397941, 0.5536256846]), ('stumpff functions for universal variables 9.8696', 9.8696, [0.2026424576, 0.1013212062]), ('stumpff functions for universal variables 0.05', 0.05, [0.4979201358, 0.1662504957]), ('stumpff functions for universal variables -0.05', -0.05, [0.5020868087, 0.1670838297])], [('stumpff functions for universal variables -1e-07', -1e-07, [0.5000000042, 0.1666666675]), ('stumpff functions for universal variables 9.8696', 9.8696, [0.2026424576, 0.1013212062]), ('stumpff functions for universal variables 0.05', 0.05, [0.4979201358, 0.1662504957]), ('stumpff functions for universal variables -0.05', -0.05, [0.5020868087, 0.1670838297]), ('stumpff functions for universal variables 2e-06', 2e-06, [0.4999999167, 0.16666665]), ('stumpff functions for universal variables -3e-06', -3e-06, [0.500000125, 0.1666666917]), ('stumpff functions for universal variables 4.0', 4.0, [0.3540367091, 0.1363378216])], [('stumpff functions for universal variables 1e-07', 1e-07, [0.4999999958, 0.1666666658]), ('stumpff functions for universal variables 2e-06', 2e-06, [0.4999999167, 0.16666665]), ('stumpff functions for universal variables -3e-06', -3e-06, [0.500000125, 0.1666666917]), ('stumpff functions for universal variables 4.0', 4.0, [0.3540367091, 0.1363378216]), ('stumpff functions for universal variables 0.5', 0.5, [0.4795108058, 0.1625492603]), ('stumpff functions for universal variables 30.0', 30.0, [0.0102526963, 0.0377242152]), ('stumpff functions for universal variables 0.0', 0.0, [0.5, 0.1666666667])]]
for label, args, expected in fixtures[N-1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| stumpff functions for universal variables 1e-07 | [0.4999999917, 0.1666666658] | [0.4999999958, 0.1666666658] | Failed |
| stumpff functions for universal variables 4.0 | [0.3540367091, 0.1363378216] | [0.3540367091, 0.1363378216] | Passed |
| stumpff functions for universal variables 0.5 | [0.4795108058, 0.1625492603] | [0.4795108058, 0.1625492603] | Passed |
| stumpff functions for universal variables 30.0 | [0.0102526963, 0.0377242152] | [0.0102526963, 0.0377242152] | Passed |
| stumpff functions for universal variables 0.0 | [0.5, 0.1666666667] | [0.5, 0.1666666667] | Passed |
| stumpff functions for universal variables -1e-07 | [0.5000000083, 0.1666666675] | [0.5000000042, 0.1666666675] | Failed |
| stumpff functions for universal variables -0.5 | [0.521183673, 0.1708832825] | [0.521183673, 0.1708832825] | Passed |
SHA-256 / 1b7258ac888de2553ff0406cab9e07251c6e3d1c549ef717c9ab3a0deda3af88
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
z=x
if z>1e-6:
s=math.sqrt(z)
c=(1-math.cos(s))/z; S=(s-math.sin(s))/s**3
elif z<-1e-6:
s=math.sqrt(-z)
c=(math.cosh(s)-1)/(-z); S=(math.sinh(s)-s)/s**3
else:
c=1/2-z/24+z*z/720; S=1/6-z/120+z*z/5040
return [round(c,10),round(S,10)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('stumpff functions for universal variables 1e-07', 1e-07, [0.4999999958, 0.1666666658]), ('stumpff functions for universal variables 4.0', 4.0, [0.3540367091, 0.1363378216]), ('stumpff functions for universal variables 0.5', 0.5, [0.4795108058, 0.1625492603]), ('stumpff functions for universal variables 30.0', 30.0, [0.0102526963, 0.0377242152]), ('stumpff functions for universal variables 0.0', 0.0, [0.5, 0.1666666667]), ('stumpff functions for universal variables -1e-07', -1e-07, [0.5000000042, 0.1666666675]), ('stumpff functions for universal variables -0.5', -0.5, [0.521183673, 0.1708832825])], [('stumpff functions for universal variables -1e-07', -1e-07, [0.5000000042, 0.1666666675]), ('stumpff functions for universal variables 1e-07', 1e-07, [0.4999999958, 0.1666666658]), ('stumpff functions for universal variables 0.0', 0.0, [0.5, 0.1666666667]), ('stumpff functions for universal variables -0.5', -0.5, [0.521183673, 0.1708832825]), ('stumpff functions for universal variables -4.0', -4.0, [0.6905489228, 0.203357551]), ('stumpff functions for universal variables -25.0', -25.0, [2.928397941, 0.5536256846]), ('stumpff functions for universal variables 9.8696', 9.8696, [0.2026424576, 0.1013212062])], [('stumpff functions for universal variables 1e-07', 1e-07, [0.4999999958, 0.1666666658]), ('stumpff functions for universal variables -0.5', -0.5, [0.521183673, 0.1708832825]), ('stumpff functions for universal variables -4.0', -4.0, [0.6905489228, 0.203357551]), ('stumpff functions for universal variables -25.0', -25.0, [2.928397941, 0.5536256846]), ('stumpff functions for universal variables 9.8696', 9.8696, [0.2026424576, 0.1013212062]), ('stumpff functions for universal variables 0.05', 0.05, [0.4979201358, 0.1662504957]), ('stumpff functions for universal variables -0.05', -0.05, [0.5020868087, 0.1670838297])], [('stumpff functions for universal variables -1e-07', -1e-07, [0.5000000042, 0.1666666675]), ('stumpff functions for universal variables 9.8696', 9.8696, [0.2026424576, 0.1013212062]), ('stumpff functions for universal variables 0.05', 0.05, [0.4979201358, 0.1662504957]), ('stumpff functions for universal variables -0.05', -0.05, [0.5020868087, 0.1670838297]), ('stumpff functions for universal variables 2e-06', 2e-06, [0.4999999167, 0.16666665]), ('stumpff functions for universal variables -3e-06', -3e-06, [0.500000125, 0.1666666917]), ('stumpff functions for universal variables 4.0', 4.0, [0.3540367091, 0.1363378216])], [('stumpff functions for universal variables 1e-07', 1e-07, [0.4999999958, 0.1666666658]), ('stumpff functions for universal variables 2e-06', 2e-06, [0.4999999167, 0.16666665]), ('stumpff functions for universal variables -3e-06', -3e-06, [0.500000125, 0.1666666917]), ('stumpff functions for universal variables 4.0', 4.0, [0.3540367091, 0.1363378216]), ('stumpff functions for universal variables 0.5', 0.5, [0.4795108058, 0.1625492603]), ('stumpff functions for universal variables 30.0', 30.0, [0.0102526963, 0.0377242152]), ('stumpff functions for universal variables 0.0', 0.0, [0.5, 0.1666666667])]]
for label, args, expected in fixtures[N-1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| stumpff functions for universal variables 1e-07 | [0.4999999958, 0.1666666658] | [0.4999999958, 0.1666666658] | Passed |
| stumpff functions for universal variables 4.0 | [0.3540367091, 0.1363378216] | [0.3540367091, 0.1363378216] | Passed |
| stumpff functions for universal variables 0.5 | [0.4795108058, 0.1625492603] | [0.4795108058, 0.1625492603] | Passed |
| stumpff functions for universal variables 30.0 | [0.0102526963, 0.0377242152] | [0.0102526963, 0.0377242152] | Passed |
| stumpff functions for universal variables 0.0 | [0.5, 0.1666666667] | [0.5, 0.1666666667] | Passed |
| stumpff functions for universal variables -1e-07 | [0.5000000042, 0.1666666675] | [0.5000000042, 0.1666666675] | Passed |
| stumpff functions for universal variables -0.5 | [0.521183673, 0.1708832825] | [0.521183673, 0.1708832825] | Passed |
SHA-256 / df2e6e846f1f133e3dcaf4ac9abb41d686782a2c0fbbda1863fe6f4c1f23e437
Verification & scope
A deterministic toy two-body model with stipulated constants and conventions; not flight dynamics software or a validated SGP4 implementation. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:48:13.222339+00:00.
Case digest / 64cb1266b11846be51557f884ae6ece6b183aa8cabfe357fa6ac270bd427a095