Exemplo n.º 1
0
    def test_exp(self):
        """Tests multiarg gradients with exp and tanh functions."""
        x = -2.5
        y = 1.5
        gradf = lambda x, y: (
            np.exp(x / 3) / 3 * np.tanh(y),
            np.exp(x / 3) * (1 - np.tanh(y)**2),
        )
        f = lambda x, y: np.exp(x / 3) * np.tanh(y)

        # gradient wrt first argument
        gx = qml.grad(f, 0)
        auto_gradx = gx(x, y)
        correct_gradx = gradf(x, y)[0]
        np.allclose(auto_gradx, correct_gradx)

        # gradient wrt second argument
        gy = qml.grad(f, 1)
        auto_grady = gy(x, y)
        correct_grady = gradf(x, y)[1]
        np.allclose(auto_grady, correct_grady)

        # gradient wrt both arguments
        gxy = qml.grad(f, [0, 1])
        auto_gradxy = gxy(x, y)
        correct_gradxy = gradf(x, y)
        np.allclose(auto_gradxy, correct_gradxy)
    def test_gradient_multiargs(self):
        """Tests gradients of univariate functions with multiple arguments in signature."""
        self.logTestName()

        for gradf, f, name in zip(self.grad_margs_funcs, self.margs_fns,
                                  self.fnames):
            with self.subTest(i=name):
                for jdx in range(len(x_vals[:-1])):
                    x = x_vals[jdx]
                    y = x_vals[jdx + 1]
                    # gradient wrt first argument
                    gx = qml.grad(f, 0)
                    auto_gradx = gx(x, y)
                    correct_gradx = gradf(x, y)[0]
                    self.assertAllAlmostEqual(auto_gradx,
                                              correct_gradx,
                                              delta=self.tol)
                    # gradient wrt second argument
                    gy = qml.grad(f, 1)
                    auto_grady = gy(x, y)
                    correct_grady = gradf(x, y)[1]
                    self.assertAllAlmostEqual(auto_grady,
                                              correct_grady,
                                              delta=self.tol)
                    # gradient wrt both arguments
                    gxy = qml.grad(f, [0, 1])
                    auto_gradxy = gxy(x, y)
                    correct_gradxy = gradf(x, y)
                    self.assertAllAlmostEqual(auto_gradxy,
                                              correct_gradxy,
                                              delta=self.tol)
Exemplo n.º 3
0
 def test_sin(self):
     """Tests with sin function."""
     x_vals = np.linspace(-10, 10, 16, endpoint=False)
     g = qml.grad(np.sin, 0)
     auto_grad = [g(x) for x in x_vals]
     correct_grad = np.cos(x_vals)
     np.allclose(auto_grad, correct_grad)
Exemplo n.º 4
0
 def test_linear(self):
     """Tests linear function."""
     x_vals = np.linspace(-10, 10, 16, endpoint=False)
     func = lambda x: 2 * x
     g = qml.grad(func, 0)
     auto_grad = [g(x) for x in x_vals]
     correct_grad = x_vals**2
     np.allclose(auto_grad, correct_grad)
Exemplo n.º 5
0
 def test_exp(self):
     """Tests exp function."""
     x_vals = np.linspace(-10, 10, 16, endpoint=False)
     func = lambda x: np.exp(x / 10.0) / 10.0
     g = qml.grad(func, 0)
     auto_grad = [g(x) for x in x_vals]
     correct_grad = np.exp(x_vals / 10.0)
     np.allclose(auto_grad, correct_grad)
Exemplo n.º 6
0
 def test_quadratic(self):
     """Tests gradients with a quadratic function."""
     multi_var = lambda x: np.sum([x_**2 for x_ in x])
     grad_multi_var = lambda x: np.array([2 * x_ for x_ in x])
     x_vec = np.random.uniform(-5, 5, size=(2))
     g = qml.grad(multi_var, 0)
     auto_grad = g(x_vec)
     correct_grad = grad_multi_var(x_vec)
     np.allclose(auto_grad, correct_grad)
Exemplo n.º 7
0
    def test_sin(self):
        """Tests gradients with multivariate sin and cosine."""
        multi_var = lambda x: np.sin(x[0]) + np.cos(x[1])
        grad_multi_var = lambda x: np.array([np.cos(x[0]), -np.sin(x[1])])

        x_vec = [1.5, -2.5]
        g = qml.grad(multi_var, 0)
        auto_grad = g(x_vec)
        correct_grad = grad_multi_var(x_vec)
        np.allclose(auto_grad, correct_grad)
Exemplo n.º 8
0
    def test_array_parameters_autograd(self, tol):
        """Test that gradients of array parameters give
        same results as positional arguments."""

        a, b, c = 0.5, 0.54, 0.3

        def ansatz(x, y, z):
            qml.QubitStateVector(np.array([1, 0, 1, 1]) / np.sqrt(3),
                                 wires=[0, 1])
            qml.Rot(x, y, z, wires=0)
            qml.CNOT(wires=[0, 1])
            return qml.expval(qml.PauliZ(0))

        def circuit1(x, y, z):
            return ansatz(x, y, z)

        def circuit2(x, array):
            return ansatz(x, array[0], array[1])

        def circuit3(array):
            return ansatz(*array)

        dev = qml.device('default.qubit', wires=2)
        circuit1 = qml.QNode(circuit1, dev)
        grad1 = qml.grad(circuit1, argnum=[0, 1, 2])

        positional_grad = circuit1.jacobian([a, b, c])
        positional_autograd = grad1(a, b, c)
        assert np.allclose(positional_grad,
                           positional_autograd,
                           atol=tol,
                           rtol=0)

        circuit2 = qml.QNode(circuit2, dev)
        grad2 = qml.grad(circuit2, argnum=[0, 1])

        circuit3 = qml.QNode(circuit3, dev)
        grad3 = qml.grad(circuit3, argnum=0)

        array_grad = circuit3.jacobian([np.array([a, b, c])])
        array_autograd = grad3(np.array([a, b, c]))
        assert np.allclose(array_grad, array_autograd, atol=tol, rtol=0)
Exemplo n.º 9
0
    def test_linear(self):
        """Tests gradients with multivariate multidimensional linear func."""
        x_vec = np.random.uniform(-5, 5, size=(2))
        x_vec_multidim = np.expand_dims(x_vec, axis=1)

        gradf = lambda x: np.array([[2 * x_[0]] for x_ in x])
        f = lambda x: np.sum([x_[0]**2 for x_ in x])

        g = qml.grad(f, 0)
        auto_grad = g(x_vec_multidim)
        correct_grad = gradf(x_vec_multidim)
        np.allclose(auto_grad, correct_grad)
Exemplo n.º 10
0
 def test_exp(self):
     """Tests gradients with a multivariate exp and tanh."""
     multi_var = lambda x: np.exp(x[0] / 3) * np.tanh(x[1])
     grad_multi_var = lambda x: np.array([
         np.exp(x[0] / 3) / 3 * np.tanh(x[1]),
         np.exp(x[0] / 3) * (1 - np.tanh(x[1])**2),
     ])
     x_vec = np.random.uniform(-5, 5, size=(2))
     g = qml.grad(multi_var, 0)
     auto_grad = g(x_vec)
     correct_grad = grad_multi_var(x_vec)
     np.allclose(auto_grad, correct_grad)
Exemplo n.º 11
0
    def test_array_parameters_autograd(self):
        "Test that gradients of array parameters give same results as positional arguments."
        self.logTestName()

        a, b, c = 0.5, 0.54, 0.3

        def ansatz(x, y, z):
            qml.QubitStateVector(np.array([1, 0, 1, 1]) / np.sqrt(3),
                                 wires=[0, 1])
            qml.Rot(x, y, z, wires=0)
            qml.CNOT(wires=[0, 1])
            return qml.expval.PauliZ(0)

        def circuit1(x, y, z):
            return ansatz(x, y, z)

        def circuit2(x, array):
            return ansatz(x, array[0], array[1])

        def circuit3(array):
            return ansatz(*array)

        circuit1 = qml.QNode(circuit1, self.dev2)
        grad1 = qml.grad(circuit1, argnum=[0, 1, 2])

        positional_grad = circuit1.jacobian([a, b, c])
        positional_autograd = grad1(a, b, c)
        self.assertAllAlmostEqual(positional_grad,
                                  positional_autograd,
                                  delta=self.tol)

        circuit2 = qml.QNode(circuit2, self.dev2)
        grad2 = qml.grad(circuit2, argnum=[0, 1])

        circuit3 = qml.QNode(circuit3, self.dev2)
        grad3 = qml.grad(circuit3, argnum=0)

        array_grad = circuit3.jacobian([np.array([a, b, c])])
        array_autograd = grad3(np.array([a, b, c]))
        self.assertAllAlmostEqual(array_grad, array_autograd, delta=self.tol)
Exemplo n.º 12
0
    def test_sin(self):
        """Tests gradients with multivariate multidimensional sin and cos."""
        x_vec = np.random.uniform(-5, 5, size=(2))
        x_vec_multidim = np.expand_dims(x_vec, axis=1)

        gradf = lambda x: np.array([[np.cos(x[0, 0])], [-np.sin(x[[1]])]],
                                   dtype=np.float64)
        f = lambda x: np.sin(x[0, 0]) + np.cos(x[1, 0])

        g = qml.grad(f, 0)
        auto_grad = g(x_vec_multidim)
        correct_grad = gradf(x_vec_multidim)
        np.allclose(auto_grad, correct_grad)
    def test_gradient_univar(self):
        """Tests gradients of univariate unidimensional functions."""
        self.logTestName()

        for gradf, f, name in zip(self.grad_uni_fns, self.univariate_funcs,
                                  self.fnames):
            with self.subTest(i=name):
                for x in x_vals:
                    g = qml.grad(f, 0)
                    auto_grad = g(x)
                    correct_grad = gradf(x)
                    self.assertAlmostEqual(auto_grad,
                                           correct_grad,
                                           delta=self.tol)
Exemplo n.º 14
0
    def test_exp(self):
        """Tests gradients with multivariate multidimensional exp and tanh."""
        x_vec = np.random.uniform(-5, 5, size=(2))
        x_vec_multidim = np.expand_dims(x_vec, axis=1)

        gradf = lambda x: np.array([
            [np.exp(x[0, 0] / 3) / 3 * np.tanh(x[1, 0])],
            [np.exp(x[0, 0] / 3) * (1 - np.tanh(x[1, 0])**2)],
        ])
        f = lambda x: np.exp(x[0, 0] / 3) * np.tanh(x[1, 0])

        g = qml.grad(f, 0)
        auto_grad = g(x_vec_multidim)
        correct_grad = gradf(x_vec_multidim)
        np.allclose(auto_grad, correct_grad)
    def test_gradient_multivar(self):
        """Tests gradients of multivariate unidimensional functions."""
        self.logTestName()

        for gradf, f, name in zip(self.grad_multi_funcs,
                                  self.multivariate_funcs, self.fnames):
            with self.subTest(i=name):
                for jdx in range(len(x_vals[:-1])):
                    x_vec = x_vals[jdx:jdx + 2]
                    g = qml.grad(f, 0)
                    auto_grad = g(x_vec)
                    correct_grad = gradf(x_vec)
                    self.assertAllAlmostEqual(auto_grad,
                                              correct_grad,
                                              delta=self.tol)
Exemplo n.º 16
0
    def test_sin(self):
        """Tests multiarg gradients with sin and cos functions."""
        x = -2.5
        y = 1.5
        gradf = lambda x, y: (np.cos(x), -np.sin(y))
        f = lambda x, y: np.sin(x) + np.cos(y)

        # gradient wrt first argument
        gx = qml.grad(f, 0)
        auto_gradx = gx(x, y)
        correct_gradx = gradf(x, y)[0]
        np.allclose(auto_gradx, correct_gradx)

        # gradient wrt second argument
        gy = qml.grad(f, 1)
        auto_grady = gy(x, y)
        correct_grady = gradf(x, y)[1]
        np.allclose(auto_grady, correct_grady)

        # gradient wrt both arguments
        gxy = qml.grad(f, [0, 1])
        auto_gradxy = gxy(x, y)
        correct_gradxy = gradf(x, y)
        np.allclose(auto_gradxy, correct_gradxy)
Exemplo n.º 17
0
    def test_linear(self):
        """Tests multiarg gradients with a linear function."""
        x = -2.5
        y = 1.5
        gradf = lambda x, y: (2 * x, 2 * y)
        f = lambda x, y: np.sum([x_**2 for x_ in [x, y]])

        # gradient wrt first argument
        gx = qml.grad(f, 0)
        auto_gradx = gx(x, y)
        correct_gradx = gradf(x, y)[0]
        np.allclose(auto_gradx, correct_gradx)

        # gradient wrt second argument
        gy = qml.grad(f, 1)
        auto_grady = gy(x, y)
        correct_grady = gradf(x, y)[1]
        np.allclose(auto_grady, correct_grady)

        # gradient wrt both arguments
        gxy = qml.grad(f, [0, 1])
        auto_gradxy = gxy(x, y)
        correct_gradxy = gradf(x, y)
        np.allclose(auto_gradxy, correct_gradxy)
    def test_gradient_multivar_multidim(self):
        """Tests gradients of multivariate multidimensional functions."""
        self.logTestName()

        for gradf, f, name in zip(self.grad_mvar_mdim_funcs,
                                  self.mvar_mdim_funcs, self.fnames):
            with self.subTest(i=name):
                for jdx in range(len(x_vals[:-1])):
                    x_vec = x_vals[jdx:jdx + 2]
                    x_vec_multidim = np.expand_dims(x_vec, axis=1)
                    g = qml.grad(f, 0)
                    auto_grad = g(x_vec_multidim)
                    correct_grad = gradf(x_vec_multidim)
                    self.assertAllAlmostEqual(auto_grad,
                                              correct_grad,
                                              delta=self.tol)
Exemplo n.º 19
0
    def test_qnode_array_parameters(self):
        "Test that QNode can take arrays as input arguments, and that they interact properly with autograd."
        self.logTestName()

        @qml.qnode(self.dev1)
        def circuit_n1s(dummy1, array, dummy2):
            qml.RY(0.5 * array[0, 1], wires=0)
            qml.RY(-0.5 * array[1, 1], wires=0)
            return qml.expval(qml.PauliX(0))  # returns a scalar

        @qml.qnode(self.dev1)
        def circuit_n1v(dummy1, array, dummy2):
            qml.RY(0.5 * array[0, 1], wires=0)
            qml.RY(-0.5 * array[1, 1], wires=0)
            return qml.expval(
                qml.PauliX(0)),  # note the comma, returns a 1-vector

        @qml.qnode(self.dev2)
        def circuit_nn(dummy1, array, dummy2):
            qml.RY(0.5 * array[0, 1], wires=0)
            qml.RY(-0.5 * array[1, 1], wires=0)
            qml.RY(array[1, 0], wires=1)
            return qml.expval(qml.PauliX(0)), qml.expval(
                qml.PauliX(1))  # returns a 2-vector

        args = (0.46, np.array([[2., 3., 0.3], [7., 4., 2.1]]), -0.13)
        grad_target = (np.array(1.),
                       np.array([[0.5, 0.43879, 0], [0, -0.43879,
                                                     0]]), np.array(-0.4))
        cost_target = 1.03257
        for circuit in [circuit_n1s, circuit_n1v, circuit_nn]:

            def cost(x, array, y):
                c = circuit(0.111, array, 4.5)
                if not np.isscalar(c):
                    c = c[0]  # get a scalar
                return c + 0.5 * array[0, 0] + x - 0.4 * y

            cost_grad = qml.grad(cost, argnum=[0, 1, 2])
            self.assertAllAlmostEqual(cost(*args), cost_target, delta=self.tol)
            self.assertAllAlmostEqual(cost_grad(*args),
                                      grad_target,
                                      delta=self.tol)
Exemplo n.º 20
0
    def test_qnode_gradient_agrees(self):
        "Tests that simple gradient example is consistent."
        self.logTestName()

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

        @qml.qnode(dev, interface='autograd')
        def circuit(phi, theta):
            qml.RX(phi[0], wires=0)
            qml.RY(phi[1], wires=1)
            qml.CNOT(wires=[0, 1])
            qml.PhaseShift(theta[0], wires=0)
            return qml.expval(qml.PauliZ(0))

        @qml.qnode(dev, interface='torch')
        def circuit_torch(phi, theta):
            qml.RX(phi[0], wires=0)
            qml.RY(phi[1], wires=1)
            qml.CNOT(wires=[0, 1])
            qml.PhaseShift(theta[0], wires=0)
            return qml.expval(qml.PauliZ(0))

        phi = [0.5, 0.1]
        theta = [0.2]

        phi_t = torch.autograd.Variable(torch.tensor(phi), requires_grad=True)
        theta_t = torch.autograd.Variable(torch.tensor(theta),
                                          requires_grad=True)

        dcircuit = qml.grad(circuit, [0, 1])
        autograd_grad = dcircuit(phi, theta)

        torch_eval = circuit_torch(phi_t, theta_t)
        torch_eval.backward()

        self.assertAllAlmostEqual(autograd_grad[0],
                                  phi_t.grad.detach().numpy(),
                                  delta=self.tol)
        self.assertAllAlmostEqual(autograd_grad[1],
                                  theta_t.grad.detach().numpy(),
                                  delta=self.tol)
Exemplo n.º 21
0
    def test_qnode_gradient_agrees(self):
        "Tests that simple gradient example is consistent."
        self.logTestName()

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

        @qml.qnode(dev, interface='autograd')
        def circuit(phi, theta):
            qml.RX(phi[0], wires=0)
            qml.RY(phi[1], wires=1)
            qml.CNOT(wires=[0, 1])
            qml.PhaseShift(theta[0], wires=0)
            return qml.expval.PauliZ(0)

        @qml.qnode(dev, interface='tfe')
        def circuit_tfe(phi, theta):
            qml.RX(phi[0], wires=0)
            qml.RY(phi[1], wires=1)
            qml.CNOT(wires=[0, 1])
            qml.PhaseShift(theta[0], wires=0)
            return qml.expval.PauliZ(0)

        phi = [0.5, 0.1]
        theta = [0.2]

        phi_t = tfe.Variable(phi)
        theta_t = tfe.Variable(theta)

        dcircuit = qml.grad(circuit, [0, 1])
        autograd_grad = dcircuit(phi, theta)

        dcircuit = tfe.gradients_function(circuit_tfe)
        tfe_grad = dcircuit(phi_t, theta_t)

        self.assertAllAlmostEqual(autograd_grad[0],
                                  tfe_grad[0],
                                  delta=self.tol)
        self.assertAllAlmostEqual(autograd_grad[1],
                                  tfe_grad[1],
                                  delta=self.tol)