4

大家好:Cirq 提供了一种从数组创建单一门的方法。我尝试在 Qiskit 中做同样的事情,但没能完全做到。这是一个示例代码,到目前为止我可以放在一起。另外,有没有办法用这个单一的从 q[0] 到 q[1] 应用受控操作?或者为此目的创建一个特定的标记门以在电路中使用?如果是这样,怎么做?非常感谢!

from qiskit.extensions import *
U2x2 = np.array([[0.998762, -0.049745], [-0.049745, -0.998762]])
# Still not sure how to use this, though it compiles
gate2x2 = UnitaryGate(U2x2)

# The best I could do so far was this:
# Create the quantum circuit
q = QuantumRegister(2)
c = ClassicalRegister(2)
qc = QuantumCircuit(q, c)

qc.unitary(U2x2, range(1))
qc.measure(q[0], c[0])
4

2 回答 2

3

I believe your implementation with qc.unitary(U2x2, range(1)) is correct if you just want a regular unitary gate from an array. Instantiating a UnitaryGate seems to be already done within the qc.unitary() call, so just calling qc.unitary() should be fine.

However, if you want a controlled version of this unitary gate, I found that instantiating the UnitaryGate manually and then adding a control to that gate works fine. Something similar to this should work:

from qiskit.circuit.add_control import add_control

gate2x2 = UnitaryGate(U2x2)
gate2x2_ctrl = add_control(gate2x2, 1)

qc.append(gate2x2_ctrl, [q[0], q[1]])

Here is the source code for add_control() as well in case you wanted more information.

于 2019-12-31T14:33:51.447 回答
1

事实证明以下工作,但门以违反直觉的方式应用。这可能是 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>,其中第一位,即ain|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)。要获得预期的输出,您需要改为appendon [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'}
于 2020-01-04T16:16:27.660 回答