FA-69536 / Orbital propagation / Open access
Fixed-step RK4 two-body propagation: Third stage reuses the first slope · case 01
The midpoint correction never happens and error grows.
ROOT CAUSE
k3 is evaluated from s+h/2*k1 instead of s+h/2*k2.
VERIFIED REPAIR
Probe k3 with k2.
Unsuccessful approach: Probing k3 a full step along k2 mixes the fourth-stage rule into the third.
Case contract
Input [r0, v0, mu, T, steps] for a planar two-body orbit. Integrate state [x,y,vx,vy] with acceleration -mu r/|r|^3 using classical RK4 with h=T/steps for exactly steps steps. Return the final state rounded to 6 decimals.
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):
r0,v0,mu,T,steps=x
h=T/steps
def f(s):
px,py,vx,vy=s
rr=(px*px+py*py)**1.5
return [vx,vy,-mu*px/rr,-mu*py/rr]
s=list(r0)+list(v0)
for _ in range(steps):
k1=f(s)
k2=f([s[i]+h/2*k1[i] for i in range(4)])
k3=f([s[i]+h/2*k1[i] for i in range(4)])
k4=f([s[i]+h*k3[i] for i in range(4)])
s=[s[i]+h/6*(k1[i]+2*k2[i]+2*k3[i]+k4[i]) for i in range(4)]
return [round(c,6) for c in s]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12]', [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12], [5586.092992, 4218.445527, -4.547562, 6.021804]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20]', [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20], [4101.15166, 6610.394483, -5.692596, 5.332573]), ('fixed-step rk4 two-body propagation [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15]', [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15], [-6593.162659, 6759.502773, -4.170281, -4.18782]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30]', [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30], [-0.98999, 0.141112, -0.141113, -0.989997]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25]', [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25], [-2.095663, 1.089551, -0.384431, -0.37274]), ('fixed-step rk4 two-body propagation [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10]', [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10], [-0.154684, -0.721678, 1.394034, 0.039166]), ('fixed-step rk4 two-body propagation [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6]', [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6], [6111.623093, 3316.078893, -3.439749, 6.583115])], [('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20]', [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20], [4101.15166, 6610.394483, -5.692596, 5.332573]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30]', [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30], [-0.98999, 0.141112, -0.141113, -0.989997]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25]', [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25], [-2.095663, 1.089551, -0.384431, -0.37274]), ('fixed-step rk4 two-body propagation [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10]', [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10], [-0.154684, -0.721678, 1.394034, 0.039166]), ('fixed-step rk4 two-body propagation [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6]', [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6], [6111.623093, 3316.078893, -3.439749, 6.583115]), ('fixed-step rk4 two-body propagation [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8]', [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8], [-0.108631, 0.939625, -0.993051, -0.614991]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12]', [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12], [5586.092992, 4218.445527, -4.547562, 6.021804])], [('fixed-step rk4 two-body propagation [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15]', [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15], [-6593.162659, 6759.502773, -4.170281, -4.18782]), ('fixed-step rk4 two-body propagation [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6]', [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6], [6111.623093, 3316.078893, -3.439749, 6.583115]), ('fixed-step rk4 two-body propagation [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8]', [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8], [-0.108631, 0.939625, -0.993051, -0.614991]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12]', [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12], [5586.092992, 4218.445527, -4.547562, 6.021804]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20]', [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20], [4101.15166, 6610.394483, -5.692596, 5.332573]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30]', [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30], [-0.98999, 0.141112, -0.141113, -0.989997]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25]', [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25], [-2.095663, 1.089551, -0.384431, -0.37274])], [('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30]', [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30], [-0.98999, 0.141112, -0.141113, -0.989997]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20]', [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20], [4101.15166, 6610.394483, -5.692596, 5.332573]), ('fixed-step rk4 two-body propagation [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15]', [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15], [-6593.162659, 6759.502773, -4.170281, -4.18782]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25]', [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25], [-2.095663, 1.089551, -0.384431, -0.37274]), ('fixed-step rk4 two-body propagation [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10]', [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10], [-0.154684, -0.721678, 1.394034, 0.039166]), ('fixed-step rk4 two-body propagation [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6]', [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6], [6111.623093, 3316.078893, -3.439749, 6.583115]), ('fixed-step rk4 two-body propagation [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8]', [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8], [-0.108631, 0.939625, -0.993051, -0.614991])], [('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25]', [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25], [-2.095663, 1.089551, -0.384431, -0.37274]), ('fixed-step rk4 two-body propagation [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10]', [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10], [-0.154684, -0.721678, 1.394034, 0.039166]), ('fixed-step rk4 two-body propagation [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6]', [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6], [6111.623093, 3316.078893, -3.439749, 6.583115]), ('fixed-step rk4 two-body propagation [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8]', [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8], [-0.108631, 0.939625, -0.993051, -0.614991]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12]', [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12], [5586.092992, 4218.445527, -4.547562, 6.021804]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20]', [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20], [4101.15166, 6610.394483, -5.692596, 5.332573]), ('fixed-step rk4 two-body propagation [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15]', [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15], [-6593.162659, 6759.502773, -4.170281, -4.18782])]]
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 |
|---|---|---|---|
| fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12] | [5586.503925, 4219.584528, -4.544835, 6.022513] | [5586.092992, 4218.445527, -4.547562, 6.021804] | Failed |
| fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20] | [4101.681296, 6611.716065, -5.689722, 5.333952] | [4101.15166, 6610.394483, -5.692596, 5.332573] | Failed |
| fixed-step rk4 two-body propagation [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15] | [-6595.202376, 6760.520819, -4.171425, -4.184388] | [-6593.162659, 6759.502773, -4.170281, -4.18782] | Failed |
| fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30] | [-0.99326, 0.153453, -0.152383, -0.983292] | [-0.98999, 0.141112, -0.141113, -0.989997] | Failed |
| fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25] | [-2.088993, 1.130888, -0.389636, -0.361838] | [-2.095663, 1.089551, -0.384431, -0.37274] | Failed |
| fixed-step rk4 two-body propagation [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10] | [-0.162344, -0.731741, 1.380021, 0.017988] | [-0.154684, -0.721678, 1.394034, 0.039166] | Failed |
| fixed-step rk4 two-body propagation [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6] | [6111.594397, 3316.64024, -3.438502, 6.583471] | [6111.623093, 3316.078893, -3.439749, 6.583115] | Failed |
SHA-256 / ce4e2d43e65aa799ce03e138ac60fbcf7b425aa83e780732792df813af903a1d
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
r0,v0,mu,T,steps=x
h=T/steps
def f(s):
px,py,vx,vy=s
rr=(px*px+py*py)**1.5
return [vx,vy,-mu*px/rr,-mu*py/rr]
s=list(r0)+list(v0)
for _ in range(steps):
k1=f(s)
k2=f([s[i]+h/2*k1[i] for i in range(4)])
k3=f([s[i]+h*k2[i] for i in range(4)])
k4=f([s[i]+h*k3[i] for i in range(4)])
s=[s[i]+h/6*(k1[i]+2*k2[i]+2*k3[i]+k4[i]) for i in range(4)]
return [round(c,6) for c in s]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12]', [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12], [5586.092992, 4218.445527, -4.547562, 6.021804]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20]', [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20], [4101.15166, 6610.394483, -5.692596, 5.332573]), ('fixed-step rk4 two-body propagation [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15]', [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15], [-6593.162659, 6759.502773, -4.170281, -4.18782]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30]', [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30], [-0.98999, 0.141112, -0.141113, -0.989997]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25]', [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25], [-2.095663, 1.089551, -0.384431, -0.37274]), ('fixed-step rk4 two-body propagation [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10]', [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10], [-0.154684, -0.721678, 1.394034, 0.039166]), ('fixed-step rk4 two-body propagation [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6]', [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6], [6111.623093, 3316.078893, -3.439749, 6.583115])], [('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20]', [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20], [4101.15166, 6610.394483, -5.692596, 5.332573]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30]', [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30], [-0.98999, 0.141112, -0.141113, -0.989997]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25]', [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25], [-2.095663, 1.089551, -0.384431, -0.37274]), ('fixed-step rk4 two-body propagation [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10]', [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10], [-0.154684, -0.721678, 1.394034, 0.039166]), ('fixed-step rk4 two-body propagation [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6]', [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6], [6111.623093, 3316.078893, -3.439749, 6.583115]), ('fixed-step rk4 two-body propagation [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8]', [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8], [-0.108631, 0.939625, -0.993051, -0.614991]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12]', [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12], [5586.092992, 4218.445527, -4.547562, 6.021804])], [('fixed-step rk4 two-body propagation [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15]', [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15], [-6593.162659, 6759.502773, -4.170281, -4.18782]), ('fixed-step rk4 two-body propagation [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6]', [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6], [6111.623093, 3316.078893, -3.439749, 6.583115]), ('fixed-step rk4 two-body propagation [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8]', [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8], [-0.108631, 0.939625, -0.993051, -0.614991]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12]', [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12], [5586.092992, 4218.445527, -4.547562, 6.021804]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20]', [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20], [4101.15166, 6610.394483, -5.692596, 5.332573]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30]', [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30], [-0.98999, 0.141112, -0.141113, -0.989997]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25]', [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25], [-2.095663, 1.089551, -0.384431, -0.37274])], [('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30]', [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30], [-0.98999, 0.141112, -0.141113, -0.989997]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20]', [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20], [4101.15166, 6610.394483, -5.692596, 5.332573]), ('fixed-step rk4 two-body propagation [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15]', [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15], [-6593.162659, 6759.502773, -4.170281, -4.18782]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25]', [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25], [-2.095663, 1.089551, -0.384431, -0.37274]), ('fixed-step rk4 two-body propagation [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10]', [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10], [-0.154684, -0.721678, 1.394034, 0.039166]), ('fixed-step rk4 two-body propagation [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6]', [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6], [6111.623093, 3316.078893, -3.439749, 6.583115]), ('fixed-step rk4 two-body propagation [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8]', [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8], [-0.108631, 0.939625, -0.993051, -0.614991])], [('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25]', [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25], [-2.095663, 1.089551, -0.384431, -0.37274]), ('fixed-step rk4 two-body propagation [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10]', [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10], [-0.154684, -0.721678, 1.394034, 0.039166]), ('fixed-step rk4 two-body propagation [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6]', [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6], [6111.623093, 3316.078893, -3.439749, 6.583115]), ('fixed-step rk4 two-body propagation [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8]', [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8], [-0.108631, 0.939625, -0.993051, -0.614991]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12]', [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12], [5586.092992, 4218.445527, -4.547562, 6.021804]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20]', [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20], [4101.15166, 6610.394483, -5.692596, 5.332573]), ('fixed-step rk4 two-body propagation [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15]', [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15], [-6593.162659, 6759.502773, -4.170281, -4.18782])]]
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 |
|---|---|---|---|
| fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12] | [5545.724321, 4191.03158, -4.560031, 5.967617] | [5586.092992, 4218.445527, -4.547562, 6.021804] | Failed |
| fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20] | [4057.309774, 6554.470832, -5.696574, 5.255633] | [4101.15166, 6610.394483, -5.692596, 5.332573] | Failed |
| fixed-step rk4 two-body propagation [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15] | [-6531.780814, 6688.766336, -4.104435, -4.204252] | [-6593.162659, 6759.502773, -4.170281, -4.18782] | Failed |
| fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30] | [-0.764156, -0.145779, 0.335258, -1.085337] | [-0.98999, 0.141112, -0.141113, -0.989997] | Failed |
| fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25] | [-1.757816, 0.494611, -0.133053, -0.563093] | [-2.095663, 1.089551, -0.384431, -0.37274] | Failed |
| fixed-step rk4 two-body propagation [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10] | [-0.050996, -0.605395, 1.445964, 0.341021] | [-0.154684, -0.721678, 1.394034, 0.039166] | Failed |
| fixed-step rk4 two-body propagation [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6] | [6092.617237, 3305.872335, -3.437663, 6.559798] | [6111.623093, 3316.078893, -3.439749, 6.583115] | Failed |
SHA-256 / 7afe21fefa3c98c5e48724611fdc634e615b3fc3a73d4e83a39bb80552ee092a
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
r0,v0,mu,T,steps=x
h=T/steps
def f(s):
px,py,vx,vy=s
rr=(px*px+py*py)**1.5
return [vx,vy,-mu*px/rr,-mu*py/rr]
s=list(r0)+list(v0)
for _ in range(steps):
k1=f(s)
k2=f([s[i]+h/2*k1[i] for i in range(4)])
k3=f([s[i]+h/2*k2[i] for i in range(4)])
k4=f([s[i]+h*k3[i] for i in range(4)])
s=[s[i]+h/6*(k1[i]+2*k2[i]+2*k3[i]+k4[i]) for i in range(4)]
return [round(c,6) for c in s]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12]', [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12], [5586.092992, 4218.445527, -4.547562, 6.021804]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20]', [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20], [4101.15166, 6610.394483, -5.692596, 5.332573]), ('fixed-step rk4 two-body propagation [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15]', [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15], [-6593.162659, 6759.502773, -4.170281, -4.18782]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30]', [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30], [-0.98999, 0.141112, -0.141113, -0.989997]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25]', [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25], [-2.095663, 1.089551, -0.384431, -0.37274]), ('fixed-step rk4 two-body propagation [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10]', [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10], [-0.154684, -0.721678, 1.394034, 0.039166]), ('fixed-step rk4 two-body propagation [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6]', [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6], [6111.623093, 3316.078893, -3.439749, 6.583115])], [('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20]', [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20], [4101.15166, 6610.394483, -5.692596, 5.332573]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30]', [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30], [-0.98999, 0.141112, -0.141113, -0.989997]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25]', [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25], [-2.095663, 1.089551, -0.384431, -0.37274]), ('fixed-step rk4 two-body propagation [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10]', [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10], [-0.154684, -0.721678, 1.394034, 0.039166]), ('fixed-step rk4 two-body propagation [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6]', [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6], [6111.623093, 3316.078893, -3.439749, 6.583115]), ('fixed-step rk4 two-body propagation [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8]', [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8], [-0.108631, 0.939625, -0.993051, -0.614991]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12]', [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12], [5586.092992, 4218.445527, -4.547562, 6.021804])], [('fixed-step rk4 two-body propagation [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15]', [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15], [-6593.162659, 6759.502773, -4.170281, -4.18782]), ('fixed-step rk4 two-body propagation [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6]', [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6], [6111.623093, 3316.078893, -3.439749, 6.583115]), ('fixed-step rk4 two-body propagation [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8]', [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8], [-0.108631, 0.939625, -0.993051, -0.614991]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12]', [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12], [5586.092992, 4218.445527, -4.547562, 6.021804]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20]', [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20], [4101.15166, 6610.394483, -5.692596, 5.332573]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30]', [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30], [-0.98999, 0.141112, -0.141113, -0.989997]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25]', [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25], [-2.095663, 1.089551, -0.384431, -0.37274])], [('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30]', [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30], [-0.98999, 0.141112, -0.141113, -0.989997]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20]', [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20], [4101.15166, 6610.394483, -5.692596, 5.332573]), ('fixed-step rk4 two-body propagation [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15]', [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15], [-6593.162659, 6759.502773, -4.170281, -4.18782]), ('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25]', [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25], [-2.095663, 1.089551, -0.384431, -0.37274]), ('fixed-step rk4 two-body propagation [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10]', [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10], [-0.154684, -0.721678, 1.394034, 0.039166]), ('fixed-step rk4 two-body propagation [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6]', [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6], [6111.623093, 3316.078893, -3.439749, 6.583115]), ('fixed-step rk4 two-body propagation [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8]', [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8], [-0.108631, 0.939625, -0.993051, -0.614991])], [('fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25]', [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25], [-2.095663, 1.089551, -0.384431, -0.37274]), ('fixed-step rk4 two-body propagation [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10]', [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10], [-0.154684, -0.721678, 1.394034, 0.039166]), ('fixed-step rk4 two-body propagation [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6]', [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6], [6111.623093, 3316.078893, -3.439749, 6.583115]), ('fixed-step rk4 two-body propagation [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8]', [[2.0, 0.0], [0.0, 0.5], 1.0, 4.0, 8], [-0.108631, 0.939625, -0.993051, -0.614991]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12]', [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12], [5586.092992, 4218.445527, -4.547562, 6.021804]), ('fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20]', [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20], [4101.15166, 6610.394483, -5.692596, 5.332573]), ('fixed-step rk4 two-body propagation [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15]', [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15], [-6593.162659, 6759.502773, -4.170281, -4.18782])]]
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 |
|---|---|---|---|
| fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12] | [5586.092992, 4218.445527, -4.547562, 6.021804] | [5586.092992, 4218.445527, -4.547562, 6.021804] | Passed |
| fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 8.5], 398600.4418, 900.0, 20] | [4101.15166, 6610.394483, -5.692596, 5.332573] | [4101.15166, 6610.394483, -5.692596, 5.332573] | Passed |
| fixed-step rk4 two-body propagation [[0.0, 9000.0], [-6.2, 0.8], 398600.4418, 1200.0, 15] | [-6593.162659, 6759.502773, -4.170281, -4.18782] | [-6593.162659, 6759.502773, -4.170281, -4.18782] | Passed |
| fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.0], 1.0, 3.0, 30] | [-0.98999, 0.141112, -0.141113, -0.989997] | [-0.98999, 0.141112, -0.141113, -0.989997] | Passed |
| fixed-step rk4 two-body propagation [[1.0, 0.0], [0.0, 1.2], 1.0, 5.0, 25] | [-2.095663, 1.089551, -0.384431, -0.37274] | [-2.095663, 1.089551, -0.384431, -0.37274] | Passed |
| fixed-step rk4 two-body propagation [[-1.5, 0.5], [0.1, -0.7], 1.0, 2.0, 10] | [-0.154684, -0.721678, 1.394034, 0.039166] | [-0.154684, -0.721678, 1.394034, 0.039166] | Passed |
| fixed-step rk4 two-body propagation [[6800.0, 1200.0], [-1.1, 7.4], 398600.4418, 300.0, 6] | [6111.623093, 3316.078893, -3.439749, 6.583115] | [6111.623093, 3316.078893, -3.439749, 6.583115] | Passed |
SHA-256 / 4dde3624fcf421a2c56fe0547cd5ef2fdbdbe920a2f0a647b409c44c26ca17c0
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:12.321023+00:00.
Case digest / add200c96f74df17127cb27387178ca2bc8ed82d29db44b9dc77e20291d4307b