Пример #1
0
    def test_hamiltonian_dif_autograd(self, tol):
        """Tests that the hamiltonian_expand tape transform is differentiable with the Autograd interface"""

        H = qml.Hamiltonian(
            [-0.2, 0.5, 1],
            [qml.PauliX(1),
             qml.PauliZ(1) @ qml.PauliY(2),
             qml.PauliZ(0)])

        var = [
            np.array(0.1),
            np.array(0.67),
            np.array(0.3),
            np.array(0.4),
            np.array(-0.5),
            np.array(0.7),
            np.array(-0.2),
            np.array(0.5),
            np.array(1.0),
        ]
        output = 0.42294409781940356
        output2 = [
            9.68883500e-02,
            -2.90832724e-01,
            -1.04448033e-01,
            -1.94289029e-09,
            3.50307411e-01,
            -3.41123470e-01,
            0.0,
            -0.43657,
            0.64123,
        ]

        with qml.tape.JacobianTape() as tape:
            for i in range(2):
                qml.RX(np.array(0), wires=0)
                qml.RX(np.array(0), wires=1)
                qml.RX(np.array(0), wires=2)
                qml.CNOT(wires=[0, 1])
                qml.CNOT(wires=[1, 2])
                qml.CNOT(wires=[2, 0])

            qml.expval(H)

        AutogradInterface.apply(tape)

        def cost(x):
            tape.set_parameters(x, trainable_only=False)
            tapes, fn = qml.transforms.hamiltonian_expand(tape)
            res = [t.execute(dev) for t in tapes]
            return fn(res)

        assert np.isclose(cost(var), output)
        grad = qml.grad(cost)(var)
        for g, o in zip(grad, output2):
            assert np.allclose(g, o, atol=tol)
Пример #2
0
 def cost(a, b, device):
     with AutogradInterface.apply(JacobianTape()) as tape:
         qml.RY(a, wires=0)
         qml.RX(b, wires=0)
         qml.expval(qml.PauliZ(0))
     assert tape.trainable_params == {0}
     return tape.execute(device)
Пример #3
0
    def to_autograd(self):
        """Apply the Autograd interface to the internal quantum tape."""
        self.dtype = AutogradInterface.dtype

        if self.interface != "autograd" and self.interface is not None:
            # Since the interface is changing, need to re-validate the tape class.
            self._tape, interface, self.device, diff_options = self.get_tape(
                self._original_device, "autograd", self.diff_method)

            self.interface = interface
            self.diff_options.update(diff_options)
        else:
            self.interface = "autograd"

        if self.qtape is not None:
            AutogradInterface.apply(self.qtape)
Пример #4
0
 def cost(a, U, device):
     with AutogradInterface.apply(JacobianTape()) as tape:
         qml.QubitUnitary(U, wires=0)
         qml.RY(a, wires=0)
         qml.expval(qml.PauliZ(0))
     assert tape.trainable_params == [1]
     return tape.execute(device)
Пример #5
0
        def cost_fn(x):
            with AutogradInterface.apply(qml.tape.CVParamShiftTape()) as tape:
                qml.Squeezing(x[0], 0, wires=0)
                qml.Rotation(x[1], wires=0)
                qml.var(qml.X(wires=[0]))

            tapes, fn = param_shift_cv(tape, dev)
            return fn([t.execute(dev) for t in tapes])[0, 1]
Пример #6
0
        def cost(x, device):
            with AutogradInterface.apply(JacobianTape()) as tape:
                qml.Hadamard(wires=[0])
                qml.CNOT(wires=[0, 1])
                qml.sample(qml.PauliZ(0))
                qml.sample(qml.PauliX(1))

            return tape.execute(device)
Пример #7
0
    def test_interface_str(self):
        """Test that the interface string is correctly identified as autograd"""
        with AutogradInterface.apply(JacobianTape()) as tape:
            qml.RX(0.5, wires=0)
            qml.expval(qml.PauliX(0))

        assert tape.interface == "autograd"
        assert isinstance(tape, AutogradInterface)
Пример #8
0
        def cost(a, device):
            with AutogradInterface.apply(JacobianTape()) as qtape:
                qml.RY(a[0], wires=0)
                qml.RX(a[1], wires=0)
                qml.expval(qml.PauliZ(0))

            qtape.jacobian_options = {"h": 1e-8, "order": 2}
            return qtape.execute(dev)
Пример #9
0
 def cost(a, b, c, device):
     with AutogradInterface.apply(JacobianTape()) as tape:
         qml.RY(a * c, wires=0)
         qml.RZ(b, wires=0)
         qml.RX(c + c ** 2 + np.sin(a), wires=0)
         qml.expval(qml.PauliZ(0))
     assert tape.trainable_params == [0, 2]
     return tape.execute(device)
Пример #10
0
        def cost(x, y, device):
            with AutogradInterface.apply(JacobianTape()) as tape:
                qml.RX(x, wires=[0])
                qml.RY(y, wires=[1])
                qml.CNOT(wires=[0, 1])
                qml.expval(qml.PauliZ(0))
                qml.probs(wires=[1])

            return tape.execute(device)
Пример #11
0
        def cost_fn(a, p, device):
            tape = JacobianTape()

            with tape:
                qml.RX(a, wires=0)
                U3(*p, wires=0)
                qml.expval(qml.PauliX(0))

            tape = AutogradInterface.apply(tape.expand())

            assert tape.trainable_params == [1, 2, 3, 4]
            assert [i.name for i in tape.operations] == ["RX", "Rot", "PhaseShift"]
            assert np.all(np.array(tape.get_parameters()) == [p[2], p[0], -p[2], p[1] + p[2]])

            return tape.execute(device=device)
Пример #12
0
    def test_get_parameters(self):
        """Test that the get_parameters function correctly gets the trainable parameters and all
        parameters, depending on the trainable_only argument"""
        a = np.array(0.1, requires_grad=True)
        b = np.array(0.2, requires_grad=False)
        c = np.array(0.3, requires_grad=True)
        d = np.array(0.4, requires_grad=False)

        with AutogradInterface.apply(JacobianTape()) as tape:
            qml.Rot(a, b, c, wires=0)
            qml.RX(d, wires=1)
            qml.CNOT(wires=[0, 1])
            qml.expval(qml.PauliX(0))

        assert tape.trainable_params == [0, 2]
        assert np.all(tape.get_parameters(trainable_only=True) == [a, c])
        assert np.all(tape.get_parameters(trainable_only=False) == [a, b, c, d])
Пример #13
0
    def test_reusing_quantum_tape(self, tol):
        """Test re-using a quantum tape by passing new parameters"""
        a = np.array(0.1, requires_grad=True)
        b = np.array(0.2, requires_grad=True)

        dev = qml.device("default.qubit", wires=2)

        with AutogradInterface.apply(JacobianTape()) as tape:
            qml.RY(a, wires=0)
            qml.RX(b, wires=1)
            qml.CNOT(wires=[0, 1])
            qml.expval(qml.PauliZ(0))
            qml.expval(qml.PauliY(1))

        assert tape.trainable_params == [0, 1]

        def cost(a, b):
            tape.set_parameters([a, b])
            return tape.execute(dev)

        jac_fn = qml.jacobian(cost)
        jac = jac_fn(a, b)

        a = np.array(0.54, requires_grad=True)
        b = np.array(0.8, requires_grad=True)

        res2 = cost(2 * a, b)
        expected = [np.cos(2 * a), -np.cos(2 * a) * np.sin(b)]
        assert np.allclose(res2, expected, atol=tol, rtol=0)

        jac_fn = qml.jacobian(lambda a, b: cost(2 * a, b))
        jac = jac_fn(a, b)
        assert isinstance(jac, tuple) and len(jac) == 2

        expected = (
            [-2 * np.sin(2 * a), 2 * np.sin(2 * a) * np.sin(b)],
            [0, -np.cos(2 * a) * np.cos(b)],
        )
        assert np.allclose(jac[0], expected[0], atol=tol, rtol=0)
        assert np.allclose(jac[1], expected[1], atol=tol, rtol=0)