Пример #1
0
class TestOperations:
    """Tests for the operations"""
    @pytest.mark.parametrize(
        "op",
        [
            (qml.Hadamard(wires=0)),
            (qml.PauliX(wires=0)),
            (qml.PauliY(wires=0)),
            (qml.PauliZ(wires=0)),
            (qml.S(wires=0)),
            (qml.T(wires=0)),
            (qml.SX(wires=0)),
            (qml.RX(0.3, wires=0)),
            (qml.RY(0.3, wires=0)),
            (qml.RZ(0.3, wires=0)),
            (qml.PhaseShift(0.3, wires=0)),
            (qml.Rot(0.3, 0.4, 0.5, wires=0)),
        ],
    )
    def test_single_qubit_rot_angles(self, op):
        """Tests that the Rot gates yielded by single_qubit_rot_angles
        are equivalent to the true operations up to a global phase."""
        angles = op.single_qubit_rot_angles()
        obtained_mat = qml.Rot(*angles, wires=0).matrix

        # Check whether the two matrices are each others conjugate transposes
        mat_product = qml.math.dot(op.matrix, qml.math.conj(obtained_mat.T))
        mat_product /= mat_product[0, 0]

        assert qml.math.allclose(mat_product, I)
 def qfunc():
     qml.PauliX(wires=2)
     qml.CNOT(wires=[0, 2])
     qml.RX(0.2, wires=2)
     qml.Toffoli(wires=[0, 1, 2])
     qml.SX(wires=1)
     qml.PauliX(wires=1)
     qml.CRX(0.1, wires=[0, 1])
Пример #3
0
 def qfunc():
     qml.RZ(0.3, wires=0)
     qml.Hadamard(wires=0)
     qml.Rot(0.1, 0.2, 0.3, wires=0)
     qml.RX(0.1, wires=0)
     qml.SX(wires=0)
     qml.T(wires=0)
     qml.PauliX(wires=0)
Пример #4
0
 def qfunc():
     qml.RZ(0.3, wires="a")
     qml.RY(0.5, wires="a")
     qml.Rot(0.1, 0.2, 0.3, wires="b")
     qml.RX(0.1, wires="a")
     qml.CNOT(wires=["b", "a"])
     qml.SX(wires="b")
     qml.S(wires="b")
     qml.PhaseShift(0.3, wires="b")
Пример #5
0
def op(op_name):
    ops_list = {
        "RX": qml.RX(0.123, wires=0),
        "RY": qml.RY(1.434, wires=0),
        "RZ": qml.RZ(2.774, wires=0),
        "S": qml.S(wires=0),
        "SX": qml.SX(wires=0),
        "T": qml.T(wires=0),
        "CNOT": qml.CNOT(wires=[0, 1]),
        "CZ": qml.CZ(wires=[0, 1]),
        "CY": qml.CY(wires=[0, 1]),
        "SWAP": qml.SWAP(wires=[0, 1]),
        "ISWAP": qml.ISWAP(wires=[0, 1]),
        "SISWAP": qml.SISWAP(wires=[0, 1]),
        "SQISW": qml.SQISW(wires=[0, 1]),
        "CSWAP": qml.CSWAP(wires=[0, 1, 2]),
        "PauliRot": qml.PauliRot(0.123, "Y", wires=0),
        "IsingXX": qml.IsingXX(0.123, wires=[0, 1]),
        "IsingXY": qml.IsingXY(0.123, wires=[0, 1]),
        "IsingYY": qml.IsingYY(0.123, wires=[0, 1]),
        "IsingZZ": qml.IsingZZ(0.123, wires=[0, 1]),
        "Identity": qml.Identity(wires=0),
        "Rot": qml.Rot(0.123, 0.456, 0.789, wires=0),
        "Toffoli": qml.Toffoli(wires=[0, 1, 2]),
        "PhaseShift": qml.PhaseShift(2.133, wires=0),
        "ControlledPhaseShift": qml.ControlledPhaseShift(1.777, wires=[0, 2]),
        "CPhase": qml.CPhase(1.777, wires=[0, 2]),
        "MultiRZ": qml.MultiRZ(0.112, wires=[1, 2, 3]),
        "CRX": qml.CRX(0.836, wires=[2, 3]),
        "CRY": qml.CRY(0.721, wires=[2, 3]),
        "CRZ": qml.CRZ(0.554, wires=[2, 3]),
        "Hadamard": qml.Hadamard(wires=0),
        "PauliX": qml.PauliX(wires=0),
        "PauliY": qml.PauliY(wires=0),
        "PauliZ": qml.PauliZ(wires=0),
        "CRot": qml.CRot(0.123, 0.456, 0.789, wires=[0, 1]),
        "DiagonalQubitUnitary": qml.DiagonalQubitUnitary(np.array([1.0, 1.0j]), wires=1),
        "ControlledQubitUnitary": qml.ControlledQubitUnitary(
            np.eye(2) * 1j, wires=[0], control_wires=[2]
        ),
        "MultiControlledX": qml.MultiControlledX(wires=(0, 1, 2), control_values="01"),
        "SingleExcitation": qml.SingleExcitation(0.123, wires=[0, 3]),
        "SingleExcitationPlus": qml.SingleExcitationPlus(0.123, wires=[0, 3]),
        "SingleExcitationMinus": qml.SingleExcitationMinus(0.123, wires=[0, 3]),
        "DoubleExcitation": qml.DoubleExcitation(0.123, wires=[0, 1, 2, 3]),
        "DoubleExcitationPlus": qml.DoubleExcitationPlus(0.123, wires=[0, 1, 2, 3]),
        "DoubleExcitationMinus": qml.DoubleExcitationMinus(0.123, wires=[0, 1, 2, 3]),
        "QFT": qml.QFT(wires=0),
        "QubitSum": qml.QubitSum(wires=[0, 1, 2]),
        "QubitCarry": qml.QubitCarry(wires=[0, 1, 2, 3]),
        "QubitUnitary": qml.QubitUnitary(np.eye(2) * 1j, wires=0),
    }
    return ops_list.get(op_name)
Пример #6
0
    def test_sx_decomposition(self, tol):
        """Tests that the decomposition of the SX gate is correct"""
        op = qml.SX(wires=0)
        res = op.decomposition(0)

        assert len(res) == 4

        assert all([res[i].wires == Wires([0]) for i in range(4)])

        assert res[0].name == "RZ"
        assert res[1].name == "RY"
        assert res[2].name == "RZ"
        assert res[3].name == "PhaseShift"

        assert res[0].data[0] == np.pi / 2
        assert res[1].data[0] == np.pi / 2
        assert res[2].data[0] == -np.pi
        assert res[3].data[0] == np.pi / 2

        decomposed_matrix = np.linalg.multi_dot([i.matrix for i in reversed(res)])
        assert np.allclose(decomposed_matrix, op.matrix, atol=tol, rtol=0)
Пример #7
0
    "PauliY": qml.PauliY(wires=[0]),
    "PauliZ": qml.PauliZ(wires=[0]),
    "PhaseShift": qml.PhaseShift(0, wires=[0]),
    "ControlledPhaseShift": qml.ControlledPhaseShift(0, wires=[0, 1]),
    "QubitStateVector": qml.QubitStateVector(np.array([1.0, 0.0]), wires=[0]),
    "QubitUnitary": qml.QubitUnitary(np.eye(2), wires=[0]),
    "ControlledQubitUnitary": qml.ControlledQubitUnitary(np.eye(2), control_wires=[1], wires=[0]),
    "MultiControlledX": qml.MultiControlledX(control_wires=[1, 2], wires=[0]),
    "RX": qml.RX(0, wires=[0]),
    "RY": qml.RY(0, wires=[0]),
    "RZ": qml.RZ(0, wires=[0]),
    "Rot": qml.Rot(0, 0, 0, wires=[0]),
    "S": qml.S(wires=[0]),
    "SWAP": qml.SWAP(wires=[0, 1]),
    "T": qml.T(wires=[0]),
    "SX": qml.SX(wires=[0]),
    "Toffoli": qml.Toffoli(wires=[0, 1, 2]),
    "QFT": qml.QFT(wires=[0, 1, 2]),
    "SingleExcitation": qml.SingleExcitation(0, wires=[0, 1]),
    "SingleExcitationPlus": qml.SingleExcitationPlus(0, wires=[0, 1]),
    "SingleExcitationMinus": qml.SingleExcitationMinus(0, wires=[0, 1]),
    "DoubleExcitation": qml.DoubleExcitation(0, wires=[0, 1, 2, 3]),
    "DoubleExcitationPlus": qml.DoubleExcitationPlus(0, wires=[0, 1, 2, 3]),
    "DoubleExcitationMinus": qml.DoubleExcitationMinus(0, wires=[0, 1, 2, 3]),
    "QubitCarry": qml.QubitCarry(wires=[0, 1, 2, 3]),
    "QubitSum:": qml.QubitSum(wires=[0, 1, 2]),
}

all_ops = ops.keys()

# non-parametrized qubit gates
Пример #8
0
 "RY":
 qml.RY(0, wires=[0]),
 "RZ":
 qml.RZ(0, wires=[0]),
 "Rot":
 qml.Rot(0, 0, 0, wires=[0]),
 "S":
 qml.S(wires=[0]),
 "SWAP":
 qml.SWAP(wires=[0, 1]),
 "ISWAP":
 qml.ISWAP(wires=[0, 1]),
 "T":
 qml.T(wires=[0]),
 "SX":
 qml.SX(wires=[0]),
 "Toffoli":
 qml.Toffoli(wires=[0, 1, 2]),
 "QFT":
 qml.QFT(wires=[0, 1, 2]),
 "IsingXX":
 qml.IsingXX(0, wires=[0, 1]),
 "IsingYY":
 qml.IsingYY(0, wires=[0, 1]),
 "IsingZZ":
 qml.IsingZZ(0, wires=[0, 1]),
 "SingleExcitation":
 qml.SingleExcitation(0, wires=[0, 1]),
 "SingleExcitationPlus":
 qml.SingleExcitationPlus(0, wires=[0, 1]),
 "SingleExcitationMinus":
Пример #9
0
def _decomposition_2_cnots(U, wires):
    r"""If 2 CNOTs are required, we can write the circuit as
     -╭U- = -A--╭X--RZ(d)--╭X--C-
     -╰U- = -B--╰C--RX(p)--╰C--D-
    We need to find the angles for the Z and X rotations such that the inner
    part has the same spectrum as U, and then we can recover A, B, C, D.
    """
    # Compute the rotation angles
    u = math.dot(Edag, math.dot(U, E))
    gammaU = math.dot(u, math.T(u))
    evs, _ = math.linalg.eig(gammaU)

    # These choices are based on Proposition III.3 of
    # https://arxiv.org/abs/quant-ph/0308045
    # There is, however, a special case where the circuit has the form
    # -╭U- = -A--╭C--╭X--C-
    # -╰U- = -B--╰X--╰C--D-
    #
    # or some variant of this, where the two CNOTs are adjacent.
    #
    # What happens here is that the set of evs is -1, -1, 1, 1 and we can write
    # -╭U- = -A--╭X--SZ--╭X--C-
    # -╰U- = -B--╰C--SX--╰C--D-
    # where SZ and SX are square roots of Z and X respectively. (This
    # decomposition comes from using Hadamards to flip the direction of the
    # first CNOT, and then decomposing them and merging single-qubit gates.) For
    # some reason this case is not handled properly with the full algorithm, so
    # we treat it separately.

    sorted_evs = math.sort(math.real(evs))

    if math.allclose(sorted_evs, [-1, -1, 1, 1]):
        interior_decomp = [
            qml.CNOT(wires=[wires[1], wires[0]]),
            qml.S(wires=wires[0]),
            qml.SX(wires=wires[1]),
            qml.CNOT(wires=[wires[1], wires[0]]),
        ]

        # S \otimes SX
        inner_matrix = S_SX
    else:
        # For the non-special case, the eigenvalues come in conjugate pairs.
        # We need to find two non-conjugate eigenvalues to extract the angles.
        x = math.angle(evs[0])
        y = math.angle(evs[1])

        # If it was the conjugate, grab a different eigenvalue.
        if math.allclose(x, -y):
            y = math.angle(evs[2])

        delta = (x + y) / 2
        phi = (x - y) / 2

        interior_decomp = [
            qml.CNOT(wires=[wires[1], wires[0]]),
            qml.RZ(delta, wires=wires[0]),
            qml.RX(phi, wires=wires[1]),
            qml.CNOT(wires=[wires[1], wires[0]]),
        ]

        RZd = qml.RZ(math.cast_like(delta, 1j), wires=0).matrix
        RXp = qml.RX(phi, wires=0).matrix
        inner_matrix = math.kron(RZd, RXp)

    # We need the matrix representation of this interior part, V, in order to
    # decompose U = (A \otimes B) V (C \otimes D)
    V = math.dot(math.cast_like(CNOT10, U),
                 math.dot(inner_matrix, math.cast_like(CNOT10, U)))

    # Now we find the A, B, C, D in SU(2), and return the decomposition
    A, B, C, D = _extract_su2su2_prefactors(U, V)

    A_ops = zyz_decomposition(A, wires[0])
    B_ops = zyz_decomposition(B, wires[1])
    C_ops = zyz_decomposition(C, wires[0])
    D_ops = zyz_decomposition(D, wires[1])

    return C_ops + D_ops + interior_decomp + A_ops + B_ops
Пример #10
0
 def circuit():
     qml.RY(par, wires=[0])
     qml.SX(wires=[0]).inv()
     return qml.expval(qml.PauliX(0))
Пример #11
0
                op.queue()
            return qml.state()

        assert np.allclose(f(), rnd_state)
        spy.assert_called()


label_data = [
    (qml.Identity(0), "I", "I"),
    (qml.Hadamard(0), "H", "H"),
    (qml.PauliX(0), "X", "X"),
    (qml.PauliY(0), "Y", "Y"),
    (qml.PauliZ(0), "Z", "Z"),
    (qml.S(wires=0), "S", "S⁻¹"),
    (qml.T(wires=0), "T", "T⁻¹"),
    (qml.SX(wires=0), "SX", "SX⁻¹"),
    (qml.CNOT(wires=(0, 1)), "⊕", "⊕"),
    (qml.CZ(wires=(0, 1)), "Z", "Z"),
    (qml.CY(wires=(0, 1)), "Y", "Y"),
    (qml.SWAP(wires=(0, 1)), "SWAP", "SWAP⁻¹"),
    (qml.ISWAP(wires=(0, 1)), "ISWAP", "ISWAP⁻¹"),
    (qml.SISWAP(wires=(0, 1)), "SISWAP", "SISWAP⁻¹"),
    (qml.SQISW(wires=(0, 1)), "SISWAP", "SISWAP⁻¹"),
    (qml.CSWAP(wires=(0, 1, 2)), "SWAP", "SWAP"),
    (qml.Toffoli(wires=(0, 1, 2)), "⊕", "⊕"),
    (qml.MultiControlledX(control_wires=(0, 1, 2), wires=(3)), "⊕", "⊕"),
    (qml.Barrier(0), "||", "||"),
    (qml.WireCut(wires=0), "//", "//"),
]

Пример #12
0
def ideal_experiment():
    qml.SX(wires=0)
    return qml.state()
Пример #13
0
            for op in tape.operations:
                op.queue()
            return qml.state()

        assert np.allclose(f(), rnd_state)
        spy.assert_called()


label_data = [
    (qml.Hadamard(0), "H", "H"),
    (qml.PauliX(0), "X", "X"),
    (qml.PauliY(0), "Y", "Y"),
    (qml.PauliZ(0), "Z", "Z"),
    (qml.S(wires=0), "S", "S⁻¹"),
    (qml.T(wires=0), "T", "T⁻¹"),
    (qml.SX(wires=0), "SX", "SX⁻¹"),
    (qml.CNOT(wires=(0, 1)), "⊕", "⊕"),
    (qml.CZ(wires=(0, 1)), "Z", "Z"),
    (qml.CY(wires=(0, 1)), "Y", "Y"),
    (qml.SWAP(wires=(0, 1)), "SWAP", "SWAP⁻¹"),
    (qml.ISWAP(wires=(0, 1)), "ISWAP", "ISWAP⁻¹"),
    (qml.SISWAP(wires=(0, 1)), "SISWAP", "SISWAP⁻¹"),
    (qml.SQISW(wires=(0, 1)), "SISWAP", "SISWAP⁻¹"),
    (qml.CSWAP(wires=(0, 1, 2)), "SWAP", "SWAP"),
    (qml.Toffoli(wires=(0, 1, 2)), "⊕", "⊕"),
    (qml.MultiControlledX(control_wires=(0, 1, 2), wires=(3)), "⊕", "⊕"),
]


@pytest.mark.parametrize("op, label1, label2", label_data)
def test_label_method(op, label1, label2):