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)
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)
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)
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)
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)