事实证明以下工作,但门以违反直觉的方式应用。这可能是 Qiskit 中位排序的结果,这似乎导致了非常不标准的实现,所以要小心!具体来说,测试以下代码(您可以将量子位转换为|1>
使用注释掉的x()
门):
q = QuantumRegister(2, 'q')
c = ClassicalRegister(2, 'c')
U4x4 = np.array( [[0, 1, 0, 0], [1, 0, 0, 0],
[0, 0, 0, 1], [0, 0, 1, 0]] )
qc = QuantumCircuit(q,c)
qc.x(q[0])
#qc.x(q[1])
gate4x4 = UnitaryGate(U4x4)
qc.append(gate4x4, [q[0], q[1]] )
qc.measure(q[0],c[0])
qc.measure(q[1],c[1])
qc.draw()
只需查看矩阵,您就可以看到它应该具有以下输出:|00>
-> |01>
、|01>
-> |00>
、|10>
->|11>
和|11>
-> |10>
,其中第一位,即a
in|ab>
表示在 上测量的值q[0]
。换句话说,如果输入是q[0]=|1>
和q[1]=|0>
,人们会期望标准基础中的输入状态是(列向量)(0;0;1;0)
,所以输出是(0;0;0;1)
。但是通过在 Aer 上进行模拟来尝试一下,您会发现情况并非如此。如图所示,qc.x(q[0])
输出为(0;0;0;0)
。要获得预期的输出,您需要改为append
on [q[1], q[0]]
。虽然这绝对可以由知道的人处理,但我认为这完全令人困惑。
这是此门的受控版本。同样,请注意指令中所需的量子位的(非常不直观的)逆序append
,以便第一个量子位q[0]
充当控制。
q = QuantumRegister(3, 'q')
c = ClassicalRegister(3, 'c')
U4x4 = np.array( [[0, 1, 0, 0], [1, 0, 0, 0],
[0, 0, 0, 1], [0, 0, 1, 0]] )
k = 4
# This makes a controlled variant of the matrix
C_U = np.vstack([np.hstack([np.eye(k), np.zeros((k,k))]),
np.hstack([np.zeros((k,k)), U4x4])])
qc = QuantumCircuit(q,c)
#qc.x(q[0])
gate3Q = UnitaryGate(C_U)
qc.x(q[0])
qc.append(gate3Q, [q[2], q[1], q[0]] )
qc.measure(q[0],c[0])
qc.measure(q[1],c[1])
qc.measure(q[2],c[2])
qc.draw()
通过运行此代码(以及打开x(q[0])
和关闭等),您可以轻松地自己确认发生了什么
backend = BasicAer.get_backend('qasm_simulator')
shots = 2048
results = execute(qc, backend=backend, shots=shots).result()
answer = results.get_counts()
print(answer)
plot_histogram(answer)
通过查看 和 的定义,C_U
似乎append
第一个量子比特q[2]
应该是控制。但不,它是q[0]
。为了进一步参考,这是我正在运行的 Qiskit 版本:
{'qiskit-terra': '0.11.0',
'qiskit-aer': '0.3.4',
'qiskit-ignis': '0.2.0',
'qiskit-ibmq-provider': '0.4.4',
'qiskit-aqua': '0.6.1',
'qiskit': '0.14.0'}