3. Qiskit中的经典寄存器与量子寄存器

在Qiskit中构建量子电路时,最先接触的两个基础构件就是量子寄存器(QuantumRegister)和经典寄存器(ClassicalRegister)。它们不是可有可无的装饰,而是电路数据结构的骨架:量子寄存器承载量子比特,经典寄存器承载测量结果。理解它们的创建方式、命名规则、大小含义以及在电路中的角色,是后续编写测量、条件控制乃至动态电路的前提。

一、两个寄存器分别“装”什么

量子寄存器是量子比特的容器。一个QuantumRegister(3, 'q')表示一个名为q、包含3个量子比特的寄存器,其内部比特可分别通过q[0]、q[1]、q[2]访问。经典寄存器则是经典比特的容器,ClassicalRegister(3, 'c')表示名为c、包含3个经典比特的寄存器,用于存放测量后坍缩得到的0/1结果。二者在电路中的角色分工明确:量子寄存器是“被操作的对象”,经典寄存器是“被写入的结果区”。

需要强调的是,经典寄存器并不参与量子门运算。对c施加X门是没有意义的;它只在measure、reset的经典条件、if_test条件分支等场景中被读写。把这一点记牢,可以避免很多“为什么门作用在经典比特上报错”的困惑。

二、创建、命名与大小

两个类的构造签名高度对称:QuantumRegister(size, name)与ClassicalRegister(size, name)。其中size是正整数,表示寄存器内比特数量;name是可选字符串,省略时Qiskit会自动生成q、c等默认名。命名看似小事,实则是多寄存器电路可读性的关键。当电路里同时存在数据寄存器data、辅助寄存器anc、测量结果寄存器meas时,清晰的命名能让measure(data[0], meas[0])这样的语句自解释。

命名有两条实用规则。第一,同一电路内寄存器名应唯一,否则在按名称索引或可视化时容易混淆。第二,名称尽量使用有语义的短标识,避免空格和特殊字符,便于在QuantumCircuit的字符串表示和图形输出中稳定显示。大小方面,寄存器大小在创建时确定,之后不能直接“扩容”;若需要更多比特,应创建新寄存器并重建电路,或从一开始就按最大需求规划。

from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit

q = QuantumRegister(2, 'q')      # 2个量子比特,名为 q
c = ClassicalRegister(2, 'c')    # 2个经典比特,名为 c
qc = QuantumCircuit(q, c)        # 将两个寄存器绑定到电路

qc.h(q[0])
qc.cx(q[0], q[1])
qc.measure(q, c)                 # 整体测量:q[i] -> c[i]

上面这段代码展示了最典型的绑定方式:先创建寄存器,再把它们作为参数传给QuantumCircuit。此时电路的量子比特数等于q的大小,经典比特数等于c的大小。也可以只传量子寄存器、稍后再add_register添加经典寄存器,但在需要测量的场景中,提前规划好两者更清晰。

三、寄存器在电路中的角色与索引关系

寄存器绑定到电路后,电路会维护“寄存器—比特”的映射。量子比特在电路中的全局索引按寄存器添加顺序排列:先加入的寄存器占据低位索引。例如先加q(2位)再加anc(1位),则q[0]、q[1]对应全局0、1,anc[0]对应全局2。经典比特同理。这个顺序直接影响measure的配对和后续结果字符串的位序,是读结果时最容易出错的地方。

测量时,qc.measure(q, c)要求两个寄存器大小一致,并按位置一一配对:q[0]→c[0]、q[1]→c[1]。若大小不一致会报错,此时应改为逐位测量qc.measure(q[0], c[0]),或使用切片qc.measure(q[0:2], c[0:2])。这种“按位置配对”的语义,正是经典寄存器在电路中最核心的角色:它把量子测量结果落到确定的经典位上,供后续读取和条件判断使用。

寄存器绑定与测量配对关系 QuantumRegister(2, 'q') q[0] q[1] 承载量子比特,接受量子门操作 ClassicalRegister(2, 'c') c[0] c[1] 存放测量结果,供读取与条件判断 measure 按位置配对 QuantumCircuit(q, c) 量子比特数 = q.size,经典比特数 = c.size 全局索引按寄存器添加顺序排列:先加入的寄存器占据低位索引,测量结果位序随之确定

四、多寄存器场景下的规划建议

当电路包含多个量子寄存器时,常见做法是把功能相关的比特归入同一寄存器。例如一个3比特的GHZ态制备电路,可以把三个数据比特放进data寄存器,把用于纠错或条件判断的辅助比特放进anc寄存器。这样在写qc.cx(data[0], anc[0])时,读者一眼就能看出跨寄存器的操作意图。经典寄存器也可以按用途拆分:meas_data存放数据比特测量结果,meas_syndrome存放校验结果,便于后续分别读取和处理。

一个容易忽略的细节是:QuantumCircuit允许在创建后通过add_register追加寄存器,但追加会改变全局索引布局。如果电路中已经存在按位置配对的测量或条件判断,追加寄存器可能打乱原有映射。因此更稳妥的做法是在建电路之初就把所有需要的寄存器规划好,一次性传入构造函数。

命名建议:量子寄存器用q、data、anc,经典寄存器用c、meas、syndrome。名称短、语义明确、全电路唯一,能显著降低多寄存器电路的阅读成本。

五、从寄存器到结果读取

寄存器的大小和配对关系最终会体现在结果字符串上。以2比特电路为例,若q[0]→c[0]、q[1]→c[1],则测量结果键'01'表示c[1]=0、c[0]=1,即字符串最右位对应最低位经典比特。这个位序约定与全局索引一致,是解读counts和后续条件控制的基础。若把寄存器顺序或配对关系弄反,读出的结果就会整体错位。

总结来说,QuantumRegister与ClassicalRegister的创建只需一行代码,但它们决定了电路的比特容量、索引布局、测量配对和结果位序。命名让电路可读,大小让资源可控,绑定顺序让映射确定,而“按位置配对”的测量语义则把量子世界的结果稳定地落到经典位上。把这四件事在动手写第一行门操作之前想清楚,后面的测量与条件控制就会顺畅得多。