def test_scalar_jacobian(self, execute_kwargs, tol): """Test scalar jacobian calculation""" a = tf.Variable(0.1, dtype=tf.float64) dev = qml.device("default.qubit", wires=2) with tf.GradientTape() as t: with qml.tape.JacobianTape() as tape: qml.RY(a, wires=0) qml.expval(qml.PauliZ(0)) res = execute([tape], dev, **execute_kwargs)[0] res = t.jacobian(res, a) assert res.shape == (1, ) # compare to standard tape jacobian with qml.tape.JacobianTape() as tape: qml.RY(a, wires=0) qml.expval(qml.PauliZ(0)) tape.trainable_params = {0} tapes, fn = param_shift(tape) expected = fn(dev.batch_execute(tapes)) assert expected.shape == (1, 1) assert np.allclose(res, np.squeeze(expected), atol=tol, rtol=0)
def test_scalar_jacobian(self, execute_kwargs, tol): """Test scalar jacobian calculation""" a = np.array(0.1, requires_grad=True) dev = qml.device("default.qubit", wires=2) def cost(a): with qml.tape.JacobianTape() as tape: qml.RY(a, wires=0) qml.expval(qml.PauliZ(0)) return execute([tape], dev, **execute_kwargs)[0] res = qml.jacobian(cost)(a) assert res.shape == (1, ) # compare to standard tape jacobian with qml.tape.JacobianTape() as tape: qml.RY(a, wires=0) qml.expval(qml.PauliZ(0)) tape.trainable_params = {0} tapes, fn = param_shift(tape) expected = fn(dev.batch_execute(tapes)) assert expected.shape == (1, 1) assert np.allclose(res, np.squeeze(expected), atol=tol, rtol=0)
def cost_fn(params): with qml.tape.JacobianTape() as tape: qml.RX(params[0], wires=[0]) RY(params[1], wires=[1]) qml.CNOT(wires=[0, 1]) qml.expval(qml.PauliZ(0)) qml.var(qml.PauliX(1)) tapes, fn = param_shift(tape, fallback_fn=qml.gradients.finite_diff) assert len(tapes) == 5 # check that the fallback method was called for the specified argnums spy.assert_called() assert spy.call_args[1]["argnum"] == {1} return fn(dev.batch_execute(tapes))
def test_all_fallback(self, mocker, tol): """Test that *only* the fallback logic is called if no parameters support the parameter-shift rule""" spy_fd = mocker.spy(qml.gradients, "finite_diff") spy_ps = mocker.spy(qml.gradients.parameter_shift, "expval_param_shift") dev = qml.device("default.qubit.autograd", wires=2) x = 0.543 y = -0.654 params = np.array([x, y], requires_grad=True) class RY(qml.RY): grad_method = "F" class RX(qml.RX): grad_method = "F" with qml.tape.JacobianTape() as tape: RX(x, wires=[0]) RY(y, wires=[1]) qml.CNOT(wires=[0, 1]) qml.expval(qml.PauliZ(0) @ qml.PauliX(1)) tapes, fn = param_shift(tape, fallback_fn=qml.gradients.finite_diff) assert len(tapes) == 1 + 2 # check that the fallback method was called for all argnums spy_fd.assert_called() spy_ps.assert_not_called() res = fn(dev.batch_execute(tapes)) assert res.shape == (1, 2) expected = np.array([[-np.sin(y) * np.sin(x), np.cos(y) * np.cos(x)]]) assert np.allclose(res, expected, atol=tol, rtol=0)