exp: 轮次32——均匀细分认证一次调用可证段内碰撞,界经720项检验未证伪,但P50≤20ms的档只能证出54~63%

- certify_uniform:固定 n 个子段一次 gaps 调用,判据与二分同源(子段界=整段界/n),证不出即拒
- 确定界反证:48段×121点×15组对=720项检验 0 违例;有信息量仅 61 项,最紧仍高出 0.035 mm
  (是"未能在真实运动上证伪",不是证明;浮点误差仍未形式化)
- 第180题 1.08-1.10s 漏检段在每个 n>=8 均判碰撞;二次加密(2n+1)反证 0 误放行
- 更正轮次31的"自适应cap无收益":旧公式 bound/2+eps 会把本可通过的子段钳成不可证;
  改为 bound+2eps 后交错实测决策不变、快 1.36~1.65x(n=8 13.13→9.68,n=128 98.46→59.76 ms)
- 负结论:只有 n<=16 能把认证压进 20 ms,但该档仅证出 26-30/48 根,其余必须刹停;
  成本=log(bound/间隙) 决定,故下一步要在反馈后限幅并让安全层要求正余量(现 cap=0.5 会截掉余量)
- 测试 23→26 项:n=5拒/n=6受的解析对照、cap_required 公式、n 张量类型门
This commit is contained in:
cbb
2026-10-20 19:30:02 +08:00
parent 6de085fd37
commit c6b46b8bb1
6 changed files with 389 additions and 4 deletions
+41
View File
@@ -477,6 +477,47 @@ class SegmentCertificateTest(unittest.TestCase):
self.assertEqual(result['collision'].tolist(), [True, False])
self.assertEqual(result['outside_box'].tolist(), [False, True])
def test_uniform_matches_bound_formula_and_needs_no_round_trips(self):
class ConstantGap(self.ThinObstacle):
def gaps(self, q, cap):
return {'gm': torch.full((q.shape[0], 1), 0.1, dtype=q.dtype, device=q.device)}
# 界 1 mm/度、间隙 0.1 mm:子段判据 0.2 > 1/n 需要 n ≥ 6,n=5 必须落 unproven。
kin = ConstantGap()
kin.cert_lever = torch.ones(1, 6, dtype=torch.float64)
a, b = torch.zeros(1, 6, dtype=torch.float64), torch.zeros(1, 6, dtype=torch.float64)
b[:, 0] = 1.0
for n, safe in ((5, False), (6, True)):
with self.subTest(n=n):
result = kin.certify_uniform(a, b, n=n)
self.assertEqual(bool(result['safe'].item()), safe)
self.assertEqual(result['points'], n + 1)
self.assertFalse(bool(result['collision'].item()))
self.assertEqual(bool(result['unproven'].item()), not safe)
self.assertAlmostEqual(result['cap_required_mm'], 1.0 / n + 2e-4, places=9)
def test_uniform_catches_hidden_collision_and_rejects_short_grids(self):
a = torch.tensor([[0.0, 0, 0, 0, 0, 0], [-1.0, 0, 0, 0, 0, 0], [6.0, 0, 0, 0, 0, 0]], dtype=torch.float64)
b = torch.tensor([[1.0, 0, 0, 0, 0, 0], [0.0, 0, 0, 0, 0, 0], [6.0, 0, 0, 0, 0, 0]], dtype=torch.float64)
kin = self.ThinObstacle()
short = kin.certify_uniform(a, b, n=2)
self.assertEqual(short['collision'].tolist(), [False, False, False])
self.assertEqual(short['unproven'].tolist(), [True, False, False])
self.assertEqual(short['safe'].tolist(), [False, True, False])
for n in (4, 8, 64):
with self.subTest(n=n):
result = kin.certify_uniform(a, b, n=n)
self.assertEqual(result['collision'].tolist(), [True, False, False])
self.assertEqual(result['safe'].tolist(), [False, True, False])
self.assertEqual(result['outside_box'].tolist(), [False, False, True])
def test_uniform_requires_plain_int_count(self):
a = torch.zeros(1, 6, dtype=torch.float64)
for tensor in (torch.tensor(8, dtype=torch.uint8), torch.tensor(8)):
with self.subTest(dtype=tensor.dtype):
with self.assertRaisesRegex(ValueError, 'subdivision count'):
self.ThinObstacle().certify_uniform(a, a.clone(), n=tensor)
def test_nonfinite_and_outside_box_are_rejected(self):
a, b = torch.zeros(1, 6, dtype=torch.float64), torch.zeros(1, 6, dtype=torch.float64)
kin = self.ThinObstacle()