def test_lifted_gate_two_qubit(): test_unitary = lifted_gate(CNOT(0, 1), 4) true_unitary = lifted_gate_matrix(mat.CNOT, [0, 1], 4) assert np.allclose(test_unitary, true_unitary) test_unitary = lifted_gate(CNOT(1, 0), 4) true_unitary = lifted_gate_matrix(mat.CNOT, [1, 0], 4) assert np.allclose(test_unitary, true_unitary) test_unitary = lifted_gate(CNOT(1, 3), 4) true_unitary = lifted_gate_matrix(mat.CNOT, [1, 3], 4) assert np.allclose(test_unitary, true_unitary)
def test_lifted_gate_single_qubit(): test_unitary = lifted_gate(H(0), 1) true_unitary = mat.H assert np.allclose(test_unitary, true_unitary) test_unitary = lifted_gate(H(0), 5) true_unitary = np.kron(np.eye(2**4), mat.H) assert np.allclose(test_unitary, true_unitary) test_unitary = lifted_gate(RX(0.2, 3), 5) true_unitary = np.kron(np.eye(2**1), np.kron(mat.RX(0.2), np.eye(2**3))) assert np.allclose(test_unitary, true_unitary) test_unitary = lifted_gate(RX(0.5, 4), 5) true_unitary = np.kron(np.eye(2**0), np.kron(mat.RX(0.5), np.eye(2**4))) assert np.allclose(test_unitary, true_unitary)
def do_gate(self, gate: Gate) -> "ReferenceWavefunctionSimulator": """ Perform a gate. :return: ``self`` to support method chaining. """ unitary = lifted_gate(gate=gate, n_qubits=self.n_qubits) self.wf = unitary.dot(self.wf) return self
def do_gate(self, gate: Gate) -> "AbstractQuantumSimulator": """ Perform a gate. :return: ``self`` to support method chaining. """ unitary = lifted_gate(gate=gate, n_qubits=self.n_qubits) self.density = unitary.dot(self.density).dot(np.conj(unitary).T) return self
def test_lifted_gate_with_nonconstant_params(): gate = RX(Parameter("theta"), 0) with pytest.raises(TypeError): lifted_gate(gate, 1)
def test_lifted_gate_modified(): test_unitary = lifted_gate(RZ(np.pi / 4, 0).dagger(), 1) true_unitary = mat.RZ(-np.pi / 4) assert np.allclose(test_unitary, true_unitary) test_unitary = lifted_gate(X(0).dagger().controlled(1), 2) true_unitary = lifted_gate(CNOT(1, 0), 2) other_true = mat.CNOT assert np.allclose(test_unitary, true_unitary) assert np.allclose(other_true, true_unitary) test_unitary = lifted_gate( X(1).dagger().controlled(0).dagger().dagger(), 2) true_unitary = lifted_gate(CNOT(0, 1), 2) assert np.allclose(test_unitary, true_unitary) test_unitary = lifted_gate( X(0).dagger().controlled(1).dagger().dagger().controlled(2), 3) true_unitary = lifted_gate(CCNOT(1, 2, 0), 3) other_true = mat.CCNOT assert np.allclose(test_unitary, true_unitary) assert np.allclose(other_true, true_unitary) test_unitary = lifted_gate( RY(np.pi / 4, 0).dagger().controlled(2).dagger().dagger(), 3) ry_part = lifted_gate(RY(-np.pi / 4, 0), 1) zero = np.eye(2) zero[1, 1] = 0 one = np.eye(2) one[0, 0] = 0 true_unitary = np.kron(zero, np.eye(4)) + np.kron( one, np.kron(np.eye(2), ry_part)) assert np.allclose(test_unitary, true_unitary) test_unitary = lifted_gate(PHASE(0.0, 1).forked(0, [np.pi]), 2) true_unitary = lifted_gate(CZ(0, 1), 2) assert np.allclose(test_unitary, true_unitary) test_unitary = lifted_gate( PHASE(0.0, 2).forked(1, [0.0]).forked(0, [0.0, np.pi]), 3) true_unitary = lifted_gate(CZ(1, 2).controlled(0), 3) assert np.allclose(test_unitary, true_unitary)