コード例 #1
0
ファイル: test_qnode.py プロジェクト: wuben3125/pennylane
    def test_keywordarg_not_differentiated(self):
        "Tests that qnodes do not differentiate w.r.t. keyword arguments."
        self.logTestName()

        a, b = 0.5, 0.54

        def circuit1(weights, x=0.3):
            qml.QubitStateVector(np.array([1, 0, 1, 1]) / np.sqrt(3), [0, 1])
            qml.Rot(weights[0], weights[1], x, 0)
            qml.CNOT([0, 1])
            return qml.expval.PauliZ(0), qml.expval.PauliY(1)

        circuit1 = qml.QNode(circuit1, self.dev2)

        def circuit2(weights):
            qml.QubitStateVector(np.array([1, 0, 1, 1]) / np.sqrt(3), [0, 1])
            qml.Rot(weights[0], weights[1], 0.3, 0)
            qml.CNOT([0, 1])
            return qml.expval.PauliZ(0), qml.expval.PauliY(1)

        circuit2 = qml.QNode(circuit2, self.dev2)

        res1 = circuit1.jacobian([np.array([a, b])])
        res2 = circuit2.jacobian([np.array([a, b])])

        self.assertAllAlmostEqual(res1, res2, delta=self.tol)
コード例 #2
0
ファイル: test_qnode.py プロジェクト: zeta1999/pennylane
    def test_keywordarg_not_differentiated(self, tol):
        """Tests that qnodes do not differentiate w.r.t. keyword arguments."""
        a, b = 0.5, 0.54

        def circuit1(weights, x=0.3):
            qml.QubitStateVector(np.array([1, 0, 1, 1]) / np.sqrt(3),
                                 wires=[0, 1])
            qml.Rot(weights[0], weights[1], x, wires=0)
            qml.CNOT(wires=[0, 1])
            return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliY(1))

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

        def circuit2(weights):
            qml.QubitStateVector(np.array([1, 0, 1, 1]) / np.sqrt(3),
                                 wires=[0, 1])
            qml.Rot(weights[0], weights[1], 0.3, wires=0)
            qml.CNOT(wires=[0, 1])
            return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliY(1))

        circuit2 = qml.QNode(circuit2, dev)

        res1 = circuit1.jacobian([np.array([a, b])])
        res2 = circuit2.jacobian([np.array([a, b])])

        assert np.allclose(res1, res2, atol=tol, rtol=0)
コード例 #3
0
    def test_simple_circuits(self):

        default_qubit = qml.device('default.qubit', wires=4)

        for dev in self.devices:
            gates = [
                qml.PauliX(wires=0),
                qml.PauliY(wires=1),
                qml.PauliZ(wires=2),
                qml.S(wires=3),
                qml.T(wires=0),
                qml.RX(2.3, wires=1),
                qml.RY(1.3, wires=2),
                qml.RZ(3.3, wires=3),
                qml.Hadamard(wires=0),
                qml.Rot(0.1, 0.2, 0.3, wires=1),
                qml.CRot(0.1, 0.2, 0.3, wires=[2, 3]),
                qml.Toffoli(wires=[0, 1, 2]),
                qml.SWAP(wires=[1, 2]),
                qml.CSWAP(wires=[1, 2, 3]),
                qml.U1(1.0, wires=0),
                qml.U2(1.0, 2.0, wires=2),
                qml.U3(1.0, 2.0, 3.0, wires=3),
                qml.CRX(0.1, wires=[1, 2]),
                qml.CRY(0.2, wires=[2, 3]),
                qml.CRZ(0.3, wires=[3, 1]),
                qml.CZ(wires=[2, 3]),
                qml.QubitUnitary(np.array([[1, 0], [0, 1]]), wires=2),
            ]

            layers = 3
            np.random.seed(1967)
            gates_per_layers = [
                np.random.permutation(gates).numpy() for _ in range(layers)
            ]

            for obs in {
                    qml.PauliX(wires=0),
                    qml.PauliY(wires=0),
                    qml.PauliZ(wires=0),
                    qml.Identity(wires=0),
                    qml.Hadamard(wires=0)
            }:
                if obs.name in dev.observables:

                    def circuit():
                        """4-qubit circuit with layers of randomly selected gates and random connections for
                        multi-qubit gates."""
                        qml.BasisState(np.array([1, 0, 0, 0]),
                                       wires=[0, 1, 2, 3])
                        for gates in gates_per_layers:
                            for gate in gates:
                                if gate.name in dev.operations:
                                    qml.apply(gate)
                        return qml.expval(obs)

                    qnode_default = qml.QNode(circuit, default_qubit)
                    qnode = qml.QNode(circuit, dev)

                    assert np.allclose(qnode(), qnode_default(), atol=1e-3)
コード例 #4
0
ファイル: test_qnode.py プロジェクト: zeta1999/pennylane
    def test_caching(self):
        """Test that the circuit structure does not change on
        subsequent evalutions with caching turned on
        """
        dev = qml.device('default.qubit', wires=2)

        def circuit(x, c=None):
            qml.RX(x, wires=0)

            for i in range(c.val):
                qml.RX(x, wires=i)

            return qml.expval(qml.PauliZ(0))

        circuit = qml.QNode(circuit, dev, cache=True)

        # first evaluation
        circuit(0, c=0)
        # check structure
        assert len(circuit.queue) == 1

        # second evaluation
        circuit(0, c=1)
        # check structure
        assert len(circuit.queue) == 1
コード例 #5
0
    def test_projectq_ops(self):

        results = [-1.0, -1.0]
        for i, dev in enumerate(self.devices[1:3]):

            gates = [
                qml.PauliX(wires=0),
                qml.PauliY(wires=1),
                qml.PauliZ(wires=2),
                SqrtX(wires=0),
                SqrtSwap(wires=[3, 0]),
            ]

            layers = 3
            np.random.seed(1967)
            gates_per_layers = [
                np.random.permutation(gates).numpy() for _ in range(layers)
            ]

            def circuit():
                """4-qubit circuit with layers of randomly selected gates."""
                for gates in gates_per_layers:
                    for gate in gates:
                        if gate.name in dev.operations:
                            qml.apply(gate)
                return qml.expval(qml.PauliZ(0))

            qnode = qml.QNode(circuit, dev)
            assert np.allclose(qnode(), results[i], atol=1e-3)
コード例 #6
0
ファイル: test_template.py プロジェクト: ycchen1989/pennylane
    def test_two_mode_rect_overparameterised(self):
        """Test that a two mode interferometer using the rectangular mesh
        correctly gives a beamsplitter+2 rotation gates when requested"""
        N = 2
        wires = range(N)
        dev = qml.device('default.gaussian', wires=N)

        theta = [0.321]
        phi = [0.234]
        varphi = [0.42342, 0.543]

        def circuit(varphi):
            qml.template.Interferometer(theta, phi, varphi, wires=wires)
            return [qml.expval.MeanPhoton(w) for w in wires]

        qnode = qml.QNode(circuit, dev)
        self.assertAllAlmostEqual(qnode(varphi), [0, 0], delta=self.tol)

        queue = qnode.queue
        self.assertEqual(len(queue), 3)

        self.assertTrue(isinstance(qnode.queue[0], qml.Beamsplitter))
        self.assertAllEqual(qnode.queue[0].parameters, theta + phi)

        self.assertTrue(isinstance(qnode.queue[1], qml.Rotation))
        self.assertAllEqual(qnode.queue[1].parameters, [varphi[0]])

        self.assertTrue(isinstance(qnode.queue[2], qml.Rotation))
        self.assertAllEqual(qnode.queue[2].parameters, [varphi[1]])
コード例 #7
0
ファイル: test_template.py プロジェクト: ycchen1989/pennylane
    def test_four_mode_triangular(self):
        """Test that a 4 mode interferometer using triangular mesh gives the correct gates"""
        N = 4
        wires = range(N)
        dev = qml.device('default.gaussian', wires=N)

        theta = [0.321, 0.4523, 0.21321, 0.123, 0.5234, 1.23]
        phi = [0.234, 0.324, 0.234, 1.453, 1.42341, -0.534]
        varphi = [0.42342, 0.234, 0.4523]

        def circuit_tria(varphi):
            qml.template.Interferometer(theta,
                                        phi,
                                        varphi,
                                        mesh='triangular',
                                        wires=wires)
            return [qml.expval.MeanPhoton(w) for w in wires]

        qnode = qml.QNode(circuit_tria, dev)
        self.assertAllAlmostEqual(qnode(varphi), [0] * N, delta=self.tol)

        queue = qnode.queue
        self.assertEqual(len(queue), 9)

        expected_bs_wires = [[2, 3], [1, 2], [0, 1], [2, 3], [1, 2], [2, 3]]

        for idx, op in enumerate(qnode.queue[:6]):
            self.assertTrue(isinstance(op, qml.Beamsplitter))
            self.assertAllEqual(op.parameters, [theta[idx], phi[idx]])
            self.assertAllEqual(op.wires, expected_bs_wires[idx])

        for idx, op in enumerate(qnode.queue[6:]):
            self.assertTrue(isinstance(op, qml.Rotation))
            self.assertAllEqual(op.parameters, [varphi[idx]])
            self.assertAllEqual(op.wires, [idx])
コード例 #8
0
    def test_op_successors(self):
        "Tests QNode._op_successors()."
        self.logTestName()

        def qf(x):
            qml.RX(x, wires=[0])
            qml.CNOT(wires=[0, 1])
            qml.RY(0.4, wires=[0])
            qml.RZ(-0.2, wires=[1])
            return qml.expval(qml.PauliX(0)), qml.expval(qml.PauliZ(1))
        q = qml.QNode(qf, self.dev2)
        q.construct([1.0])

        # the six operations in qf should appear in q.ops in the same order they appear above
        self.assertTrue(q.ops[0].name == 'RX')
        self.assertTrue(q.ops[1].name == 'CNOT')
        self.assertTrue(q.ops[2].name == 'RY')
        self.assertTrue(q.ops[3].name == 'RZ')
        self.assertTrue(q.ops[4].name == 'PauliX')
        self.assertTrue(q.ops[5].name == 'PauliZ')
        # only gates
        gate_successors = q._op_successors(0, only='G')
        self.assertTrue(q.ops[0] not in gate_successors)
        self.assertTrue(q.ops[1] in gate_successors)
        self.assertTrue(q.ops[4] not in gate_successors)
        # only evs
        ev_sucessors = q._op_successors(0, only='E')
        self.assertTrue(q.ops[0] not in ev_sucessors)
        self.assertTrue(q.ops[1] not in ev_sucessors)
        self.assertTrue(q.ops[4] in ev_sucessors)
        # both
        successors = q._op_successors(0, only=None)
        self.assertTrue(q.ops[0] not in successors)
        self.assertTrue(q.ops[1] in successors)
        self.assertTrue(q.ops[4] in successors)
コード例 #9
0
    def test_cv_gradients_multiple_gate_parameters(self):
        "Tests that gates with multiple free parameters yield correct gradients."
        self.logTestName()
        par = [0.4, -0.3, -0.7, 0.2]

        def qf(r0, phi0, r1, phi1):
            qml.Squeezing(r0, phi0, wires=[0])
            qml.Squeezing(r1, phi1, wires=[0])
            return qml.expval(qml.NumberOperator(0))

        q = qml.QNode(qf, self.gaussian_dev)
        grad_F = q.jacobian(par, method='F')
        grad_A = q.jacobian(par, method='A')
        grad_A2 = q.jacobian(par, method='A', force_order2=True)

        # analytic method works for every parameter
        self.assertTrue(q.grad_method_for_par == {i:'A' for i in range(4)})
        # the different methods agree
        self.assertAllAlmostEqual(grad_A, grad_F, delta=self.tol)
        self.assertAllAlmostEqual(grad_A2, grad_F, delta=self.tol)

        # check against the known analytic formula
        r0, phi0, r1, phi1 = par
        dn = np.zeros([4])

        dn[0] = np.cosh(2 * r1) * np.sinh(2 * r0) + np.cos(phi0 - phi1) * np.cosh(2 * r0) * np.sinh(2 * r1)
        dn[1] = -0.5 * np.sin(phi0 - phi1) * np.sinh(2 * r0) * np.sinh(2 * r1)
        dn[2] = np.cos(phi0 - phi1) * np.cosh(2 * r1) * np.sinh(2 * r0) + np.cosh(2 * r0) * np.sinh(2 * r1)
        dn[3] = 0.5 * np.sin(phi0 - phi1) * np.sinh(2 * r0) * np.sinh(2 * r1)

        self.assertAllAlmostEqual(grad_A, dn, delta=self.tol)
コード例 #10
0
ファイル: test_torch.py プロジェクト: ycchen1989/pennylane
    def test_keywordarg_gradient(self):
        "Tests that qnodes' keyword arguments work with gradients"
        self.logTestName()

        def circuit(x, y, input_state=np.array([0, 0])):
            qml.BasisState(input_state, wires=[0, 1])
            qml.RX(x, wires=[0])
            qml.RY(y, wires=[0])
            return qml.expval.PauliZ(0)

        circuit = qml.QNode(circuit, self.dev2).to_torch()

        x = 0.543
        y = 0.45632

        x_t = torch.autograd.Variable(torch.tensor(x), requires_grad=True)
        y_t = torch.autograd.Variable(torch.tensor(y), requires_grad=True)
        c = circuit(x_t, y_t, input_state=np.array([0, 0]))
        c.backward()
        self.assertAllAlmostEqual(x_t.grad.numpy(), [-np.sin(x)*np.cos(y)], delta=self.tol)
        self.assertAllAlmostEqual(y_t.grad.numpy(), [-np.sin(y)*np.cos(x)], delta=self.tol)

        x_t = torch.autograd.Variable(torch.tensor(x), requires_grad=True)
        y_t = torch.autograd.Variable(torch.tensor(y), requires_grad=True)
        c = circuit(x_t, y_t, input_state=np.array([1, 0]))
        c.backward()
        self.assertAllAlmostEqual(x_t.grad.numpy(), [np.sin(x)*np.cos(y)], delta=self.tol)
        self.assertAllAlmostEqual(y_t.grad.numpy(), [np.sin(y)*np.cos(x)], delta=self.tol)

        x_t = torch.autograd.Variable(torch.tensor(x), requires_grad=True)
        y_t = torch.autograd.Variable(torch.tensor(y), requires_grad=True)
        c = circuit(x_t, y_t)
        c.backward()
        self.assertAllAlmostEqual(x_t.grad.numpy(), [-np.sin(x)*np.cos(y)], delta=self.tol)
        self.assertAllAlmostEqual(y_t.grad.numpy(), [-np.sin(y)*np.cos(x)], delta=self.tol)
コード例 #11
0
ファイル: test_qnode.py プロジェクト: zeta1999/pennylane
    def test_multidim_array(self, s, tol):
        """Tests that arguments which are multidimensional arrays are
        properly evaluated and differentiated in QNodes."""

        multidim_array = np.reshape(b, s)

        def circuit(w):
            qml.RX(w[np.unravel_index(0, s)], wires=0)  # b[0]
            qml.RX(w[np.unravel_index(1, s)], wires=1)  # b[1]
            qml.RX(w[np.unravel_index(2, s)], wires=2)  # ...
            qml.RX(w[np.unravel_index(3, s)], wires=3)
            qml.RX(w[np.unravel_index(4, s)], wires=4)
            qml.RX(w[np.unravel_index(5, s)], wires=5)
            qml.RX(w[np.unravel_index(6, s)], wires=6)
            qml.RX(w[np.unravel_index(7, s)], wires=7)
            return tuple(qml.expval(qml.PauliZ(idx)) for idx in range(len(b)))

        dev = qml.device('default.qubit', wires=8)
        circuit = qml.QNode(circuit, dev)

        # circuit evaluations
        circuit_output = circuit(multidim_array)
        expected_output = np.cos(b)
        assert np.allclose(circuit_output, expected_output, atol=tol, rtol=0)

        # circuit jacobians
        circuit_jacobian = circuit.jacobian([multidim_array])
        expected_jacobian = -np.diag(np.sin(b))
        assert np.allclose(circuit_jacobian,
                           expected_jacobian,
                           atol=tol,
                           rtol=0)
コード例 #12
0
ファイル: test_qnode.py プロジェクト: zeta1999/pennylane
    def test_multiple_expectation_jacobian_array(self, tol):
        """Tests that qnodes using an array argument return correct gradients
        for multiple expectation values."""
        a, b, c = 0.5, 0.54, 0.3

        def circuit(weights):
            qml.QubitStateVector(np.array([1, 0, 1, 1]) / np.sqrt(3),
                                 wires=[0, 1])
            qml.Rot(weights[0], weights[1], weights[2], wires=0)
            qml.CNOT(wires=[0, 1])
            return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliY(1))

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

        res = circuit.jacobian([np.array([a, b, c])])
        assert np.allclose(self.expected_jacobian(a, b, c),
                           res,
                           atol=tol,
                           rtol=0)

        jac = qml.jacobian(circuit, 0)
        res = jac(np.array([a, b, c]))
        assert np.allclose(self.expected_jacobian(a, b, c),
                           res,
                           atol=tol,
                           rtol=0)
コード例 #13
0
    def test_qnode_gradient_fanout(self):
        "Tests that the correct gradient is computed for qnodes which use the same parameter in multiple gates."
        self.logTestName()

        extra_param = 0.31

        def circuit(reused_param, other_param):
            qml.RX(extra_param, wires=[0])
            qml.RY(reused_param, wires=[0])
            qml.RZ(other_param, wires=[0])
            qml.RX(reused_param, wires=[0])
            return qml.expval.PauliZ(0)

        f = qml.QNode(circuit, self.qubit_dev1)
        zero_state = np.array([1., 0.])

        for reused_p in thetas:
            reused_p = reused_p**3 / 19
            for other_p in thetas:
                other_p = other_p**2 / 11

                # autograd gradient
                grad = autograd.grad(f)
                grad_eval = grad(reused_p, other_p)

                # manual gradient
                grad_true0 = (expZ(Rx(reused_p) @ Rz(other_p) @ Ry(reused_p + np.pi / 2) @ Rx(extra_param) @ zero_state) \
                             -expZ(Rx(reused_p) @ Rz(other_p) @ Ry(reused_p - np.pi / 2) @ Rx(extra_param) @ zero_state)) / 2
                grad_true1 = (expZ(Rx(reused_p + np.pi / 2) @ Rz(other_p) @ Ry(reused_p) @ Rx(extra_param) @ zero_state) \
                             -expZ(Rx(reused_p - np.pi / 2) @ Rz(other_p) @ Ry(reused_p) @ Rx(extra_param) @ zero_state)) / 2
                grad_true = grad_true0 + grad_true1  # product rule

                self.assertAlmostEqual(grad_eval, grad_true, delta=self.tol)
コード例 #14
0
ファイル: test_qnode.py プロジェクト: wuben3125/pennylane
 def check_methods(qf, d):
     q = qml.QNode(qf, self.dev2)
     q.construct(
         par
     )  # NOTE: the default plugin is a discrete (qubit) simulator, it cannot execute CV gates, but the QNode can be constructed
     #print(q.grad_method_for_par)
     self.assertTrue(q.grad_method_for_par == d)
コード例 #15
0
ファイル: test_qnode.py プロジェクト: wuben3125/pennylane
    def test_multiple_expectation_jacobian_positional(self):
        "Tests that qnodes using positional arguments return correct gradients for multiple expectation values."
        self.logTestName()

        a, b, c = 0.5, 0.54, 0.3

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

        circuit = qml.QNode(circuit, self.dev2)

        # compare our manual Jacobian computation to theoretical result
        # Note: circuit.jacobian actually returns a full jacobian in this case
        res = circuit.jacobian(np.array([a, b, c]))
        self.assertAllAlmostEqual(self.expected_jacobian(a, b, c),
                                  res,
                                  delta=self.tol)

        # compare our manual Jacobian computation to autograd
        # not sure if this is the intended usage of jacobian
        jac0 = qml.jacobian(circuit, 0)
        jac1 = qml.jacobian(circuit, 1)
        jac2 = qml.jacobian(circuit, 2)
        res = np.stack([jac0(a, b, c), jac1(a, b, c), jac2(a, b, c)]).T

        self.assertAllAlmostEqual(self.expected_jacobian(a, b, c),
                                  res,
                                  delta=self.tol)
コード例 #16
0
    def test_qfunc_gradients(self):
        "Tests that the various ways of computing the gradient of a qfunc all agree."
        self.logTestName()

        def circuit(x, y, z):
            qml.RX(x, wires=[0])
            qml.CNOT(wires=[0, 1])
            qml.RY(-1.6, wires=[0])
            qml.RY(y, wires=[1])
            qml.CNOT(wires=[1, 0])
            qml.RX(z, wires=[0])
            qml.CNOT(wires=[0, 1])
            return qml.expval.PauliZ(0)

        qnode = qml.QNode(circuit, self.qubit_dev2)
        params = np.array([0.1, -1.6, np.pi / 5])

        # manual gradients
        grad_fd1 = qnode.jacobian(params, method='F', order=1)
        grad_fd2 = qnode.jacobian(params, method='F', order=2)
        grad_angle = qnode.jacobian(params, method='A')

        # automatic gradient
        grad_fn = autograd.grad(qnode.evaluate)
        grad_auto = grad_fn(params)

        # gradients computed with different methods must agree
        self.assertAllAlmostEqual(grad_fd1, grad_fd2, self.tol)
        self.assertAllAlmostEqual(grad_fd1, grad_angle, self.tol)
        self.assertAllAlmostEqual(grad_fd1, grad_auto, self.tol)
コード例 #17
0
ファイル: test_qnode.py プロジェクト: wuben3125/pennylane
    def test_multidim_array(self):
        "Tests that arguments which are multidimensional arrays are properly evaluated and differentiated in QNodes."
        self.logTestName()

        for s in b_shapes:
            multidim_array = np.reshape(b, s)

            def circuit(w):
                qml.RX(w[np.unravel_index(0, s)], 0)  # b[0]
                qml.RX(w[np.unravel_index(1, s)], 1)  # b[1]
                qml.RX(w[np.unravel_index(2, s)], 2)  # ...
                qml.RX(w[np.unravel_index(3, s)], 3)
                qml.RX(w[np.unravel_index(4, s)], 4)
                qml.RX(w[np.unravel_index(5, s)], 5)
                qml.RX(w[np.unravel_index(6, s)], 6)
                qml.RX(w[np.unravel_index(7, s)], 7)
                return tuple(qml.expval.PauliZ(idx) for idx in range(len(b)))

            circuit = qml.QNode(circuit, self.dev8)

            # circuit evaluations
            circuit_output = circuit(multidim_array)
            expected_output = np.cos(b)
            self.assertAllAlmostEqual(circuit_output,
                                      expected_output,
                                      delta=self.tol)

            # circuit jacobians
            circuit_jacobian = circuit.jacobian(multidim_array)
            expected_jacobian = -np.diag(np.sin(b))
            self.assertAllAlmostEqual(circuit_jacobian,
                                      expected_jacobian,
                                      delta=self.tol)
コード例 #18
0
ファイル: test_qnode.py プロジェクト: zeta1999/pennylane
    def test_multiple_expectation_jacobian_positional(self, tol):
        """Tests that qnodes using positional arguments return
        correct gradients for multiple expectation values."""
        a, b, c = 0.5, 0.54, 0.3

        def circuit(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)), qml.expval(qml.PauliY(1))

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

        # compare our manual Jacobian computation to theoretical result
        # Note: circuit.jacobian actually returns a full jacobian in this case
        res = circuit.jacobian(np.array([a, b, c]))
        assert np.allclose(self.expected_jacobian(a, b, c),
                           res,
                           atol=tol,
                           rtol=0)

        # compare our manual Jacobian computation to autograd
        # not sure if this is the intended usage of jacobian
        jac0 = qml.jacobian(circuit, 0)
        jac1 = qml.jacobian(circuit, 1)
        jac2 = qml.jacobian(circuit, 2)
        res = np.stack([jac0(a, b, c), jac1(a, b, c), jac2(a, b, c)]).T

        assert np.allclose(self.expected_jacobian(a, b, c),
                           res,
                           atol=tol,
                           rtol=0)
コード例 #19
0
ファイル: test_qnode.py プロジェクト: zeta1999/pennylane
    def test_differentiate_positional_multidim(self, tol):
        """Tests that all positional arguments are differentiated
        when they are multidimensional."""
        def circuit(a, b):
            qml.RX(a[0], wires=0)
            qml.RX(a[1], wires=1)
            qml.RX(b[2, 1], wires=2)
            return qml.expval(qml.PauliZ(0)), qml.expval(
                qml.PauliZ(1)), qml.expval(qml.PauliZ(2))

        dev = qml.device('default.qubit', wires=3)
        circuit = qml.QNode(circuit, dev)

        a = np.array([-np.sqrt(2), -0.54])
        b = np.array([np.pi / 7] * 6).reshape([3, 2])
        circuit_output = circuit(a, b)
        expected_output = np.cos(np.array([[a[0], a[1], b[-1, 0]]]))
        assert np.allclose(circuit_output, expected_output, atol=tol, rtol=0)

        # circuit jacobians
        circuit_jacobian = circuit.jacobian([a, b])
        expected_jacobian = np.array([
            [-np.sin(a[0])] + [0.] * 7,  # expval 0
            [0., -np.sin(a[1])] + [0.] * 6,  # expval 1
            [0.] * 2 + [0.] * 5 + [-np.sin(b[2, 1])]
        ])  # expval 2
        assert np.allclose(circuit_jacobian,
                           expected_jacobian,
                           atol=tol,
                           rtol=0)
コード例 #20
0
ファイル: test_qnode.py プロジェクト: zeta1999/pennylane
    def test_differentiate_second_third_positional(self, tol):
        """Tests that the second and third positional arguments are differentiated."""
        def circuit4(a, b, c):
            qml.RX(b, wires=0)
            qml.RX(c, wires=1)
            return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))

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

        a = 0.7418
        b = -5.
        c = np.pi / 7
        circuit_output = circuit4(a, b, c)
        expected_output = np.array([[np.cos(b), np.cos(c)]])
        assert np.allclose(circuit_output, expected_output, atol=tol, rtol=0)

        # circuit jacobians
        circuit_jacobian = circuit4.jacobian([a, b, c])
        expected_jacobian = np.array([[0., -np.sin(b), 0.],
                                      [0., 0., -np.sin(c)]])
        assert np.allclose(circuit_jacobian,
                           expected_jacobian,
                           atol=tol,
                           rtol=0)
コード例 #21
0
ファイル: test_qnode.py プロジェクト: ycchen1989/pennylane
    def test_multiple_expectation_jacobian_array(self):
        "Tests that qnodes using an array argument return correct gradients for multiple expectation values."
        self.logTestName()

        a, b, c = 0.5, 0.54, 0.3

        def circuit(weights):
            qml.QubitStateVector(np.array([1, 0, 1, 1]) / np.sqrt(3),
                                 wires=[0, 1])
            qml.Rot(weights[0], weights[1], weights[2], wires=0)
            qml.CNOT(wires=[0, 1])
            return qml.expval.PauliZ(0), qml.expval.PauliY(1)

        circuit = qml.QNode(circuit, self.dev2)

        res = circuit.jacobian([np.array([a, b, c])])
        self.assertAllAlmostEqual(self.expected_jacobian(a, b, c),
                                  res,
                                  delta=self.tol)

        jac = qml.jacobian(circuit, 0)
        res = jac(np.array([a, b, c]))
        self.assertAllAlmostEqual(self.expected_jacobian(a, b, c),
                                  res,
                                  delta=self.tol)
コード例 #22
0
ファイル: test_qnode.py プロジェクト: wuben3125/pennylane
    def test_differentiate_positional_multidim(self):
        "Tests that all positional arguments are differentiated when they are multidimensional."
        self.logTestName()

        def circuit(a, b):
            qml.RX(a[0], 0)
            qml.RX(a[1], 1)
            qml.RX(b[2, 1], 2)
            return qml.expval.PauliZ(0), qml.expval.PauliZ(
                1), qml.expval.PauliZ(2)

        circuit = qml.QNode(circuit, self.dev3)

        a = np.array([-np.sqrt(2), -0.54])
        b = np.array([np.pi / 7] * 6).reshape([3, 2])
        circuit_output = circuit(a, b)
        expected_output = np.cos(np.array([[a[0], a[1], b[-1, 0]]]))
        self.assertAllAlmostEqual(circuit_output,
                                  expected_output,
                                  delta=self.tol)

        # circuit jacobians
        circuit_jacobian = circuit.jacobian([a, b])
        expected_jacobian = np.array([
            [-np.sin(a[0])] + [0.] * 7,  # expval 0
            [0., -np.sin(a[1])] + [0.] * 6,  # expval 1
            [0.] * 2 + [0.] * 5 + [-np.sin(b[2, 1])]
        ])  # expval 2
        self.assertAllAlmostEqual(circuit_jacobian,
                                  expected_jacobian,
                                  delta=self.tol)
コード例 #23
0
ファイル: test_qnode.py プロジェクト: zeta1999/pennylane
    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)
コード例 #24
0
    def test_cv_gradients_gaussian_circuit(self):
        """Tests that the gradients of circuits of gaussian gates match between the finite difference and analytic methods."""
        self.logTestName()

        class PolyN(qml.ops.PolyXP):
            "Mimics NumberOperator using the arbitrary 2nd order observable interface. Results should be identical."
            def __init__(self, wires):
                hbar = 2
                q = np.diag([-0.5, 0.5/hbar, 0.5/hbar])
                super().__init__(q, wires=wires)
                self.name = 'PolyXP'

        gates = []
        for name in qml.ops._cv__ops__:
            cls = getattr(qml.ops, name)

            if cls.supports_analytic:
                gates.append(cls)

        obs   = [qml.ops.X, qml.ops.NumberOperator, PolyN]
        par = [0.4]

        for G in reversed(gates):
            log.debug('Testing gate %s...', G.__name__[0])
            for O in obs:
                log.debug('Testing observable %s...', O.__name__[0])
                def circuit(x):
                    args = [0.3] * G.num_params
                    args[0] = x
                    qml.Displacement(0.5, 0, wires=0)
                    G(*args, wires=range(G.num_wires))
                    qml.Beamsplitter(1.3, -2.3, wires=[0, 1])
                    qml.Displacement(-0.5, 0, wires=0)
                    qml.Squeezing(0.5, -1.5, wires=0)
                    qml.Rotation(-1.1, wires=0)
                    return qml.expval(O(wires=0))

                q = qml.QNode(circuit, self.gaussian_dev)
                val = q.evaluate(par)
                # log.info('  value:', val)
                grad_F  = q.jacobian(par, method='F')
                grad_A2 = q.jacobian(par, method='A', force_order2=True)
                # log.info('  grad_F: ', grad_F)
                # log.info('  grad_A2: ', grad_A2)
                if O.ev_order == 1:
                    grad_A = q.jacobian(par, method='A')
                    # log.info('  grad_A: ', grad_A)
                    # the different methods agree
                    self.assertAllAlmostEqual(grad_A, grad_F, delta=self.tol)

                # analytic method works for every parameter
                self.assertTrue(q.grad_method_for_par == {0:'A'})
                # the different methods agree
                self.assertAllAlmostEqual(grad_A2, grad_F, delta=self.tol)
コード例 #25
0
ファイル: test_qnode.py プロジェクト: wuben3125/pennylane
    def test_keywordargs_used(self):
        "Tests that qnodes use keyword arguments."
        self.logTestName()

        def circuit(w, x=None):
            qml.RX(x, [0])
            return qml.expval.PauliZ(0)

        circuit = qml.QNode(circuit, self.dev1)

        c = circuit(1., x=np.pi)
        self.assertAlmostEqual(c, -1., delta=self.tol)
コード例 #26
0
ファイル: test_torch.py プロジェクト: zeta1999/pennylane
    def test_keywordargs_used(self):
        "Tests that qnodes use keyword arguments."
        self.logTestName()

        def circuit(w, x=None):
            qml.RX(x, wires=[0])
            return qml.expval(qml.PauliZ(0))

        circuit = qml.QNode(circuit, self.dev1).to_torch()

        c = circuit(torch.tensor(1.), x=np.pi)
        self.assertAlmostEqual(c.numpy(), -1., delta=self.tol)
コード例 #27
0
ファイル: test_qnode.py プロジェクト: ycchen1989/pennylane
    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)
コード例 #28
0
    def test_multiple_keywordargs_used(self):
        "Tests that qnodes use multiple keyword arguments."
        self.logTestName()

        def circuit(w, x=None, y=None):
            qml.RX(x, wires=[0])
            qml.RX(y, wires=[1])
            return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))

        circuit = qml.QNode(circuit, self.dev2).to_tfe()

        c = circuit(tf.constant(1.), x=np.pi, y=np.pi)
        self.assertAllAlmostEqual(c.numpy(), [-1., -1.], delta=self.tol)
コード例 #29
0
ファイル: test_qnode.py プロジェクト: wuben3125/pennylane
    def test_multidimensional_keywordargs_used(self):
        "Tests that qnodes use multi-dimensional keyword arguments."
        self.logTestName()

        def circuit(w, x=None):
            qml.RX(x[0], [0])
            qml.RX(x[1], [1])
            return qml.expval.PauliZ(0), qml.expval.PauliZ(1)

        circuit = qml.QNode(circuit, self.dev2)

        c = circuit(1., x=[np.pi, np.pi])
        self.assertAllAlmostEqual(c, [-1., -1.], delta=self.tol)
コード例 #30
0
ファイル: test_torch.py プロジェクト: zeta1999/pennylane
    def test_multidimensional_keywordargs_used(self):
        "Tests that qnodes use multi-dimensional keyword arguments."
        self.logTestName()

        def circuit(w, x=None):
            qml.RX(x[0], wires=[0])
            qml.RX(x[1], wires=[1])
            return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))

        circuit = qml.QNode(circuit, self.dev2).to_torch()

        c = circuit(torch.tensor(1.), x=[np.pi, np.pi])
        self.assertAllAlmostEqual(c.numpy(), [-1., -1.], delta=self.tol)