示例#1
0
    def test_hermitian_expectation(self, theta, phi, varphi, tol):
        """Test that arbitrary Hermitian expectation values are correct"""
        dev = DefaultQubitTF(wires=2)

        with qml.tape.QuantumTape() as tape:
            queue = [
                qml.RY(theta, wires=0),
                qml.RY(phi, wires=1),
                qml.CNOT(wires=[0, 1])
            ]
            observables = [
                qml.expval(qml.Hermitian(A, wires=[i])) for i in range(2)
            ]

        res = dev.execute(tape)

        a = A[0, 0]
        re_b = A[0, 1].real
        d = A[1, 1]
        ev1 = ((a - d) * np.cos(theta) +
               2 * re_b * np.sin(theta) * np.sin(phi) + a + d) / 2
        ev2 = ((a - d) * np.cos(theta) * np.cos(phi) + 2 * re_b * np.sin(phi) +
               a + d) / 2
        expected = np.array([ev1, ev2])

        assert np.allclose(res, expected, atol=tol, rtol=0)
示例#2
0
    def test_multi_mode_hermitian_expectation(self, theta, phi, varphi, tol):
        """Test that arbitrary multi-mode Hermitian expectation values are correct"""
        A = np.array([
            [-6, 2 + 1j, -3, -5 + 2j],
            [2 - 1j, 0, 2 - 1j, -5 + 4j],
            [-3, 2 + 1j, 0, -4 + 3j],
            [-5 - 2j, -5 - 4j, -4 - 3j, -6],
        ])

        dev = DefaultQubitTF(wires=2)

        with qml.tape.QuantumTape() as tape:
            queue = [
                qml.RY(theta, wires=0),
                qml.RY(phi, wires=1),
                qml.CNOT(wires=[0, 1])
            ]
            observables = [qml.expval(qml.Hermitian(A, wires=[0, 1]))]

        res = dev.execute(tape)

        # below is the analytic expectation value for this circuit with arbitrary
        # Hermitian observable A
        expected = 0.5 * (6 * np.cos(theta) * np.sin(phi) - np.sin(theta) *
                          (8 * np.sin(phi) + 7 * np.cos(phi) + 3) -
                          2 * np.sin(phi) - 6 * np.cos(phi) - 6)

        assert np.allclose(res, expected, atol=tol, rtol=0)
示例#3
0
    def test_multi_mode_hermitian_expectation(self, theta, phi, varphi, tol):
        """Test that arbitrary multi-mode Hermitian expectation values are correct"""
        A = np.array([
            [-6, 2 + 1j, -3, -5 + 2j],
            [2 - 1j, 0, 2 - 1j, -5 + 4j],
            [-3, 2 + 1j, 0, -4 + 3j],
            [-5 - 2j, -5 - 4j, -4 - 3j, -6],
        ])

        dev = DefaultQubitTF(wires=2)
        queue = [
            qml.RY(theta, wires=0),
            qml.RY(phi, wires=1),
            qml.CNOT(wires=[0, 1])
        ]
        observables = [qml.Hermitian(A, wires=[0, 1])]

        for i in range(len(observables)):
            observables[i].return_type = qml.operation.Expectation

        res = dev.execute(
            qml.CircuitGraph(queue + observables, {}, Wires([0, 1])))

        # below is the analytic expectation value for this circuit with arbitrary
        # Hermitian observable A
        expected = 0.5 * (6 * np.cos(theta) * np.sin(phi) - np.sin(theta) *
                          (8 * np.sin(phi) + 7 * np.cos(phi) + 3) -
                          2 * np.sin(phi) - 6 * np.cos(phi) - 6)

        assert np.allclose(res, expected, atol=tol, rtol=0)
示例#4
0
    def test_hermitian_expectation(self, theta, phi, varphi, tol):
        """Test that arbitrary Hermitian expectation values are correct"""
        dev = DefaultQubitTF(wires=2)
        queue = [
            qml.RY(theta, wires=0),
            qml.RY(phi, wires=1),
            qml.CNOT(wires=[0, 1])
        ]
        observables = [qml.Hermitian(A, wires=[i]) for i in range(2)]

        for i in range(len(observables)):
            observables[i].return_type = qml.operation.Expectation

        res = dev.execute(
            qml.CircuitGraph(queue + observables, {}, Wires([0, 1])))

        a = A[0, 0]
        re_b = A[0, 1].real
        d = A[1, 1]
        ev1 = ((a - d) * np.cos(theta) +
               2 * re_b * np.sin(theta) * np.sin(phi) + a + d) / 2
        ev2 = ((a - d) * np.cos(theta) * np.cos(phi) + 2 * re_b * np.sin(phi) +
               a + d) / 2
        expected = np.array([ev1, ev2])

        assert np.allclose(res, expected, atol=tol, rtol=0)
    def test_invalid_qubit_state_vector_size(self):
        """Test that an exception is raised if the state
        vector is the wrong size"""
        dev = DefaultQubitTF(wires=2)
        state = np.array([0, 1])

        with pytest.raises(ValueError, match=r"State vector must be of length 2\*\*wires"):
            dev.apply([qml.QubitStateVector(state, wires=[0, 1])])
示例#6
0
    def test_apply_ops_above_8_wires_using_special(self):
        """Test that special apply methods that involve slicing function correctly when using 9
        wires"""
        dev = DefaultQubitTF(wires=9)
        dev._apply_ops = {"CNOT": dev._apply_cnot}

        queue = [qml.CNOT(wires=[1, 2])]
        dev.apply(queue)
    def test_invalid_qubit_state_vector_norm(self):
        """Test that an exception is raised if the state
        vector is not normalized"""
        dev = DefaultQubitTF(wires=2)
        state = np.array([0, 12])

        with pytest.raises(ValueError, match=r"Sum of amplitudes-squared does not equal one"):
            dev.apply([qml.QubitStateVector(state, wires=[0])])
示例#8
0
    def test_invalid_basis_state(self, tol):
        """Test that an exception is raised if the basis state is invalid"""
        dev = DefaultQubitTF(wires=4)
        state = np.array([0, 0, 1, 2])

        with pytest.raises(
                ValueError,
                match=r"BasisState parameter must consist of 0 or 1 integers"):
            dev.apply([qml.BasisState(state, wires=[0, 1, 2, 3])])
    def test_invalid_basis_state_length(self, tol):
        """Test that an exception is raised if the basis state is the wrong size"""
        dev = DefaultQubitTF(wires=4)
        state = np.array([0, 0, 1, 0])

        with pytest.raises(
            ValueError, match=r"BasisState parameter and wires must be of equal length"
        ):
            dev.apply([qml.BasisState(state, wires=[0, 1, 2])])
    def test_single_wire_expectation(self, gate, obs, expected, theta, phi, varphi, tol):
        """Test that identity expectation value (i.e. the trace) is 1"""
        dev = DefaultQubitTF(wires=2)
        queue = [gate(theta, wires=0), gate(phi, wires=1), qml.CNOT(wires=[0, 1])]
        observables = [obs(wires=[i]) for i in range(2)]

        for i in range(len(observables)):
            observables[i].return_type = qml.operation.Expectation

        res = dev.execute(qml.CircuitGraph(queue + observables, {}, Wires([0, 1, 2])))
        assert np.allclose(res, expected(theta, phi), atol=tol, rtol=0)
    def test_invalid_state_prep(self):
        """Test that an exception is raised if a state preparation is not the
        first operation in the circuit."""
        dev = DefaultQubitTF(wires=2)
        state = np.array([0, 12])

        with pytest.raises(
            qml.DeviceError,
            match=r"cannot be used after other Operations have already been applied",
        ):
            dev.apply([qml.PauliZ(0), qml.QubitStateVector(state, wires=[0])])
示例#12
0
    def test_full_subsystem_statevector(self, mocker):
        """Test applying a state vector to the full subsystem"""
        dev = DefaultQubitTF(wires=['a', 'b', 'c'])
        state = tf.constant([1, 0, 0, 0, 1, 0, 1, 1], dtype=tf.complex128) / 2.
        state_wires = qml.wires.Wires(['a', 'b', 'c'])

        spy = mocker.spy(dev, "_scatter")
        dev._apply_state_vector(state=state, device_wires=state_wires)

        assert np.all(tf.reshape(dev._state, [-1]) == state)
        spy.assert_not_called()
示例#13
0
    def test_qubit_state_vector(self, init_state, tol):
        """Test qubit state vector application"""
        dev = DefaultQubitTF(wires=1)
        state = init_state(1)

        dev.apply([qml.QubitStateVector(state, wires=[0])])

        res = dev.state
        expected = state
        assert isinstance(res, tf.Tensor)
        assert np.allclose(res, expected, atol=tol, rtol=0)
示例#14
0
    def test_apply_ops_above_8_wires(self, mocker):
        """Test that when 9 wires are used, the _apply_ops dictionary is empty and application of a
        CNOT gate is performed using _apply_unitary_einsum"""
        dev = DefaultQubitTF(wires=9)
        assert dev._apply_ops == {}

        spy = mocker.spy(DefaultQubitTF, "_apply_unitary_einsum")

        queue = [qml.CNOT(wires=[1, 2])]
        dev.apply(queue)

        spy.assert_called_once()
示例#15
0
    def test_two_qubit_parameters(self, init_state, op, func, theta, tol):
        """Test two qubit parametrized operations"""
        dev = DefaultQubitTF(wires=2)
        state = init_state(2)

        queue = [qml.QubitStateVector(state, wires=[0, 1])]
        queue += [op(theta, wires=[0, 1])]
        dev.apply(queue)

        res = dev.state
        expected = func(theta) @ state
        assert np.allclose(res, expected, atol=tol, rtol=0)
示例#16
0
    def test_three_qubit_no_parameters(self, init_state, op, mat, tol):
        """Test non-parametrized three qubit operations"""
        dev = DefaultQubitTF(wires=3)
        state = init_state(3)

        queue = [qml.QubitStateVector(state, wires=[0, 1, 2])]
        queue += [op(wires=[0, 1, 2])]
        dev.apply(queue)

        res = dev.state
        expected = mat @ state
        assert np.allclose(res, expected, atol=tol, rtol=0)
示例#17
0
    def test_partial_subsystem_statevector(self, mocker):
        """Test applying a state vector to a subset of wires of the full subsystem"""
        dev = DefaultQubitTF(wires=['a', 'b', 'c'])
        state = tf.constant([1, 0, 1, 0], dtype=tf.complex128) / np.sqrt(2.)
        state_wires = qml.wires.Wires(['a', 'c'])

        spy = mocker.spy(dev, "_scatter")
        dev._apply_state_vector(state=state, device_wires=state_wires)
        res = tf.reshape(tf.reduce_sum(dev._state, axis=(1, )), [-1])

        assert np.all(res == state)
        spy.assert_called()
示例#18
0
    def test_var(self, theta, phi, varphi, tol):
        """Tests for variance calculation"""
        dev = DefaultQubitTF(wires=1)
        # test correct variance for <Z> of a rotated state

        with qml.tape.QuantumTape() as tape:
            queue = [qml.RX(phi, wires=0), qml.RY(theta, wires=0)]
            observables = [qml.var(qml.PauliZ(wires=[0]))]

        res = dev.execute(tape)
        expected = 0.25 * (3 - np.cos(2 * theta) -
                           2 * np.cos(theta)**2 * np.cos(2 * phi))
        assert np.allclose(res, expected, atol=tol, rtol=0)
示例#19
0
    def test_qubit_unitary(self, init_state, mat, tol):
        """Test application of arbitrary qubit unitaries"""
        N = int(np.log2(len(mat)))
        dev = DefaultQubitTF(wires=N)
        state = init_state(N)

        queue = [qml.QubitStateVector(state, wires=range(N))]
        queue += [qml.QubitUnitary(mat, wires=range(N))]
        dev.apply(queue)

        res = dev.state
        expected = mat @ state
        assert np.allclose(res, expected, atol=tol, rtol=0)
示例#20
0
    def test_single_qubit_no_parameters(self, init_state, op, mat, tol):
        """Test non-parametrized single qubit operations"""
        dev = DefaultQubitTF(wires=1)
        state = init_state(1)

        queue = [qml.QubitStateVector(state, wires=[0])]
        queue += [op(wires=0)]
        dev.apply(queue)

        res = dev.state
        expected = mat @ state
        assert isinstance(res, tf.Tensor)
        assert np.allclose(res, expected, atol=tol, rtol=0)
示例#21
0
    def test_basis_state(self, tol):
        """Test basis state initialization"""
        dev = DefaultQubitTF(wires=4)
        state = np.array([0, 0, 1, 0])

        dev.apply([qml.BasisState(state, wires=[0, 1, 2, 3])])

        res = dev.state
        expected = np.zeros([2**4])
        expected[np.ravel_multi_index(state, [2] * 4)] = 1

        assert isinstance(res, tf.Tensor)
        assert np.allclose(res, expected, atol=tol, rtol=0)
    def test_var(self, theta, phi, varphi, tol):
        """Tests for variance calculation"""
        dev = DefaultQubitTF(wires=1)
        # test correct variance for <Z> of a rotated state

        queue = [qml.RX(phi, wires=0), qml.RY(theta, wires=0)]
        observables = [qml.PauliZ(wires=[0])]

        for i in range(len(observables)):
            observables[i].return_type = qml.operation.Variance

        res = dev.execute(qml.CircuitGraph(queue + observables, {}, Wires([0])))
        expected = 0.25 * (3 - np.cos(2 * theta) - 2 * np.cos(theta) ** 2 * np.cos(2 * phi))
        assert np.allclose(res, expected, atol=tol, rtol=0)
示例#23
0
    def test_single_wire_expectation(self, gate, obs, expected, theta, phi,
                                     varphi, tol):
        """Test that identity expectation value (i.e. the trace) is 1"""
        dev = DefaultQubitTF(wires=2)

        with qml.tape.QuantumTape() as tape:
            queue = [
                gate(theta, wires=0),
                gate(phi, wires=1),
                qml.CNOT(wires=[0, 1])
            ]
            observables = [qml.expval(obs(wires=[i])) for i in range(2)]

        res = dev.execute(tape)
        assert np.allclose(res, expected(theta, phi), atol=tol, rtol=0)
示例#24
0
    def test_apply_ops_not_supported(self, mocker, monkeypatch):
        """Test that when a version of TensorFlow before 2.3.0 is used, the _apply_ops dictionary is
        empty and application of a CNOT gate is performed using _apply_unitary_einsum"""
        with monkeypatch.context() as m:
            m.setattr("pennylane.devices.default_qubit_tf.SUPPORTS_APPLY_OPS",
                      False)
            dev = DefaultQubitTF(wires=3)
            assert dev._apply_ops == {}

            spy = mocker.spy(DefaultQubitTF, "_apply_unitary_einsum")

            queue = [qml.CNOT(wires=[1, 2])]
            dev.apply(queue)

            spy.assert_called_once()
示例#25
0
    def test_controlled_rotation(self, init_state, tol):
        """Test three axis controlled-rotation gate"""
        dev = DefaultQubitTF(wires=2)
        state = init_state(2)

        a = 0.542
        b = 1.3432
        c = -0.654

        queue = [qml.QubitStateVector(state, wires=[0, 1])]
        queue += [qml.CRot(a, b, c, wires=[0, 1])]
        dev.apply(queue)

        res = dev.state
        expected = CRot3(a, b, c) @ state
        assert np.allclose(res, expected, atol=tol, rtol=0)
示例#26
0
    def test_inverse_operation(self, init_state, tol):
        """Test that the inverse of an operation is correctly applied"""
        """Test three axis rotation gate"""
        dev = DefaultQubitTF(wires=1)
        state = init_state(1)

        a = 0.542
        b = 1.3432
        c = -0.654

        queue = [qml.QubitStateVector(state, wires=[0])]
        queue += [qml.Rot(a, b, c, wires=0).inv()]
        dev.apply(queue)

        res = dev.state
        expected = np.linalg.inv(Rot3(a, b, c)) @ state
        assert np.allclose(res, expected, atol=tol, rtol=0)
示例#27
0
    def test_var_hermitian(self, theta, phi, varphi, tol):
        """Tests for variance calculation using an arbitrary Hermitian observable"""
        dev = DefaultQubitTF(wires=2)

        # test correct variance for <H> of a rotated state
        H = np.array([[4, -1 + 6j], [-1 - 6j, 2]])

        with qml.tape.QuantumTape() as tape:
            queue = [qml.RX(phi, wires=0), qml.RY(theta, wires=0)]
            observables = [qml.var(qml.Hermitian(H, wires=[0]))]

        res = dev.execute(tape)
        expected = 0.5 * (2 * np.sin(2 * theta) * np.cos(phi)**2 +
                          24 * np.sin(phi) * np.cos(phi) *
                          (np.sin(theta) - np.cos(theta)) +
                          35 * np.cos(2 * phi) + 39)

        assert np.allclose(res, expected, atol=tol, rtol=0)
示例#28
0
    def test_var_hermitian(self, theta, phi, varphi, tol):
        """Tests for variance calculation using an arbitrary Hermitian observable"""
        dev = DefaultQubitTF(wires=2)

        # test correct variance for <H> of a rotated state
        H = np.array([[4, -1 + 6j], [-1 - 6j, 2]])
        queue = [qml.RX(phi, wires=0), qml.RY(theta, wires=0)]
        observables = [qml.Hermitian(H, wires=[0])]

        for i in range(len(observables)):
            observables[i].return_type = qml.operation.Variance

        res = dev.execute(qml.CircuitGraph(queue + observables, {},
                                           Wires([0])))
        expected = 0.5 * (2 * np.sin(2 * theta) * np.cos(phi)**2 +
                          24 * np.sin(phi) * np.cos(phi) *
                          (np.sin(theta) - np.cos(theta)) +
                          35 * np.cos(2 * phi) + 39)

        assert np.allclose(res, expected, atol=tol, rtol=0)