简介:这是《量子计算和量子信息》(尼尔森与丘原著)经典教材的配套课后答案,由量子信息爱好者goropikari整理的英文非官方解题手册,面向正在研读本书的本科生、研究生及自学者,旨在帮助读者独立完成习题并验证对量子比特、量子门、量子噪声、距离度量、冯诺依曼熵等核心概念的理解。整个资源打包为一个PDF文档,体积仅466KB,轻量便携,便于随时查阅。当前已有1359人学习使用。解答覆盖第二章量子力学基础、第八章量子噪声与量子操作、第九章距离度量与保真度、第十一章熵与信息论等关键章节,每章均给出逐步推导;还专门列出勘误表,指出原书第101页式(2.150)的ρ应为ρ′、第408页式(9.49)系数计算有误等细节,并附反例说明。读者可借助它比对解题思路、自查逻辑漏洞,同时培养不盲目轻信、主动验证的独立思考能力,尤其适合配合Nielsen和Chuang的10周年纪念版教材使用。
1. 量子计算课后答案:习题不是作业,是量子态演算的体检单
量子计算学习者拿到尼尔森、赵千川版教材的课后答案,最常见的状态是:对完答案,合上书,感觉自己懂了。等到下一次遇到密度算符的迹运算,又卡在原地。这本教材的习题不是算术题,每一道都在检查你的某个具体理解环节——基变换、测量坍缩、算符作用次序,或者量子误差纠正里的逻辑比特和物理比特的区别。课后答案如果只用来对结果,等于把整套推导里最有价值的部分扔掉了:答案能暴露你推理链断点的位置。这篇笔记只做一件事:把课后答案用成一套诊断工具,做对理解比做对题目重要。适合正在啃这本教材、卡在某个推导环节、需要验证思路的量子计算学习者。
2. 拆书先于拆题:尼尔森教材的习题路线图
2.1 从线性代数到量子态演算:习题主线里的三个递进层次
这本教材的习题有一条清晰的递进主线,我习惯把它拆成三个层次。第一层是线性代数操作,集中在教材前半部分的基础章节:矩阵乘法、内积、特征值分解、张量积、以及狄拉克记号下的各类运算。这一层的习题并不深,但它们是后续所有推导的底座。你不妨把这一层的每道题看成一次手算仿真,要求你先把量子态写成向量、把量子门写成矩阵,然后老老实实做乘法。很多人跳过这一层直接看算法章节,到后面遇到张量积维度对不上、内积符号写反的时候,再回头补基础,代价是双倍的。
第二层是量子电路的理解,从单量子比特门拓展到多比特门。CNOT、Hadamard、相位门、Swap门,以及电路图的书写规范和两种比特顺序约定。这一层的习题检验你是否真正理解可逆计算的概念——量子门的逆就是它的共轭转置,以及为何测量会破坏叠加态。答案对照的重点不在最终数值,而在中间电路结构。我见过不少人在这一层把答案当成了终点:算出的最终态矢量和答案对上了,就不再管了。实际上,如果不会画电路图,或者画不出与答案等价的另一个电路结构,说明这个知识点还没焊牢。
第三层是算法与信息论:Shor算法、Grover算法、量子傅里叶变换、复杂度分析、保真度、熵、量子信道和量子误差纠正。这一层的习题特点是推导链路长、近似条件多、边界情况隐蔽。答案往往不是几行数值,而是一整页推导。面对这一层的习题,我的建议是一次只做一道,做完后立刻逆推复盘,不要连续刷题,否则很容易出现“答案看得懂,下次题换个说法就不会”的空心状态。没有捷径,也没有框架能帮你跳过推导训练。
具体到习题类型上,第一层次的题目关键词是“计算”和“验证”:验证某个算符是否厄米、计算两个量子比特的张量积、把Ket写成列向量再转成矩阵。第二层次的关键词是“电路”和“等价”:画出某个门的电路实现、证明两个电路等价、推导交换门后的相位变化。第三层次的关键词是“设计”和“分析”:设计一个满足特定条件的电路、分析算法在噪声环境下的保真度衰减。拿到一本习题册,先按关键词把题目归类,比按章节顺序刷题更接近教材作者的出题思路。
为什么要按三个层次来对待课后答案?因为不同层次的习题,答案对你的价值完全不同。第一层的答案基本是数值结果和少量推导,直接对照即可;第二层的答案往往给出量子电路图和中间步骤,对照答案的价值在卡住的那一刻,看看你卡在哪个门之后;第三层的答案接近一篇小型论文推导,需要你花时间自己推一遍再对答案。如果一个初学者拿着第三层答案从头抄到尾,抄完等于什么都没学到,因为算法推导里的每一步都需要前面两个层次的基础。先分层,再决定怎么用答案,这是整本教材习题策略的起点。
2.2 计算类与信息论类习题:两种验算节奏
教材后半部分开始区分计算类习题和信息论类习题,对应量子计算与量子信息两条主线。计算类习题的重点是某个量子门矩阵的正确表示、某个算法的量子电路输出、某个特定量子态的演化结果。这类题目的答案大概率是确定性的,你可以拿矩阵乘法或几行代码来验算,对就是对,错就是错。信息论类习题的重点则完全不同:信道保真度的计算、噪声模型下的态演化、熵的单调性证明、可容错性和距离的权衡。这类题目推导多于数值,答案往往不是一个数字,而是一个不等式或者一个推论的完整证明。
两类习题的验算节奏差别很大。计算类习题适合“先自己算完再对答案”,信息论类习题适合“只看答案每行开头,然后自己续写推导”。我在这上面有过翻车经历:当时急着刷完噪声信道那一章的习题,每道题都直接对着答案抄,抄到需要证明保真度单调性的题目时直接卡壳。后来换了一种做法——只看答案每行的开头提示,遮住后续内容,手动补完推导,效果反而好了很多。这不是玄学,而是因为信息论类习题的推导逻辑线比计算量更关键,对答案的姿势必须反过来。
我的经验法则是,题目问“计算”“给出”“求”,大概率是计算类;问“证明”“说明”“讨论”,大概率是信息论类。混合类题目通常先问“给出电路”再问“分析保真度”,这时候就分两段处理:电路部分先行计算,推导部分再走逆推。还有一个小细节,信息论类习题的答案里会出现大量约等和不等式放缩,不要试图把每一步都变成完全相等,那既不是答案的本意,也容易把自己绕进去。
| 习题类型 | 典型特征 | 验算节奏 | 答案对照方式 |
|---|---|---|---|
| 计算类 | 有明确的矩阵或数值结果 | 先算完再对 | 直接逐行对照 |
| 信息论类 | 涉及不等式、熵、信道 | 边推边看提示 | 只看首行提示,补完再比 |
| 混合类 | 先设计电路再分析保真度 | 分两段处理 | 电路部分直接对,分析部分逆推 |
我在实际使用中还会做一道工序:把教材的习题按这个表格打上标签,贴在每章标题的空白处。这样到复习阶段,可以快速筛选哪些题当时卡着做出来的,哪些题一次通过。前者是重点复习对象,后者可以放一放。
还有一个容易忽略的点:这本教材的习题顺序和正文内容并不是严格同步的,有些章节末尾的习题会用到后面章节的记号。第一次做的时候不需要死磕,标注一下,等学到那个记号再回来做。这是我个人比较受益的习惯:按自己的进度给答案排个序,往往比按教材顺序硬啃效率更高。
3. 把答案用成工具:验算、对照、逆推的三层用法
3.1 第一层用法:矩阵验算与归一化检查
这是最基础也是最容易忽略的检查。量子计算习题里,凡是涉及量子态演算的答案,第一步检查的就是归一化条件。如果一道题的答案是某个态矢量,那这个矢量的模长平方必须等于1。如果答案是某个密度算符,那它的迹必须是1。用Python的numpy来验算,代码量极短,但它能第一时间过滤掉很多似是而非的结果。
import numpy as np # 示例:某习题答案给出的量子态矢量 psi = np.array([1/np.sqrt(2), 1/np.sqrt(2)]) norm_squared = np.sum(np.abs(psi)**2) print(f"态矢量模长平方: {norm_squared:.6f}") # 示例:某习题答案给出的密度算符 rho = np.array([[0.5, 0.2], [0.2, 0.5]]) trace = np.trace(rho) print(f"密度算符的迹: {trace:.6f}")逻辑说明:对一个纯态矢量,模长平方等于1;对一个混合态密度算符,迹等于1。这两行代码无论答案是否复杂都适用。如果你验算的习题答案是一个经过好几轮演化的态矢量,建议在每一步演算之后再做一次同样的检查,这样能第一时间定位到底哪一步出错。参数说明只有一个,就是数组的dtype。建议初始化时显式指定dtype=complex,因为量子力学里的负数相位很常见,用实数类型会让后续共轭转置操作丢失相位信息。
你可能觉得归一化检查太基础,不值得当成正式步骤。实际上它是一条诊断链的起点。量子计算的推导错因分布很不均匀,大部分错误发生在中间步骤,而非最终结果。归一化检查不需要你知道标准答案,只需要你知道物理规律,这是一种完全独立于教材答案的验证手段。我在快速推导时尤其依赖它,因为它能在我对答案之前就先发现明显的问题。
如果你的习题答案涉及多比特系统,把归一化检查套在一个循环里,逐一打印每个态的模长。你会很快发现,有些态矢量分量对不上答案,但模长依然是1。这时候不要怀疑归一化,而是去检查基的顺序约定。这属于维度和基向量排序问题,和归一化是两码事。先把两者分开,排查效率会高很多。
3.2 第二层用法:逆推对照法
逆推对照是我最常用的答案学习方法。具体操作分三步。
第一步,看答案的最终结果,在草稿纸的右上角写下来。第二步,看答案的第一步推导,然后挡住剩下的部分,自己往下推。第三步,推不动了,再往下看一行答案,继续推。整个过程里,答案的每一行都是一次提示,而不是一次复制。
你可能会问,这和写完再对答案,或者直接抄答案后复读一遍有什么区别?区别在于逆推的时候,大脑处于生成状态,你会不断建立下一步的候选集合,然后和答案比对,这种比对本身就是在校准你的思维模式。尤其是量子电路习题,从某一节电路图开始,答案给出的中间态已经是逐行演算的,如果你完全从零推导卡在某个门作用之后的相位变换上,这一行答案就是在告诉你,你对这个门的理解出现了偏差。
逆推时,根据卡壳程度可以选三种模式。轻度卡壳,只看下一行答案的等号右边,补齐左边;中度卡壳,允许自己看两步提示,但必须口头复述这两步之间的逻辑;重度卡壳,干脆把整题答案抄一遍,但在每行旁边批注“这一步用到什么性质”。三种模式难度递减,但无论哪种,都比从头抄一遍管用。
我一般会在逆推结束时做一次纸上总结:用三句话写出这道题考察的知识点、我做错的地方、下回怎么避免。这个习惯来自我读这本教材时踩过的坑——当时连续三章只看答案不逆推,到量子误差纠正那一章直接崩了,回头补了整整两周的基础。后悔药是有的,逆推就是后悔药。
逆推对照法要注意一个边界:不要逆推到“中间步骤全对但结果还是错”的情况。这时候多半是最后一步的化简出了问题,比如归一化常数漏掉了系数,或者某一步把矩阵的转置和共轭换混了。遇到这种情况,先不急着从头再来,对比答案的最终形式和你算的最终形式,找到差异项,再反向定位到中间步骤。这个反向定位的过程,本身就是一种高质量的习题训练。
3.3 第三层用法:用数值仿真复现推导
对计算类习题,用数值仿真复现推导是最稳的验证方式。常见做法是用Python的numpy和量子计算框架比如cirq或qiskit跑一遍量子电路,再与手算结果对比。如果只是验证这本教材的习题,numpy就够用了,不需要引入重量级的框架;当你需要验证更复杂的多比特电路或者噪声信道时,再考虑上cirq或qiskit。
import numpy as np # 单比特Hadamard门后接CNOT,制备Bell态 H = np.array([[1, 1], [1, -1]]) / np.sqrt(2) CNOT = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]) # 初始态 |00> = [1, 0, 0, 0] psi0 = np.array([1, 0, 0, 0], dtype=complex) # H作用在第一个比特上: H ⊗ I I_2 = np.eye(2) H_on_first = np.kron(H, I_2) psi1 = H_on_first @ psi0 psi2 = CNOT @ psi1 print("Bell态系数:", psi2)逻辑说明:这里的电路对应的是先对第一个量子比特作用Hadamard门,然后以它为控制比特执行CNOT。numpy的kron函数就是张量积,这一步是量子计算习题计算里最容易出错的地方——两个量子比特的状态空间维度是4,不是2,单比特门作用到第一个比特上时,必须和单位门做张量积才能得到4x4矩阵。参数说明:CNOT门的矩阵表示有几种不同的排序约定,如果你发现自己算出来的结果和答案差一个符号或者行序不对,先检查你的基本比特顺序约定,这是量子计算习题对照答案时最常见的隐性坑。
提示:如果你用手算和框架对照时发现结果不一致,先查比特顺序约定,而不是怀疑框架。
如果你用cirq这类框架,它的声明式接口能帮你少写很多底层矩阵。但我建议至少在前期习题里保留numpy的验算路径,因为教材里的习题设计意图是训练手算能力,直接上框架等于跳过了这个训练。框架是验证工具,不是学习工具,这个界限要分清楚。
当你需要验证更复杂的多比特电路时,再上cirq或qiskit。以cirq为例,同样的Bell态可以这样写:
import cirq q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit( cirq.H(q0), cirq.CNOT(q0, q1) ) simulator = cirq.Simulator() result = simulator.simulate(circuit) print(result.final_state_vector)逻辑说明:cirq里LineQubit.range(2)声明两个量子比特,H和CNOT直接用声明式写法,simulator.simulate返回最终态矢量。这里不需要自己处理张量积和比特顺序,框架默认采用little-endian顺序,打印final_state_vector时,会看到和numpy代码里相同的系数顺序。参数说明:LineQubit.range(2)的两个比特顺序,cirq默认第一个比特是最高位,如果你的手算约定是big-endian,打印结果需要反序才能对应上。这是框架与手算对照时最常见的差异来源。
| 场景 | 推荐工具 | 原因 |
|---|---|---|
| 验证单比特门 / 双比特门的算子 | numpy | 直接、快、无依赖 |
| 验证完整量子电路输出 | cirq / qiskit | 电路声明更清晰,自动处理维度 |
| 验证噪声信道和保真度 | qiskit | 自带噪声模型和采样器 |
4. 习题答案排查:量子推导里的五个常见翻车点
4.1 现象一:算符次序颠倒导致的相位错乱
现象:自己算出的答案和标准答案只在相位上差了一个负号,其他部分完全一致。原因:量子电路中的门作用次序是从左到右施加到态矢量上的,但在矩阵乘法里,最先作用的门反而写在最右边。如果颠倒顺序,矩阵乘法不满足交换律,结果必然不同。
解决:养成一个习惯——先把电路图画出来,标注每一层门,然后用从右到左的矩阵乘法规则重写一遍表达式。代码里也一样,如果你用numpy实现电路,注意施加顺序。
# 正确:先施加 U1,再施加 U2 psi_final = U2 @ U1 @ psi_initial # 错误:顺手写成 U1 @ U2 @ psi_initial这段代码里的@符号表示矩阵乘法,U2 @ U1 @ psi_initial的顺序必须和电路图从左到右的顺序对应,这是唯一的要点。这条看起来简单,但它能解释量子习题里至少三分之一莫名其妙的相位差异。凡是答案差负号,第一先检查算符顺序,第二再检查共轭转置,两个方向排查完,大部分问题都能落地。
4.2 现象二:测量坍缩后忘了更新密度算符
现象:密度算符的演化算到测量之后,结果和答案对不上,迹不再是1,甚至出现了负特征值。原因:混合态进行投影测量后,密度算符需要按照投影算符和概率重新归一化。很多人把测量当成了酉演化,但测量不是可逆的,这是量子力学里最常见的误解。
解决:先算测量概率,再算测量后的态。
# 投影算符 P,当前密度算符 rho p = np.real(np.trace(P @ rho)) # 测量概率 rho_post = P @ rho @ P / p # 归一化后的测量态逻辑说明:p 必须取实部,因为numpy的trace在复数域上会返回带极小的虚部的复数,直接拿它做分母会污染后面的计算。rho_post 的物理含义是测量后的密度算符,它必须再次满足 trace(rho_post) = 1,可以用这一步做自检。我做习题时吃过这个亏,后来养成了一个条件反射:看到“测量”两个字,立刻检查自己有没有除以概率。这个条件反射在噪声信道和量子误差纠正章节尤其管用。
4.3 现象三:张量积维度对不上
现象:算到一半矩阵维度突然对不上,比如2x2的矩阵和4x4的矩阵相乘。原因:把单比特门直接当成作用于整个多比特系统的门,忽略了需要先做张量积扩展维度。这是量子计算习题里最普遍的翻车点,几乎每个人都踩过。
解决:任何单比特门作用到多比特系统上,先做张量积扩展维度。
# 2比特系统,单比特H门作用到第0个比特 H_on_q0 = np.kron(H, np.eye(2)) # 错误:直接把 2x2 的 H 当成 4x4 的矩阵参与运算用Python做验算时,建议封装一个统一的函数来扩展维度,避免每次手写kron导致顺序混乱。维度检查的代码很简单:print(U_full.shape),看一眼形状就能定位问题。养成这个动作习惯后,张量积维度错误出现的频率会直线下降。
4.4 现象四:投影算符像个小黑匣子,遗漏共轭转置
现象:投影算符写成ket bra的某个部分,计算时忘记了共轭转置,导致结果偏离。原因:投影算符 P = |psi><psi|,写错矩阵元素的位置,或者漏掉了<psi|的共轭操作,这在复数域上会引入相位误差。尤其当psi的分量是复数时,ket和bra不是简单的转置关系,而是共轭转置关系。
解决:所有投影算符都用共轭转置构造。
# 正确:复数态矢的投影算符 P = np.outer(psi.conj(), psi) # 错误:P = np.outer(psi, psi),当 psi 为复数时,P 不是 Hermitian逻辑说明:np.outer(psi.conj(), psi) 构造的是 |psi><psi|,np.outer(psi, psi) 构造的是 |psi><psi*|,只有当psi全是实数时两者才等价。量子计算习题里复数态是常态,所以这个检查点一定要养成固定的写法。参数说明是conj()和转置的顺序,先共轭再外积,顺序反了同样会出错,最好在注释里写清楚构造的是哪个方向。
4.5 现象五:误差纠正码把逻辑比特和物理比特混为一谈
现象:量子误差纠正的习题完全没有思路,或者算出来的纠错码和答案对不上。原因:量子误差纠正里,很多题要求你在物理比特层面做测量,然后推导逻辑比特的状态。如果直接把物理比特上的测量结果当作逻辑比特的状态,就会丢掉纠错码的冗余信息。逻辑比特和物理比特之间的译码映射,才是这一类习题真正的考点。
解决:先画出量子电路图,把物理比特、辅助比特、逻辑比特分别标记出来,再逐层推导。我的经验是,把“逻辑比特状态与物理比特状态的映射表”写在草稿纸上,再开始计算。这个表一旦写对,后续推导就顺了。这类题目的答案往往很长,不要指望一步到位,耐心地按电路分层推进。分层推导的每一层都做一次归一化检查,能在早期抓住大多数错误。
5. 把习题答案用活:从一题一解到一套验算习惯
我处理这本教材习题时,最后养成了一套固定验算习惯。你可以在自己的笔记里建一个模板,每次做完题顺序执行:所有态矢量先验归一化,模长平方约等于1;密度算符先验迹等于1;多比特系统先验维度,2比特是4维,3比特是8维;测量之后检查是否做了投影和除以概率;逆推时至少推两行再对答案。
def quick_check(state): """统一验算:维度 + 归一化/迹""" state = np.asarray(state, dtype=complex) print("维度:", state.shape) if state.ndim == 1: print("归一化:", np.sum(np.abs(state)**2)) elif state.ndim == 2: print("迹:", np.trace(state))逻辑说明:quick_check接收一个态矢量或密度算符,np.asarray确保输入类型规范,dtype=complex避免相位信息丢失。state.ndim判断输入是向量还是矩阵,一维向量打印归一化模长平方,二维矩阵打印迹。这两个数值就是量子习题验算中最核心的两个不变量。
这个模板简单到不好意思说出口,但它救过我两次。一次是Grover算法习题里,我把迭代算符的相位写反了,当时靠逆推卡在答案第三行才发现问题。另一次是密度算符演化题,忘记除以测量概率,幸好固定检查轨迹时发现迹不等于1,顺着这个线索查到了测量步骤。
我还会给每个习题做一个三行答案卡片:考察的知识点、我犯错的位置、下次要留意的提示词。这个卡片比任何漂亮的笔记都有用。量子计算的推导链很长,真正能让你下次不踩同一个坑的,不是大段重抄,而是那一行提示词。合上书后,你能回忆起来的,往往不是答案本身,而是卡片上那行提醒自己的话。从一道习题到一套验算习惯,中间隔着的是反复做同一道错题的次数。希望我的这套习惯也能帮到你。
本文还有配套的精品资源,点击获取