def decompose_ua(phi, wires=None): r"""Implements the circuit decomposing the controlled application of the unitary :math:`U_A(\phi)` .. math:: U_A(\phi) = \left(\begin{array}{cc} 0 & e^{-i\phi} \\ e^{-i\phi} & 0 \\ \end{array}\right) in terms of the quantum operations supported by PennyLane. :math:`U_A(\phi)` is used in `arXiv:1805.04340 <https://arxiv.org/abs/1805.04340>`_, to define two-qubit exchange gates required to build particle-conserving VQE ansatze for quantum chemistry simulations. See :func:`~.ParticleConservingU1`. :math:`U_A(\phi)` is expressed in terms of ``PhaseShift``, ``Rot`` and ``PauliZ`` operations :math:`U_A(\phi) = R_\phi(-2\phi) R(-\phi, \pi, \phi) \sigma_z`. Args: phi (float): angle :math:`\phi` defining the unitary :math:`U_A(\phi)` wires (list[Wires]): the wires ``n`` and ``m`` the circuit acts on """ n, m = wires CZ(wires=wires) CRot(-phi, np.pi, phi, wires=wires) # decomposition of C-PhaseShift(2*phi) gate PhaseShift(-phi, wires=m) CNOT(wires=wires) PhaseShift(phi, wires=m) CNOT(wires=wires) PhaseShift(-phi, wires=n)
def entangler(par1, par2, wires): """Implements a two qubit unitary consisting of a controlled-Z entangler and Pauli-Y rotations. Args: par1 (float or qml.Variable): parameter of first Pauli-Y rotation par2 (float or qml.Variable): parameter of second Pauli-Y rotation wires (Wires): two wire indices that unitary acts on """ CZ(wires=wires) RY(par1, wires=wires[0]) RY(par2, wires=wires[1])
class TestKrausOps: """Unit tests for the method `_get_kraus_ops()`""" unitary_ops = [ (PauliX, np.array([[0, 1], [1, 0]])), (Hadamard, np.array([[INV_SQRT2, INV_SQRT2], [INV_SQRT2, -INV_SQRT2]])), (CNOT, np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])), ] @pytest.mark.parametrize("ops", unitary_ops) def test_unitary_kraus(self, ops, tol): """Tests that matrices of non-diagonal unitary operations are retrieved correctly""" dev = qml.device("default.mixed", wires=2) assert np.allclose(dev._get_kraus(ops[0]), [ops[1]], atol=tol, rtol=0) diagonal_ops = [ (PauliZ(wires=0), np.array([1, -1])), (CZ(wires=[0, 1]), np.array([1, 1, 1, -1])), ] @pytest.mark.parametrize("ops", diagonal_ops) def test_diagonal_kraus(self, ops, tol): """Tests that matrices of non-diagonal unitary operations are retrieved correctly""" dev = qml.device("default.mixed", wires=2) assert np.allclose(dev._get_kraus(ops[0]), ops[1], atol=tol, rtol=0) p = 0.5 K0 = np.sqrt(1 - p) * np.eye(2) K1 = np.sqrt(p / 3) * np.array([[0, 1], [1, 0]]) K2 = np.sqrt(p / 3) * np.array([[0, -1j], [1j, 0]]) K3 = np.sqrt(p / 3) * np.array([[1, 0], [0, -1]]) channel_ops = [ ( AmplitudeDamping(p, wires=0), [ np.diag([1, np.sqrt(1 - p)]), np.sqrt(p) * np.array([[0, 1], [0, 0]]) ], ), (DepolarizingChannel(p, wires=0), [K0, K1, K2, K3]), ] @pytest.mark.parametrize("ops", channel_ops) def test_channel_kraus(self, ops, tol): """Tests that kraus matrices of non-unitary channels are retrieved correctly""" dev = qml.device("default.mixed", wires=1) assert np.allclose(dev._get_kraus(ops[0]), ops[1], atol=tol, rtol=0)