FA-87166 / Physics integrator stability / Open access
Hamilton product x component has a flipped cross term · case 01
Rotations about combined axes drift into the wrong orientation.
ROOT CAUSE
The x row uses az*by - ay*bz instead of ay*bz - az*by.
VERIFIED REPAIR
Use the Hamilton cross product sign pattern.
Unsuccessful approach: Flipping the y row as well leaves the product non-Hamiltonian.
Case contract
solve(q, omega, dt, steps): orientation quaternion [w,x,y,z], world-frame angular velocity omega. Each step q += 0.5*dt*(0,omega) (x) q (Hamilton product, omega on the left), then renormalize to unit length. Return q with w>=0 (negate all components otherwise), rounded to 6.
Why this case matters
Game and robotics physics loops depend on integrator update order, step control and stabilization terms; a wrong decision point turns a stable simulation into drifting or exploding motion.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(q, omega, dt, steps):
def mul(a, b):
aw, ax, ay, az = a
bw, bx, by, bz = b
return [aw * bw - ax * bx - ay * by - az * bz,
aw * bx + ax * bw + az * by - ay * bz,
aw * by - ax * bz + ay * bw + az * bx,
aw * bz + ax * by - ay * bx + az * bw]
w = [0.0, omega[0], omega[1], omega[2]]
q = list(q)
for _ in range(steps):
d = mul(w, q)
q = [q[i] + 0.5 * dt * d[i] for i in range(4)]
n = math.sqrt(sum(c * c for c in q))
q = [c / n for c in q]
if q[0] < 0:
q = [-c for c in q]
return [round(c, 6) for c in q]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[[0.6563, -0.5379, 0.1174, 0.516], [0.015, -0.619, 1.039], 0.01, 5], [0.644583, -0.548412, 0.093024, 0.524503]], [[[0.1235, -0.981, -0.116, 0.0948], [1.519, -1.533, 2.819], 0.01, 6], [0.154086, -0.964359, -0.208115, 0.054383]], [[[0.1693, 0.5991, -0.3007, 0.7225], [-0.846, 0.203, 2.272], 0.1, 5], [0.11186, -0.653252, -0.222024, -0.71516]], [[[0.6072, -0.5005, 0.5315, 0.3134], [1.6, -3.217, 1.242], 0.01, 1], [0.617725, -0.503917, 0.516049, 0.313331]], [[[0.5438, 0.3302, -0.6582, 0.4024], [-2.872, -3.023, 2.126], 0.05, 4], [0.303775, 0.162656, -0.567546, 0.747767]], [[[-0.1116, -0.6859, -0.2807, 0.6621], [-1.367, -3.32, -3.869], 0.05, 1], [0.093483, 0.757592, 0.180891, -0.620156]], [[[0.5349, -0.3744, -0.6387, 0.4072], [-0.936, -1.882, -0.151], 0.05, 3], [0.41698, -0.471473, -0.673199, 0.38813]], [[[-0.0338, 0.1865, -0.2552, 0.9481], [3.457, -3.539, -0.052], 0.01, 6], [0.078214, -0.080294, 0.347067, -0.931118]]], [[[[-0.4028, 0.5372, 0.3775, -0.6377], [-2.487, -2.209, -0.784], 0.05, 1], [0.359741, -0.602665, -0.348298, 0.621346]], [[[0.4218, -0.8363, 0.1821, 0.2993], [-3.711, -0.391, -3.005], 0.05, 3], [0.239269, -0.866299, 0.423283, 0.114486]], [[[0.5749, 0.031, -0.4898, -0.6547], [-0.506, -3.611, 3.157], 0.01, 8], [0.576713, 0.174281, -0.5725, -0.556122]], [[[-0.684, -0.374, 0.0005, 0.6263], [-1.423, 0.536, 3.994], 0.01, 1], [0.699016, 0.367384, 0.004345, -0.613504]], [[[0.4128, -0.1945, -0.732, -0.5058], [2.801, 3.769, 1.981], 0.1, 5], [0.932232, 0.068462, 0.248894, -0.25359]], [[[0.0263, -0.6798, 0.6943, 0.2347], [-2.851, -1.309, 1.331], 0.01, 4], [0.000571, 0.704341, -0.687306, -0.177522]], [[[-0.0016, -0.616, -0.6804, -0.397], [3.345, 1.581, 1.376], 0.01, 8], [0.145089, -0.596259, -0.652903, -0.444007]], [[[0.8268, -0.0559, 0.3935, 0.398], [-0.387, 0.922, 1.986], 0.1, 7], [0.220922, -0.271091, 0.534556, 0.769385]]], [[[[0.6214, 0.2422, 0.3472, 0.6592], [1.095, -0.904, -2.267], 0.01, 5], [0.658593, 0.263446, 0.300661, 0.637538]], [[[-0.571, 0.1155, 0.5121, 0.6312], [2.085, -1.83, -1.285], 0.01, 1], [0.563386, -0.107047, -0.509932, -0.641176]], [[[-0.3438, -0.8064, 0.2793, -0.3918], [0.487, -0.414, 0.563], 0.05, 6], [0.231973, 0.824132, -0.258947, 0.447149]], [[[0.3014, -0.7802, -0.2933, -0.4631], [1.628, 1.091, -0.63], 0.05, 2], [0.364549, -0.786003, -0.21324, -0.451477]], [[[0.4999, -0.5863, 0.4671, 0.4339], [2.074, -2.687, 0.552], 0.01, 9], [0.593908, -0.596606, 0.346469, 0.413876]], [[[0.949, -0.2888, -0.074, -0.1024], [-3.298, -2.046, 1.094], 0.05, 3], [0.833212, -0.484823, -0.261738, -0.046885]], [[[-0.5736, 0.5131, -0.6375, 0.0369], [2.905, 3.624, -3.693], 0.05, 3], [0.449619, -0.183744, 0.870315, 0.081437]], [[[-0.5755, -0.1729, 0.1896, -0.7765], [-1.564, 1.954, -3.317], 0.01, 5], [0.652658, 0.171677, -0.144528, 0.723655]]], [[[[0.2873, -0.6346, 0.6402, -0.324], [3.029, -0.324, 1.16], 0.1, 8], [0.817944, -0.105726, 0.220751, 0.520633]], [[[0.901, -0.336, 0.2743, 0.007], [-1.047, -0.713, 1.265], 0.05, 9], [0.792871, -0.592602, 0.020393, 0.140583]], [[[-0.1627, -0.9669, 0.1492, 0.1278], [0.371, -1.685, -1.491], 0.01, 3], [0.150601, 0.967152, -0.174136, -0.107763]], [[[0.1401, -0.0998, 0.7197, 0.6726], [-3.242, -3.373, -3.717], 0.01, 11], [0.381235, -0.097044, 0.793491, 0.464343]], [[[0.5409, 0.1216, -0.7667, 0.3238], [1.625, -0.383, -1.461], 0.01, 8], [0.538036, 0.106531, -0.80006, 0.243047]], [[[0.2307, 0.3931, 0.7631, -0.4581], [2.174, 2.113, 3.444], 0.05, 10], [0.080385, 0.450009, -0.879659, -0.131262]], [[[0.5143, 0.5985, 0.4636, 0.403], [0.712, 0.864, -0.232], 0.01, 12], [0.469125, 0.646356, 0.463613, 0.383679]], [[[-0.5635, 0.5002, 0.4475, 0.4817], [2.041, 1.454, 2.295], 0.05, 8], [0.951465, -0.116995, -0.227714, -0.170799]]], [[[[-0.3844, 0.367, -0.6816, 0.503], [2.698, 2.563, -0.07], 0.05, 2], [0.338535, -0.370823, 0.787267, -0.357905]], [[[0.0332, -0.1691, -0.7704, -0.6138], [2.17, 2.479, 1.5], 0.1, 9], [0.881211, -0.074251, 0.351735, -0.30698]], [[[0.1785, -0.1228, -0.7653, 0.6061], [2.105, 0.281, 2.09], 0.01, 8], [0.145584, -0.036317, -0.819027, 0.553788]], [[[0.5273, 0.4224, -0.4746, 0.5641], [-2.08, 3.628, 3.896], 0.01, 13], [0.516939, 0.571342, -0.141768, 0.621485]], [[[0.7695, 0.3041, -0.5589, 0.0545], [2.708, 2.922, -1.672], 0.1, 1], [0.796192, 0.361206, -0.468484, -0.127008]], [[[0.5117, 0.4864, 0.6756, 0.2125], [1.266, 1.391, -2.594], 0.01, 8], [0.467441, 0.589939, 0.637389, 0.164941]], [[[0.6026, -0.382, 0.0313, 0.6999], [3.445, -2.631, 3.472], 0.1, 4], [0.118045, -0.158866, -0.832236, 0.51789]], [[[0.1606, -0.6566, -0.6071, -0.4179], [3.302, 3.764, -3.923], 0.05, 6], [0.452728, -0.820608, 0.226546, -0.265173]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("case %d" % i, 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 |
|---|---|---|---|
| case 0 | [0.652162, -0.532939, 0.094348, 0.530809] | [0.644583, -0.548412, 0.093024, 0.524503] | Failed |
| case 1 | [0.15158, -0.96552, -0.204873, 0.053113] | [0.154086, -0.964359, -0.208115, 0.054383] | Failed |
| case 2 | [0.154211, -0.531246, -0.17582, -0.814299] | [0.11186, -0.653252, -0.222024, -0.71516] | Failed |
| case 3 | [0.622896, -0.491315, 0.520369, 0.315953] | [0.617725, -0.503917, 0.516049, 0.313331] | Failed |
| case 4 | [0.300984, 0.217381, -0.560776, 0.740057] | [0.303775, 0.162656, -0.567546, 0.747767] | Failed |
| case 5 | [0.105859, 0.673547, 0.204839, -0.70226] | [0.093483, 0.757592, 0.180891, -0.620156] | Failed |
| case 6 | [0.441798, -0.361483, -0.708669, 0.414648] | [0.41698, -0.471473, -0.673199, 0.38813] | Failed |
| case 7 | [0.08322, -0.269223, 0.332431, -0.900046] | [0.078214, -0.080294, 0.347067, -0.931118] | Failed |
SHA-256 / 54dabe1a20016a3a95f44d1235b4eb4d03768f4c5fbc63df26bf5a74730fcd70
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(q, omega, dt, steps):
def mul(a, b):
aw, ax, ay, az = a
bw, bx, by, bz = b
return [aw * bw - ax * bx - ay * by - az * bz,
aw * bx + ax * bw + az * by - ay * bz,
aw * by + ax * bz + ay * bw - az * bx,
aw * bz + ax * by - ay * bx + az * bw]
w = [0.0, omega[0], omega[1], omega[2]]
q = list(q)
for _ in range(steps):
d = mul(w, q)
q = [q[i] + 0.5 * dt * d[i] for i in range(4)]
n = math.sqrt(sum(c * c for c in q))
q = [c / n for c in q]
if q[0] < 0:
q = [-c for c in q]
return [round(c, 6) for c in q]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[[0.6563, -0.5379, 0.1174, 0.516], [0.015, -0.619, 1.039], 0.01, 5], [0.644583, -0.548412, 0.093024, 0.524503]], [[[0.1235, -0.981, -0.116, 0.0948], [1.519, -1.533, 2.819], 0.01, 6], [0.154086, -0.964359, -0.208115, 0.054383]], [[[0.1693, 0.5991, -0.3007, 0.7225], [-0.846, 0.203, 2.272], 0.1, 5], [0.11186, -0.653252, -0.222024, -0.71516]], [[[0.6072, -0.5005, 0.5315, 0.3134], [1.6, -3.217, 1.242], 0.01, 1], [0.617725, -0.503917, 0.516049, 0.313331]], [[[0.5438, 0.3302, -0.6582, 0.4024], [-2.872, -3.023, 2.126], 0.05, 4], [0.303775, 0.162656, -0.567546, 0.747767]], [[[-0.1116, -0.6859, -0.2807, 0.6621], [-1.367, -3.32, -3.869], 0.05, 1], [0.093483, 0.757592, 0.180891, -0.620156]], [[[0.5349, -0.3744, -0.6387, 0.4072], [-0.936, -1.882, -0.151], 0.05, 3], [0.41698, -0.471473, -0.673199, 0.38813]], [[[-0.0338, 0.1865, -0.2552, 0.9481], [3.457, -3.539, -0.052], 0.01, 6], [0.078214, -0.080294, 0.347067, -0.931118]]], [[[[-0.4028, 0.5372, 0.3775, -0.6377], [-2.487, -2.209, -0.784], 0.05, 1], [0.359741, -0.602665, -0.348298, 0.621346]], [[[0.4218, -0.8363, 0.1821, 0.2993], [-3.711, -0.391, -3.005], 0.05, 3], [0.239269, -0.866299, 0.423283, 0.114486]], [[[0.5749, 0.031, -0.4898, -0.6547], [-0.506, -3.611, 3.157], 0.01, 8], [0.576713, 0.174281, -0.5725, -0.556122]], [[[-0.684, -0.374, 0.0005, 0.6263], [-1.423, 0.536, 3.994], 0.01, 1], [0.699016, 0.367384, 0.004345, -0.613504]], [[[0.4128, -0.1945, -0.732, -0.5058], [2.801, 3.769, 1.981], 0.1, 5], [0.932232, 0.068462, 0.248894, -0.25359]], [[[0.0263, -0.6798, 0.6943, 0.2347], [-2.851, -1.309, 1.331], 0.01, 4], [0.000571, 0.704341, -0.687306, -0.177522]], [[[-0.0016, -0.616, -0.6804, -0.397], [3.345, 1.581, 1.376], 0.01, 8], [0.145089, -0.596259, -0.652903, -0.444007]], [[[0.8268, -0.0559, 0.3935, 0.398], [-0.387, 0.922, 1.986], 0.1, 7], [0.220922, -0.271091, 0.534556, 0.769385]]], [[[[0.6214, 0.2422, 0.3472, 0.6592], [1.095, -0.904, -2.267], 0.01, 5], [0.658593, 0.263446, 0.300661, 0.637538]], [[[-0.571, 0.1155, 0.5121, 0.6312], [2.085, -1.83, -1.285], 0.01, 1], [0.563386, -0.107047, -0.509932, -0.641176]], [[[-0.3438, -0.8064, 0.2793, -0.3918], [0.487, -0.414, 0.563], 0.05, 6], [0.231973, 0.824132, -0.258947, 0.447149]], [[[0.3014, -0.7802, -0.2933, -0.4631], [1.628, 1.091, -0.63], 0.05, 2], [0.364549, -0.786003, -0.21324, -0.451477]], [[[0.4999, -0.5863, 0.4671, 0.4339], [2.074, -2.687, 0.552], 0.01, 9], [0.593908, -0.596606, 0.346469, 0.413876]], [[[0.949, -0.2888, -0.074, -0.1024], [-3.298, -2.046, 1.094], 0.05, 3], [0.833212, -0.484823, -0.261738, -0.046885]], [[[-0.5736, 0.5131, -0.6375, 0.0369], [2.905, 3.624, -3.693], 0.05, 3], [0.449619, -0.183744, 0.870315, 0.081437]], [[[-0.5755, -0.1729, 0.1896, -0.7765], [-1.564, 1.954, -3.317], 0.01, 5], [0.652658, 0.171677, -0.144528, 0.723655]]], [[[[0.2873, -0.6346, 0.6402, -0.324], [3.029, -0.324, 1.16], 0.1, 8], [0.817944, -0.105726, 0.220751, 0.520633]], [[[0.901, -0.336, 0.2743, 0.007], [-1.047, -0.713, 1.265], 0.05, 9], [0.792871, -0.592602, 0.020393, 0.140583]], [[[-0.1627, -0.9669, 0.1492, 0.1278], [0.371, -1.685, -1.491], 0.01, 3], [0.150601, 0.967152, -0.174136, -0.107763]], [[[0.1401, -0.0998, 0.7197, 0.6726], [-3.242, -3.373, -3.717], 0.01, 11], [0.381235, -0.097044, 0.793491, 0.464343]], [[[0.5409, 0.1216, -0.7667, 0.3238], [1.625, -0.383, -1.461], 0.01, 8], [0.538036, 0.106531, -0.80006, 0.243047]], [[[0.2307, 0.3931, 0.7631, -0.4581], [2.174, 2.113, 3.444], 0.05, 10], [0.080385, 0.450009, -0.879659, -0.131262]], [[[0.5143, 0.5985, 0.4636, 0.403], [0.712, 0.864, -0.232], 0.01, 12], [0.469125, 0.646356, 0.463613, 0.383679]], [[[-0.5635, 0.5002, 0.4475, 0.4817], [2.041, 1.454, 2.295], 0.05, 8], [0.951465, -0.116995, -0.227714, -0.170799]]], [[[[-0.3844, 0.367, -0.6816, 0.503], [2.698, 2.563, -0.07], 0.05, 2], [0.338535, -0.370823, 0.787267, -0.357905]], [[[0.0332, -0.1691, -0.7704, -0.6138], [2.17, 2.479, 1.5], 0.1, 9], [0.881211, -0.074251, 0.351735, -0.30698]], [[[0.1785, -0.1228, -0.7653, 0.6061], [2.105, 0.281, 2.09], 0.01, 8], [0.145584, -0.036317, -0.819027, 0.553788]], [[[0.5273, 0.4224, -0.4746, 0.5641], [-2.08, 3.628, 3.896], 0.01, 13], [0.516939, 0.571342, -0.141768, 0.621485]], [[[0.7695, 0.3041, -0.5589, 0.0545], [2.708, 2.922, -1.672], 0.1, 1], [0.796192, 0.361206, -0.468484, -0.127008]], [[[0.5117, 0.4864, 0.6756, 0.2125], [1.266, 1.391, -2.594], 0.01, 8], [0.467441, 0.589939, 0.637389, 0.164941]], [[[0.6026, -0.382, 0.0313, 0.6999], [3.445, -2.631, 3.472], 0.1, 4], [0.118045, -0.158866, -0.832236, 0.51789]], [[[0.1606, -0.6566, -0.6071, -0.4179], [3.302, 3.764, -3.923], 0.05, 6], [0.452728, -0.820608, 0.226546, -0.265173]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("case %d" % i, 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 |
|---|---|---|---|
| case 0 | [0.650361, -0.531027, 0.122401, 0.529206] | [0.644583, -0.548412, 0.093024, 0.524503] | Failed |
| case 1 | [0.158833, -0.984942, -0.036067, 0.057972] | [0.154086, -0.964359, -0.208115, 0.054383] | Failed |
| case 2 | [0.122694, -0.236778, 0.639024, -0.721478] | [0.11186, -0.653252, -0.222024, -0.71516] | Failed |
| case 3 | [0.619219, -0.488414, 0.528553, 0.314088] | [0.617725, -0.503917, 0.516049, 0.313331] | Failed |
| case 4 | [0.197911, 0.148177, -0.757344, 0.604404] | [0.303775, 0.162656, -0.567546, 0.747767] | Failed |
| case 5 | [0.09995, 0.635948, 0.382013, -0.663058] | [0.093483, 0.757592, 0.180891, -0.620156] | Failed |
| case 6 | [0.418345, -0.344511, -0.740709, 0.397052] | [0.41698, -0.471473, -0.673199, 0.38813] | Failed |
| case 7 | [0.077915, -0.28037, 0.15018, -0.944864] | [0.078214, -0.080294, 0.347067, -0.931118] | Failed |
SHA-256 / 4fdef7a1de6dbce248cd5840f0b9337eff9f64276670fd6baeab335a87e22993
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(q, omega, dt, steps):
def mul(a, b):
aw, ax, ay, az = a
bw, bx, by, bz = b
return [aw * bw - ax * bx - ay * by - az * bz,
aw * bx + ax * bw + ay * bz - az * by,
aw * by - ax * bz + ay * bw + az * bx,
aw * bz + ax * by - ay * bx + az * bw]
w = [0.0, omega[0], omega[1], omega[2]]
q = list(q)
for _ in range(steps):
d = mul(w, q)
q = [q[i] + 0.5 * dt * d[i] for i in range(4)]
n = math.sqrt(sum(c * c for c in q))
q = [c / n for c in q]
if q[0] < 0:
q = [-c for c in q]
return [round(c, 6) for c in q]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[[0.6563, -0.5379, 0.1174, 0.516], [0.015, -0.619, 1.039], 0.01, 5], [0.644583, -0.548412, 0.093024, 0.524503]], [[[0.1235, -0.981, -0.116, 0.0948], [1.519, -1.533, 2.819], 0.01, 6], [0.154086, -0.964359, -0.208115, 0.054383]], [[[0.1693, 0.5991, -0.3007, 0.7225], [-0.846, 0.203, 2.272], 0.1, 5], [0.11186, -0.653252, -0.222024, -0.71516]], [[[0.6072, -0.5005, 0.5315, 0.3134], [1.6, -3.217, 1.242], 0.01, 1], [0.617725, -0.503917, 0.516049, 0.313331]], [[[0.5438, 0.3302, -0.6582, 0.4024], [-2.872, -3.023, 2.126], 0.05, 4], [0.303775, 0.162656, -0.567546, 0.747767]], [[[-0.1116, -0.6859, -0.2807, 0.6621], [-1.367, -3.32, -3.869], 0.05, 1], [0.093483, 0.757592, 0.180891, -0.620156]], [[[0.5349, -0.3744, -0.6387, 0.4072], [-0.936, -1.882, -0.151], 0.05, 3], [0.41698, -0.471473, -0.673199, 0.38813]], [[[-0.0338, 0.1865, -0.2552, 0.9481], [3.457, -3.539, -0.052], 0.01, 6], [0.078214, -0.080294, 0.347067, -0.931118]]], [[[[-0.4028, 0.5372, 0.3775, -0.6377], [-2.487, -2.209, -0.784], 0.05, 1], [0.359741, -0.602665, -0.348298, 0.621346]], [[[0.4218, -0.8363, 0.1821, 0.2993], [-3.711, -0.391, -3.005], 0.05, 3], [0.239269, -0.866299, 0.423283, 0.114486]], [[[0.5749, 0.031, -0.4898, -0.6547], [-0.506, -3.611, 3.157], 0.01, 8], [0.576713, 0.174281, -0.5725, -0.556122]], [[[-0.684, -0.374, 0.0005, 0.6263], [-1.423, 0.536, 3.994], 0.01, 1], [0.699016, 0.367384, 0.004345, -0.613504]], [[[0.4128, -0.1945, -0.732, -0.5058], [2.801, 3.769, 1.981], 0.1, 5], [0.932232, 0.068462, 0.248894, -0.25359]], [[[0.0263, -0.6798, 0.6943, 0.2347], [-2.851, -1.309, 1.331], 0.01, 4], [0.000571, 0.704341, -0.687306, -0.177522]], [[[-0.0016, -0.616, -0.6804, -0.397], [3.345, 1.581, 1.376], 0.01, 8], [0.145089, -0.596259, -0.652903, -0.444007]], [[[0.8268, -0.0559, 0.3935, 0.398], [-0.387, 0.922, 1.986], 0.1, 7], [0.220922, -0.271091, 0.534556, 0.769385]]], [[[[0.6214, 0.2422, 0.3472, 0.6592], [1.095, -0.904, -2.267], 0.01, 5], [0.658593, 0.263446, 0.300661, 0.637538]], [[[-0.571, 0.1155, 0.5121, 0.6312], [2.085, -1.83, -1.285], 0.01, 1], [0.563386, -0.107047, -0.509932, -0.641176]], [[[-0.3438, -0.8064, 0.2793, -0.3918], [0.487, -0.414, 0.563], 0.05, 6], [0.231973, 0.824132, -0.258947, 0.447149]], [[[0.3014, -0.7802, -0.2933, -0.4631], [1.628, 1.091, -0.63], 0.05, 2], [0.364549, -0.786003, -0.21324, -0.451477]], [[[0.4999, -0.5863, 0.4671, 0.4339], [2.074, -2.687, 0.552], 0.01, 9], [0.593908, -0.596606, 0.346469, 0.413876]], [[[0.949, -0.2888, -0.074, -0.1024], [-3.298, -2.046, 1.094], 0.05, 3], [0.833212, -0.484823, -0.261738, -0.046885]], [[[-0.5736, 0.5131, -0.6375, 0.0369], [2.905, 3.624, -3.693], 0.05, 3], [0.449619, -0.183744, 0.870315, 0.081437]], [[[-0.5755, -0.1729, 0.1896, -0.7765], [-1.564, 1.954, -3.317], 0.01, 5], [0.652658, 0.171677, -0.144528, 0.723655]]], [[[[0.2873, -0.6346, 0.6402, -0.324], [3.029, -0.324, 1.16], 0.1, 8], [0.817944, -0.105726, 0.220751, 0.520633]], [[[0.901, -0.336, 0.2743, 0.007], [-1.047, -0.713, 1.265], 0.05, 9], [0.792871, -0.592602, 0.020393, 0.140583]], [[[-0.1627, -0.9669, 0.1492, 0.1278], [0.371, -1.685, -1.491], 0.01, 3], [0.150601, 0.967152, -0.174136, -0.107763]], [[[0.1401, -0.0998, 0.7197, 0.6726], [-3.242, -3.373, -3.717], 0.01, 11], [0.381235, -0.097044, 0.793491, 0.464343]], [[[0.5409, 0.1216, -0.7667, 0.3238], [1.625, -0.383, -1.461], 0.01, 8], [0.538036, 0.106531, -0.80006, 0.243047]], [[[0.2307, 0.3931, 0.7631, -0.4581], [2.174, 2.113, 3.444], 0.05, 10], [0.080385, 0.450009, -0.879659, -0.131262]], [[[0.5143, 0.5985, 0.4636, 0.403], [0.712, 0.864, -0.232], 0.01, 12], [0.469125, 0.646356, 0.463613, 0.383679]], [[[-0.5635, 0.5002, 0.4475, 0.4817], [2.041, 1.454, 2.295], 0.05, 8], [0.951465, -0.116995, -0.227714, -0.170799]]], [[[[-0.3844, 0.367, -0.6816, 0.503], [2.698, 2.563, -0.07], 0.05, 2], [0.338535, -0.370823, 0.787267, -0.357905]], [[[0.0332, -0.1691, -0.7704, -0.6138], [2.17, 2.479, 1.5], 0.1, 9], [0.881211, -0.074251, 0.351735, -0.30698]], [[[0.1785, -0.1228, -0.7653, 0.6061], [2.105, 0.281, 2.09], 0.01, 8], [0.145584, -0.036317, -0.819027, 0.553788]], [[[0.5273, 0.4224, -0.4746, 0.5641], [-2.08, 3.628, 3.896], 0.01, 13], [0.516939, 0.571342, -0.141768, 0.621485]], [[[0.7695, 0.3041, -0.5589, 0.0545], [2.708, 2.922, -1.672], 0.1, 1], [0.796192, 0.361206, -0.468484, -0.127008]], [[[0.5117, 0.4864, 0.6756, 0.2125], [1.266, 1.391, -2.594], 0.01, 8], [0.467441, 0.589939, 0.637389, 0.164941]], [[[0.6026, -0.382, 0.0313, 0.6999], [3.445, -2.631, 3.472], 0.1, 4], [0.118045, -0.158866, -0.832236, 0.51789]], [[[0.1606, -0.6566, -0.6071, -0.4179], [3.302, 3.764, -3.923], 0.05, 6], [0.452728, -0.820608, 0.226546, -0.265173]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("case %d" % i, 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 |
|---|---|---|---|
| case 0 | [0.644583, -0.548412, 0.093024, 0.524503] | [0.644583, -0.548412, 0.093024, 0.524503] | Passed |
| case 1 | [0.154086, -0.964359, -0.208115, 0.054383] | [0.154086, -0.964359, -0.208115, 0.054383] | Passed |
| case 2 | [0.11186, -0.653252, -0.222024, -0.71516] | [0.11186, -0.653252, -0.222024, -0.71516] | Passed |
| case 3 | [0.617725, -0.503917, 0.516049, 0.313331] | [0.617725, -0.503917, 0.516049, 0.313331] | Passed |
| case 4 | [0.303775, 0.162656, -0.567546, 0.747767] | [0.303775, 0.162656, -0.567546, 0.747767] | Passed |
| case 5 | [0.093483, 0.757592, 0.180891, -0.620156] | [0.093483, 0.757592, 0.180891, -0.620156] | Passed |
| case 6 | [0.41698, -0.471473, -0.673199, 0.38813] | [0.41698, -0.471473, -0.673199, 0.38813] | Passed |
| case 7 | [0.078214, -0.080294, 0.347067, -0.931118] | [0.078214, -0.080294, 0.347067, -0.931118] | Passed |
SHA-256 / 3d2ad33052ec1c79510fa7727fc2b9604f8add55764bfbe0df50061c49e4a7bf
Verification & scope
A deterministic bounded teaching model with stipulated toy conventions and rounded float output; not a production physics engine or a proof of numerical stability. 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:50:56.336784+00:00.
Case digest / ef51cd14a2dfc8082184921978fbdf97e1d7569f68758ec81f88c88b2822e38f