· engineering· 约 26 分钟精读
四个门按钮的边界:QubitLab 单比特关卡的门集闭包、目标常量与球面投影
十二个单比特关卡里,H、X、Z、S 四个按钮最多把态送到六个方向。本文按源码逐关核对门集的群闭包、十二个目标常量、三档保真度阈值与画布上的四套投影常数,并把文案与代码不同源的四处摆在同一张表上。
手机屏幕上,一个量子门按钮被按下的瞬间,发生的事情比它看起来少得多。少的是硬件:没有微波脉冲,没有读出谐振腔;多的是几何:一次对两个角度参数的确定性改写,随后由一个标量决定这次改写算不算数。
十月的行业消息里有一条适合放在这里的对照。北京量子信息科学研究院于十月二十二日发布超导量子计算机测控链路系统招标公告。真实超导机器上,一个门由测控链路按定时发出的一段脉冲实现,脉冲形状、幅度校准、串扰补偿和读出窗口都属于工程交付物。手机里的门没有这些,它只有一条把态矢从一个方向转到另一个方向的算术。两者共享同一套群论语言,但工程边界完全不同。把这条边界写清楚,比把它说得更大更有价值。
本文审查密旋科技 QubitLab 中十二个单比特关卡的判定链路。十二个关卡指第 3 章的第十七至二十四关,以及第六十七、六十八、八十三、八十四四个衔接关;它们在关卡分派表里的类型标记全部为 qubitHacker,共用同一个视图。审查对象是这条链上的四段:输入通道、门层、目标常量与阈值、画布投影。所有结论都可以在源码里逐行核对,本文不引入任何源码没有声明的能力。
一、审查范围与证据口径
涉及的源文件有六个:QubitHackerGameView.swift(六百六十二行,关卡视图与判定函数)、QuantumState.swift(单比特状态与四个门的实现)、QuantumModels.swift(视图模型包装)、OdysseyModel.swift(十二个关卡的目标文案与初始态)、BlochSphereCanvas.swift(九十三行的球面绘制)、LevelPlayView.swift(星级与通关回调)。
证据口径需要先说明。第一,本文只讨论这些 Swift 文件里能读到的行为,不推断未提交的分支。第二,凡是”屏幕上会怎样”的判断,都以视图体里真实挂载的控件为准,不以函数名或注释为准。第三,保真度、角度、误判率三类数字都是按源码里的公式重算的,重算脚本与公式一并写在正文里,读者可以自行复现。
二、两根滑杆:可以抵达任意方向的通道
关卡视图底部有两根滑杆。极角滑杆的区间是零到 π,步长零点零二弧度;方位角滑杆的区间是零到二倍 π,步长零点零五弧度。它们的 setter 直接写状态参数,不经过任何门函数:
这两行赋值意味着,滑杆是关卡里唯一能抵达任意方向的通道。四个门按钮只能在有限个方向之间跳,滑杆则可以停在球面上任意一点(受步长量化限制)。
步长带来的量化误差需要算一下。纯态保真度与两矢夹角的关系是
其中 δ 是两个布洛赫矢量之间的夹角。对 δ 求导得到
极角滑杆的半步是零点零一弧度,方位角滑杆的半步是零点零二五弧度。代进上界,一次最小移动带来的保真度变化不超过零点零一二五,即一点二五个百分点;而实际落差通常小于这个上界,因为 sin δ 在目标附近往往远小于一。也就是说,两格之间的量化误差最多一个多百分点,远小于后文任何一档阈值。滑杆不是粗略调节,它在数值上足够精确。
这里有一个命名与实现不一致的细节。滑杆的 setter 里调用了一个名为 checkAutoWinWithoutMeasure 的函数,字面意思是”不测量也能自动判胜”。但函数体第一行就是 if measuredShotsCount >= 10——必须先击发过一次十发批次,它才会继续往下判。函数名描述的是设计意图,函数体描述的是实际行为,两者不是一回事。读者若只读函数名,会误以为滑杆可以独立通关。
三、四个门:二十四阶群与六点闭包
四个门的实现都不是矩阵乘法,而是对角度或直角坐标的直接改写。这一层值得先肯定:它们作为布洛赫球上的旋转是准确的。
| 门 | 源码写法 | 对直角坐标的作用 | 是否改变计算基概率 |
|---|---|---|---|
| H | 先判四个特殊角,否则交换 x 与 z 并翻转 y | (x, y, z) 变为 (z, −y, x) | 是,通常把态送到赤道或极点 |
| X | θ 变为 π − θ,φ 变为 −φ | (x, y, z) 变为 (x, −y, −z) | 是,交换两极 |
| Z | φ 增加 π | (x, y, z) 变为 (−x, −y, z) | 否,只改相对相位 |
| S | φ 增加 π/2 | (x, y, z) 变为 (−y, x, z) | 否,绕 z 轴转四分之一圈 |
这四组改写与 SU(2) 中对应矩阵在布洛赫球上的作用逐项一致。H 的实现有个分支结构:当极角接近零、接近 π,或态正好落在赤道两端时走特例,其余情况走通用式;两支的结果相同,特例只是为了避免在极点上做 atan2 时产生数值抖动。这一点是工程上的合理取舍,不是近似。
真正需要量的是这四个变换生成的集合有多大。把四个门当作三个维度的正交矩阵,从单位阵出发做广度优先搜索,闭包大小为二十四——这正是立方体的旋转对称群,也就是八面体群。它作用在球面上时,把球面分成三类轨道:六个顶点方向、八个面心方向、十二个棱中点方向。
关卡里的初始态全部落在第一类轨道上。resetQubit 的所有分支都从 qubit.reset() 开始(极角零、方位角零),再施加若干门;无论施加哪些,结果仍然落在六个顶点方向之一。因此仅用四个按钮,态只能在下面六个方向之间跳:
| 方向 | 极角 | 方位角 | 一条最短门序列 | 步数 |
|---|---|---|---|---|
| 北极 | 0° | 0° | 初始态 | 0 |
| 南极 | 180° | 0° | X | 1 |
| 正 x | 90° | 0° | H | 1 |
| 负 x | 90° | 180° | H 再接 Z | 2 |
| 正 y | 90° | 90° | H 再接 S | 2 |
| 负 y | 90° | 270° | H 再接 Z 再接 S | 3 |
这张表解释了一个容易被忽略的事实:十二个关卡虽然标题各异,按钮的”步法”是同一套。学习者按 H、X、Z、S 能到达的状态集合,与关卡编号无关,只与起点是不是六个顶点之一有关。若先用滑杆把态拖离顶点,可达集合才会扩展到二十四点轨道——但那时候已经用了滑杆,门按钮就不再是唯一的路径。
四、十二个关卡的目标台账
把 targetStateCoordinates 的每个分支抄下来,得到下面这张台账。第三列判断目标是否落在六点闭包内。
| 关卡 | 目标极角与方位角 | 是否在六点闭包内 | 判定阈值 |
|---|---|---|---|
| 17 位翻转 | 180° 与 0°,二阶为 0° 与 0° | 是 | 0.90,另加比例条件 |
| 18 叠加态 | 90° 与 0°,二阶为 90° 与 180° | 是 | 0.88,另加两桶非零 |
| 19 负相位态 | 90° 与 180°,二阶为 0° 与 0° | 是 | 0.88 |
| 20 相位翻转 | 90° 与 90°,二阶为 90° 与 180° | 是 | 0.88 |
| 21 四分之一转 | 120° 与 90° | 否 | 0.88 |
| 22 赤道导航 | 0° 与 0° | 是 | 0.92,另加比例条件 |
| 23 逆运算 | 90° 与 45° | 否 | 0.88 |
| 24 综合关 | 90° 与 0° | 是 | 0.88 |
| 67 量子罗盘 | 90° 与 45° | 否 | 0.88 |
| 68 旋转硬币 | 90° 与 0° | 是 | 0.88 |
| 83 全局与相对相位 | 90° 与 180° | 是 | 0.88 |
| 84 量子随机数 | 90° 与 0° | 是 | 0.88 |
九个目标落在六点上,三个落在点外。三个越界目标共用两个坐标:第二十一关的 120° 与 90°,以及第二十三关和第六十七关的 90° 与 45°。
这不是缺陷,而是设计事实:判定目标一旦是任意角度,门按钮就不可能是唯一解,必须有连续通道托底。问题在于托底通道存在时,门按钮的教学意图还剩多少。第二十一关里,S 只改方位角、不改极角,从北极按下它态矢动都不动;要抵达 120° 与 90°,按完门仍必须去拖极角滑杆。
五、阈值换算成角度
保真度门槛是一个纯数,学习者看到的却是一根指针与一个光点之间的夹角。把三档阈值代入前式反解,得到它们各自的容差角:
| 阈值 | 允许的夹角 | 使用该阈值的关卡数 |
|---|---|---|
| 0.88 | 40.5° | 10 |
| 0.90 | 36.9° | 1(第十七关) |
| 0.92 | 32.9° | 1(第二十二关) |
四十一度的容差意味着什么?在半径约一百二十点的球面上,态矢端点可以偏离目标四十度而仍被判为通过。这个宽度足以把”正 y 方向”(90° 与 90°)与”120° 与 90°“两个不同目标同时装进去——两者夹角正好三十度,保真度零点九三三,高于零点八八的门槛。这也解释了上一节的现象:第二十一关的文案要求把态转到正 y 轴,代码的目标常量是 120° 与 90°,两者相差三十度却都能过关。门槛的宽度掩盖了文案与常量之间的分歧。
把阈值和批次抽样放在一起看,还有一层统计噪声。第十八关要求零与一两个计数桶都至少为二,在真实概率二分之一时,单批十发出现”某一桶少于两发”的概率是百分之二点一五;第十七关要求优势结果占比不低于零点七,在保真度刚好零点九零(即真实概率零点九零)时,单批被误拒的概率是百分之一点二八;第二十二关要求零态占比不低于零点七五,在阈值边界(真实概率零点九二)时误拒概率是百分之四点零一。这些数字说明,同一份正确操作在边界上仍有三到四个百分点的概率被判失败,而失败提示统一写成”保真度未达标”。把统计涨落归因成”没对准”,是这条链上最容易让学习者困惑的一处。
重复击发会缓解这个问题:第二批发十发后,累计样本变成二十发,同样的比例条件几乎不可能连续两次不满足。但代价是样本数与判定口径脱钩——判定读的是累计桶,而不是”当前这批”。这一点在下一节还会遇到。
六、四处文案与常量不同源
把每个关卡的 targetGoal 文案与 targetStateCoordinates 的常量并排放,有四处对不上。
| 关卡 | 文案要求 | 代码目标 | 按文案操作的结果 |
|---|---|---|---|
| 21 | 用 S 门把态送到正 y 轴 | 120° 与 90° | 保真度 0.933,可通过 |
| 22 | 抵达 90° 与 90° 的虚数态 | 0° 与 0° | 保真度 0.50,无法通过 |
| 23 | 逆序还原到基态 | 90° 与 45° | 保真度 0.50,无法通过 |
| 24 | 综合保真度高于 99% | 90° 与 0°,阈值 0.88 | 通过,但门槛比文案低得多 |
第二十二与第二十三关的问题最直接:按文案操作,学习者会停在离目标九十度的位置,保真度恰为零点五零,无论击发多少次都过不了,而且每次都会收到”保真度未达标”的提示。第二十二关还有第二层错位:标题是赤道导航,初始态是赤道上的 |−i⟩,文案要求去 90° 与 90° 的 |+i⟩,而目标常量写回了北极。标题、文案、常量三者各说一件事。
第二十四关的方向相反:文案承诺 99%,代码只要求 88%。判定本身没错,只是按文案做到 99% 的学习者多做了一倍功。
这四处不同源有个共同的工程根源:文案写在 OdysseyModel 的关卡表里,常量写在视图的 switch 里,两者之间没有任何编译期或测试期的一致性约束。任何一侧单独修改,都不会惊动另一侧。
七、阶段二在八个关卡里空转
十二个关卡里有八个的第二阶段目标与第一阶段完全相同:第二十一、二十二、二十三、二十四关,以及第六十七、六十八、八十三、八十四关。阶段切换时,代码只做三件事:阶段号加一、三个计数清零、写一条成功提示。它没有复位态矢,没有清空门序列,也没有重置步数。
于是这八关的第二阶段可以这样通过:第一阶段达成后,态矢仍停在目标上,计数被清零;再按一次击发按钮,抽十发,判定函数重新计算保真度,仍然高于阈值,计数满足下限,第二阶段完成。整个第二阶段不需要任何新的门操作或滑杆移动。
第十七至二十关是真正的两阶段,因为它们的二阶目标与一阶不同:第十七关要从南极回到北极,第十八关要从正 x 转到负 x,第十九关要从负 x 回到北极,第二十关要从正 y 转到负 x。这四关的二阶是有内容的。
八个空转阶段的成因不难看出:目标函数只用 level.id 做分支,没有用 challengeStage 参与那八关的取值。写一阶与二阶目标时,作者给前四关写了三元表达式,后八关直接返回常量。这个不对称在代码里只有几行,在体验上却是”一半关卡有两步,一半关卡走个过场”。
八、画布上的四套常数
球面绘制只有九十三行,但它同时用了四套互不相同的几何常数。
第一套是轮廓。半径取画布短边的百分之三十六,在关卡视图里画布高三百四十点,因此半径约一百二十二点。
第二套是赤道环。它被画成一个椭圆,横向半轴等于半径,纵向半轴等于半径的零点三五倍。
第三套是态矢端点。端点的屏幕坐标由下式给出:
把赤道上的点 (cos t, sin t, 0) 代进去,端点轨迹是一个纵向半轴只有零点一四 R 的椭圆。也就是说,画出来的赤道环比态矢真正能走到的轨迹宽出约两倍半。极点方向倒是对的:z 的系数是一,态矢在南北极正好落在轮廓上。
第四套常数藏在坐标轴里。画布上那条虚线标着 x 轴,左端在球心下方零点一 R,右端在球心上方零点一 R。但把正 x 方向的态 (1, 0, 0) 代入上面的投影式,得到的纵坐标是球心下方零点一 R——正好与虚线右端相反。同一个方向,轴线画在一侧,态矢落在另一侧,落差合计零点二 R。
还有一个更细的地方:注释里写着”画 x 轴与 y 轴”,代码里只画了一条线。y 轴从来没有被绘制。
这些常数不会让判定出错,判定走的是角度而不是屏幕坐标。它们影响的是目视判断:把态矢拖到赤道环上时,学习者以为自己到了赤道,实际可能还差十几度;沿虚线找正 x 方向时,箭头会落在虚线的镜像位置。
九、拖拽是贴图旋转,不是相机绕球
球面外层的拖拽手势读取位移,把横向位移乘零点四写进偏航角,纵向位移乘负零点四写进俯仰角,松手后用弹簧动画归零。两个角度通过 rotation3DEffect 作用在整块画布上。
这意味着拖拽旋转的是一张已经拍平的图,而不是绕着球体移动相机。球面轮廓在旋转中会变成椭圆,赤道环、态矢、标签一起被整体倾斜,彼此之间的相对位置不变。视觉上它像在转一个球,几何上它是在转一张贴纸。对教学演示来说这不算错,但如果学习者试图通过拖拽判断”箭头在球的正面还是背面”,他会得到错误的线索,因为深度信息在投影那一步就已经丢失了。
松手回弹也是取舍:视角不能保留,每次拖拽都从零开始;画面总能回到标准视角,代价是没法固定一个便于观察的斜角。
十、能力边界与三条可落地的改动
先把边界写清楚。这十二个关卡是端侧教学仿真:没有噪声模型,没有退相干,没有读出误差,没有脉冲级控制,也没有与任何量子硬件的连接。保真度是纯态重叠,不是过程保真度,也不是含噪声设备的基准值。批次抽样是本机伪随机数,不是硬件熵源。把这里的”通过”理解为”学习者在理想化模型里把态调到了目标附近”,是准确的;把它理解为”验证了某个物理过程”,就不准确了。
在这个边界内,有三处改动成本不高、收益明确。
第一,让目标常量与文案同源。把 targetGoal 里的角度改成从常量渲染,或者在测试里断言两者一致,就能消掉第六节那四处错位。第二十二与第二十三关尤其值得先改,因为按文案操作的学习者会稳定地失败。
第二,给二阶目标与一阶相同的八个关卡加一条约束:要么在阶段切换时复位态矢,要么给二阶换一个不同的目标,要么把这两关明确标成一阶。现状是”两阶段”的名义下藏着一个只需再按一次按钮的空壳。
第三,把保真度读数接进界面。视图里有一个完整的反馈元组,包含当前保真度、目标、进度条数值与逐关提示文案,函数体写了六条针对具体关卡的引导语。但这个元组在整个文件里只出现一次——它的声明处。没有任何视图读取它。学习者因此看不到自己离目标有多远,只能靠目测箭头与金色光点的距离;而如第八节所示,目测所用的那套常数与判定所用的角度并不是同一套。
十一、结语
四个门按钮能做和不能做的事,其实在群论层面就写定了:它们生成二十四阶的八面体群,把一个顶点送到另外五个顶点,仅此而已。十二个关卡里有三个目标在这六个点之外,必须有连续通道托底;而连续通道一旦存在,门按钮就不再是唯一解。这不是实现失误,而是”用有限按钮教连续几何”这件事本身的结构性张力。
真正可以改进的是三处接缝:文案与常量之间的接缝、一阶与二阶之间的接缝、目视与判定之间的接缝。三处都不涉及物理模型,只涉及同一份事实被写在了几个地方。把这些接缝对齐,比给关卡再加十个门按钮更能让学习者看懂屏幕上那根箭头。
参考资料
- [1] Nielsen, M. A., & Chuang, I. L. Quantum Computation and Quantum Information. Cambridge University Press. https://doi.org/10.1017/CBO9780511976667
- [2] Apple. Canvas. SwiftUI documentation. https://developer.apple.com/documentation/swiftui/canvas
- [3] Apple. Slider. SwiftUI documentation. https://developer.apple.com/documentation/swiftui/slider
- [4] Apple. rotation3DEffect(angle:axis:anchor:). SwiftUI documentation. https://developer.apple.com/documentation/swiftui/view/rotation3deffect(_:axis:anchor:)
- [5] 北京量子信息科学研究院. 超导量子计算机测控链路系统 E 招标公告, 2026-10-22. https://www.yfbzb.com/inviteBid/detail/20261022_641048390.html