FAILURE MAP
← Case archive

FA-69526 / Orbital propagation / Open access

Fixed-step RK4 two-body propagation: RK4 stages are averaged equally · case 01

Energy drifts much faster than expected for the step size.

Verified by executionVariant 1 · 7 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The final update uses (k1+k2+k3+k4)/4.

VERIFIED REPAIR

Weight the stages 1,2,2,1 over 6.

Unsuccessful approach: Weighting the end stages double inverts the Simpson structure.

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*k2[i] for i in range(4)])
        k4=f([s[i]+h*k3[i] for i in range(4)])
        s=[s[i]+h/4*(k1[i]+k2[i]+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 fixtureActualExpectedOutcome
fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12][5586.223725, 4218.214441, -4.547344, 6.021971][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.502929, 6610.326481, -5.692359, 5.333101][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][-6592.896007, 6759.762058, -4.170567, -4.187731][-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.989698, 0.141283, -0.141247, -0.990103][-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.099712, 1.100178, -0.387951, -0.369339][-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.1533, -0.717946, 1.394213, 0.045017][-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.677134, 3315.954506, -3.439637, 6.583201][6111.623093, 3316.078893, -3.439749, 6.583115]Failed

SHA-256 / 43ad161be0e410e40fa27511f513ad168c5ee87e2d8628b2717c87beb9922bff

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/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*(2*k1[i]+k2[i]+k3[i]+2*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 fixtureActualExpectedOutcome
fixed-step rk4 two-body propagation [[7000.0, 0.0], [0.0, 7.546], 398600.4418, 600.0, 12][5586.354452, 4217.983348, -4.547126, 6.022138][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.8542, 6610.25849, -5.692121, 5.333629][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][-6592.629342, 6760.021357, -4.170853, -4.187641][-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.989406, 0.141454, -0.141381, -0.990209][-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.103745, 1.110826, -0.391453, -0.36593][-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.151903, -0.714157, 1.394353, 0.051026][-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.731173, 3315.830118, -3.439524, 6.583286][6111.623093, 3316.078893, -3.439749, 6.583115]Failed

SHA-256 / 44935ed3e6763cbeef3c49e3fe081f1e4718f4f7559df2c96c24fe980f454196

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 fixtureActualExpectedOutcome
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.189794+00:00.

Case digest / 81f97beba7af6c29f6c15538e815d9a34b637f83fc369ba2d7e4cc6d03e8e010