예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
    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)
예제 #4
0
    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)
예제 #5
0
    def test_integration(self):
        """test integration with PennyLane and gradient calculations"""
        N = 4
        wires = range(N)
        dev = qml.device('default.gaussian', wires=N)

        sq = np.array([[0.8734294, 0.96854066], [0.86919454, 0.53085569],
                       [0.23272833, 0.0113988], [0.43046882, 0.40235136]])

        theta = np.array([
            3.28406182, 3.0058243, 3.48940764, 3.41419504, 4.7808479,
            4.47598146
        ])
        phi = np.array([
            3.89357744, 2.67721355, 1.81631197, 6.11891294, 2.09716418,
            1.37476761
        ])
        varphi = np.array([0.4134863, 6.17555778, 0.80334114, 2.02400747])

        @qml.qnode(dev)
        def circuit(theta, phi, varphi):
            for w in wires:
                qml.Squeezing(sq[w][0], sq[w][1], wires=w)

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

        res = circuit(theta, phi, varphi)
        expected = np.array([0.96852694, 0.23878521, 0.82310606, 0.16547786])
        self.assertAllAlmostEqual(res, expected, delta=self.tol)

        res = qml.jacobian(circuit, 0)(theta, phi, varphi)
        expected = np.array([[
            -6.18547621e-03, -3.20488416e-04, -4.20274088e-02, -6.21819677e-02,
            0.00000000e+00, 0.00000000e+00
        ],
                             [
                                 3.55439469e-04, 3.89820231e-02,
                                 -3.35281297e-03, 7.93009278e-04,
                                 8.30347900e-02, -3.45150712e-01
                             ],
                             [
                                 5.44893709e-03, 9.30878023e-03,
                                 -5.33374090e-01, 6.13889584e-02,
                                 -1.16931386e-01, 3.45150712e-01
                             ],
                             [
                                 3.81099656e-04, -4.79703149e-02,
                                 5.78754312e-01, 0.00000000e+00,
                                 3.38965962e-02, 0.00000000e+00
                             ]])
        self.assertAllAlmostEqual(res, expected, delta=self.tol)