事实证明,以下是可行的,但门的应用方式与直觉相反。这可能是 Qiskit 中位排序的结果,这似乎导致了非常不标准的实现,所以要小心!具体来说,测试以下代码(您可以使用注释掉的x() 门将量子位转换为|1>):
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>,其中第一位,即|ab> 中的a 表示在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)。要获得预期的输出,您需要在 [q[1], q[0]] 上使用 append。虽然这肯定可以由知道的人处理,但我认为这完全令人困惑。
这是此门的受控版本。同样,请注意 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'}