Python autograd.jacobian() Examples
The following are 23
code examples of autograd.jacobian().
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
You may also want to check out all available functions/classes of the module
autograd
, or try the search function
.
Example #1
Source File: __init__.py From pennylane with Apache License 2.0 | 7 votes |
def jacobian(func, argnum): """Returns the Jacobian as a callable function of vector-valued (functions of) QNodes. This is a wrapper around the :mod:`autograd.jacobian` function. Args: func (function): a vector-valued Python function or QNode that contains a combination of quantum and classical nodes. The output of the computation must consist of a single NumPy array (if classical) or a tuple of expectation values (if a quantum node) argnum (int or Sequence[int]): which argument to take the gradient with respect to. If a sequence is given, the Jacobian matrix corresponding to all input elements and all output elements is returned. Returns: function: the function that returns the Jacobian of the input function with respect to the arguments in argnum """ # pylint: disable=no-value-for-parameter if isinstance(argnum, int): return _jacobian(func, argnum) return lambda *args, **kwargs: _np.stack( [_jacobian(func, arg)(*args, **kwargs) for arg in argnum] ).T
Example #2
Source File: test_autograd.py From pennylane with Apache License 2.0 | 6 votes |
def test_multiple_expectation_jacobian_array(self, tol, qubit_device_2_wires): """Tests that qnodes using an array argument return correct gradients for multiple expectation values.""" par = np.array([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)) circuit = to_autograd(QubitQNode(circuit, qubit_device_2_wires)) expected_jac = self.expected_jacobian(*par) res = circuit.jacobian([par]) assert expected_jac == pytest.approx(res, abs=tol) jac = autograd.jacobian(circuit, 0) res = jac(par) assert expected_jac == pytest.approx(res, abs=tol)
Example #3
Source File: test_quantum_gradients.py From pennylane with Apache License 2.0 | 6 votes |
def test_cv_gradient_fanout(self, gaussian_dev, tol): "Tests that qnodes can compute the correct gradient when the same parameter is used in multiple gates." par = [0.5, 1.3] def circuit(x, y): qml.Displacement(x, 0, wires=[0]) qml.Rotation(y, wires=[0]) qml.Displacement(0, x, wires=[0]) return qml.expval(qml.X(0)) q = qml.QNode(circuit, gaussian_dev) grad_F = q.jacobian(par, method='F') grad_A = q.jacobian(par, method='A') grad_A2 = q.jacobian(par, method='A', options={"force_order2": True}) # analytic method works for every parameter assert q.par_to_grad_method == {0:'A', 1:'A'} # the different methods agree assert grad_A == pytest.approx(grad_F, abs=tol) assert grad_A2 == pytest.approx(grad_F, abs=tol)
Example #4
Source File: test_quantum_gradients.py From pennylane with Apache License 2.0 | 6 votes |
def test_cv_gradients_repeated_gate_parameters(self, gaussian_dev, tol): "Tests that repeated use of a free parameter in a multi-parameter gate yield correct gradients." par = [0.2, 0.3] def qf(x, y): qml.Displacement(x, 0, wires=[0]) qml.Squeezing(y, -1.3*y, wires=[0]) return qml.expval(qml.X(0)) q = qml.QNode(qf, gaussian_dev) grad_F = q.jacobian(par, method='F') grad_A = q.jacobian(par, method='A') grad_A2 = q.jacobian(par, method='A', options={"force_order2": True}) # analytic method works for every parameter assert q.par_to_grad_method == {0:'A', 1:'A'} # the different methods agree assert grad_A == pytest.approx(grad_F, abs=tol) assert grad_A2 == pytest.approx(grad_F, abs=tol)
Example #5
Source File: test_quantum_gradients.py From pennylane with Apache License 2.0 | 6 votes |
def test_cv_gradients_parameters_inside_array(self, gaussian_dev, tol): "Tests that free parameters inside an array passed to an Operation yield correct gradients." par = [0.4, 1.3] def qf(x, y): qml.Displacement(0.5, 0, wires=[0]) qml.Squeezing(x, 0, wires=[0]) M = np.zeros((5, 5), dtype=object) M[1,1] = y M[1,2] = 1.0 M[2,1] = 1.0 return qml.expval(qml.PolyXP(M, [0, 1])) q = qml.QNode(qf, gaussian_dev) grad = q.jacobian(par) grad_F = q.jacobian(par, method='F') grad_A = q.jacobian(par, method="best") grad_A2 = q.jacobian(par, method="best", options={"force_order2": True}) # par[0] can use the 'A' method, par[1] cannot assert q.par_to_grad_method == {0:'A', 1:'F'} # the different methods agree assert grad == pytest.approx(grad_F, abs=tol)
Example #6
Source File: test_quantum_gradients.py From pennylane with Apache License 2.0 | 5 votes |
def test_cv_gradients_gaussian_circuit(self, G, O, gaussian_dev, tol): """Tests that the gradients of circuits of gaussian gates match between the finite difference and analytic methods.""" tol = 1e-5 par = [0.4] 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.1, 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, gaussian_dev) val = q.evaluate(par, {}) grad_F = q.jacobian(par, method='F') grad_A2 = q.jacobian(par, method='A', options={"force_order2": True}) if O.ev_order == 1: grad_A = q.jacobian(par, method='A') # the different methods agree assert grad_A == pytest.approx(grad_F, abs=tol) # analytic method works for every parameter assert q.par_to_grad_method == {0:'A'} # the different methods agree assert grad_A2 == pytest.approx(grad_F, abs=tol)
Example #7
Source File: test_jacobian.py From autograd with MIT License | 5 votes |
def test_jacobian_higher_order(): fun = lambda x: np.sin(np.outer(x,x)) + np.cos(np.dot(x,x)) assert jacobian(fun)(npr.randn(2)).shape == (2,2,2) assert jacobian(jacobian(fun))(npr.randn(2)).shape == (2,2,2,2) # assert jacobian(jacobian(jacobian(fun)))(npr.randn(2)).shape == (2,2,2,2,2) check_grads(lambda x: np.sum(np.sin(jacobian(fun)(x))))(npr.randn(2)) check_grads(lambda x: np.sum(np.sin(jacobian(jacobian(fun))(x))))(npr.randn(2))
Example #8
Source File: test_jacobian.py From autograd with MIT License | 5 votes |
def test_jacobian_against_stacked_grads(): scalar_funs = [ lambda x: np.sum(x**3), lambda x: np.prod(np.sin(x) + np.sin(x)), lambda x: grad(lambda y: np.exp(y) * np.tanh(x[0]))(x[1]) ] vector_fun = lambda x: np.array([f(x) for f in scalar_funs]) x = npr.randn(5) jac = jacobian(vector_fun)(x) grads = [grad(f)(x) for f in scalar_funs] assert np.allclose(jac, np.vstack(grads))
Example #9
Source File: test_jacobian.py From autograd with MIT License | 5 votes |
def test_jacobian_scalar_to_vector(): fun = lambda x: np.array([x, x**2, x**3]) val = npr.randn() assert np.allclose(jacobian(fun)(val), np.array([1., 2*val, 3*val**2]))
Example #10
Source File: test_jacobian.py From autograd with MIT License | 5 votes |
def test_jacobian_against_grad(): fun = lambda x: np.sum(np.sin(x), axis=1, keepdims=True) A = npr.randn(1,3) assert np.allclose(grad(fun)(A), jacobian(fun)(A))
Example #11
Source File: test_quantum_gradients.py From pennylane with Apache License 2.0 | 5 votes |
def test_gradient_exception_on_sample(self, qubit_device_2_wires): """Tests that the proper exception is raised if differentiation of sampling is attempted.""" @qml.qnode(qubit_device_2_wires) def circuit(x): qml.RX(x, wires=[0]) return qml.sample(qml.PauliZ(0)), qml.sample(qml.PauliX(1)) with pytest.raises(qml.QuantumFunctionError, match="Circuits that include sampling can not be differentiated."): grad_fn = autograd.jacobian(circuit) grad_fn(1.0)
Example #12
Source File: test_quantum_gradients.py From pennylane with Apache License 2.0 | 5 votes |
def test_hybrid_gradients_autograd_numpy(self, qubit_device_2_wires, tol): "Test the gradient of a hybrid computation requiring autograd.numpy functions." def circuit(x, y): "Quantum node." qml.RX(x, wires=[0]) qml.CNOT(wires=[0, 1]) qml.RY(y, wires=[0]) qml.CNOT(wires=[0, 1]) return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1)) quantum = qml.QNode(circuit, qubit_device_2_wires) def classical(p): "Classical node, requires autograd.numpy functions." return anp.exp(anp.sum(quantum(p[0], anp.log(p[1])))) def d_classical(a, b, method): "Gradient of classical computed symbolically, can use normal numpy functions." val = classical((a, b)) J = quantum.jacobian((a, np.log(b)), method=method) return val * np.array([J[0, 0] + J[1, 0], (J[0, 1] + J[1, 1]) / b]) param = np.array([-0.1259, 1.53]) y0 = classical(param) grad_classical = autograd.jacobian(classical) grad_auto = grad_classical(param) grad_fd1 = d_classical(*param, 'F') grad_angle = d_classical(*param, 'A') # gradients computed with different methods must agree assert grad_fd1 == pytest.approx(grad_angle, abs=tol) assert grad_fd1 == pytest.approx(grad_auto, abs=tol) assert grad_angle == pytest.approx(grad_auto, abs=tol)
Example #13
Source File: test_quantum_gradients.py From pennylane with Apache License 2.0 | 5 votes |
def test_qfunc_gradients(self, qubit_device_2_wires, tol): "Tests that the various ways of computing the gradient of a qfunc all agree." 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(qml.PauliZ(0)) qnode = qml.QNode(circuit, qubit_device_2_wires) params = np.array([0.1, -1.6, np.pi / 5]) # manual gradients grad_fd1 = qnode.jacobian(params, method='F', options={"order": 1}) grad_fd2 = qnode.jacobian(params, method='F', options={"order": 2}) grad_angle = qnode.jacobian(params, method='A') # automatic gradient # Note: the lambda function is required as evaluate now receives a required `kwargs` argument # that cannot be differentiated by autograd. grad_fn = autograd.grad(lambda x: qnode.evaluate(x, {})) grad_auto = grad_fn(params)[np.newaxis, :] # so shapes will match # gradients computed with different methods must agree assert grad_fd1 == pytest.approx(grad_fd2, abs=tol) assert grad_fd1 == pytest.approx(grad_angle, abs=tol) assert grad_fd1 == pytest.approx(grad_auto, abs=tol)
Example #14
Source File: test_quantum_gradients.py From pennylane with Apache License 2.0 | 5 votes |
def test_CVOperation_with_heisenberg_and_no_params(self, name, gaussian_dev, tol): """An integration test for CV gates that support analytic differentiation if succeeding the gate to be differentiated, but cannot be differentiated themselves (for example, they may be Gaussian but accept no parameters). This ensures that, assuming their _heisenberg_rep is defined, the quantum gradient analytic method can still be used, and returns the correct result. """ cls = getattr(qml.ops, name) if cls.supports_heisenberg and (not cls.supports_parameter_shift): U = np.array([[0.51310276+0.81702166j, 0.13649626+0.22487759j], [0.26300233+0.00556194j, -0.96414101-0.03508489j]]) if cls.num_wires <= 0: w = list(range(2)) else: w = list(range(cls.num_wires)) def circuit(x): qml.Displacement(x, 0, wires=0) if cls.par_domain == 'A': cls(U, wires=w) else: cls(wires=w) return qml.expval(qml.X(0)) qnode = qml.QNode(circuit, gaussian_dev) grad_F = qnode.jacobian(0.5, method='F') grad_A = qnode.jacobian(0.5, method='A') grad_A2 = qnode.jacobian(0.5, method='A', options={"force_order2": True}) # par[0] can use the 'A' method assert qnode.par_to_grad_method == {0: 'A'} # the different methods agree assert grad_A == pytest.approx(grad_F, abs=tol) assert grad_A2 == pytest.approx(grad_F, abs=tol)
Example #15
Source File: likelihood.py From momi2 with GNU General Public License v3.0 | 5 votes |
def _score_cov(self, params): params = np.array(params) def f_vec(x): ret = self._log_lik(x, vector=True) # centralize return ret - np.mean(ret) j = ag.jacobian(f_vec)(params) return np.einsum('ij, ik', j, j)
Example #16
Source File: test_autograd.py From pennylane with Apache License 2.0 | 5 votes |
def test_hybrid_gradients_autograd_numpy(self, qubit_device_2_wires, tol): "Test the gradient of a hybrid computation requiring autograd.numpy functions." def circuit(x, y): "Quantum node." qml.RX(x, wires=[0]) qml.CNOT(wires=[0, 1]) qml.RY(y, wires=[0]) qml.CNOT(wires=[0, 1]) return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1)) quantum = to_autograd(QubitQNode(circuit, qubit_device_2_wires)) def classical(p): "Classical node, requires autograd.numpy functions." return anp.exp(anp.sum(quantum(p[0], anp.log(p[1])))) def d_classical(a, b, method): "Gradient of classical computed symbolically, can use normal numpy functions." val = classical((a, b)) J = quantum.jacobian((a, np.log(b)), method=method) return val * np.array([J[0, 0] + J[1, 0], (J[0, 1] + J[1, 1]) / b]) param = np.array([-0.1259, 1.53]) y0 = classical(param) grad_classical = autograd.jacobian(classical) grad_auto = grad_classical(param) grad_fd1 = d_classical(*param, 'F') grad_angle = d_classical(*param, 'A') # gradients computed with different methods must agree assert grad_fd1 == pytest.approx(grad_angle, abs=tol) assert grad_fd1 == pytest.approx(grad_auto, abs=tol) assert grad_angle == pytest.approx(grad_auto, abs=tol)
Example #17
Source File: test_autograd.py From pennylane with Apache License 2.0 | 5 votes |
def test_qfunc_gradients(self, qubit_device_2_wires, tol): "Tests that the various ways of computing the gradient of a qfunc all agree." 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(qml.PauliZ(0)) qnode = to_autograd(QubitQNode(circuit, qubit_device_2_wires)) params = np.array([0.1, -1.6, np.pi / 5]) # manual gradients grad_fd1 = qnode.jacobian(params, method='F', options={'order': 1}) grad_fd2 = qnode.jacobian(params, method='F', options={'order': 2}) grad_angle = qnode.jacobian(params, method='A') # automatic gradient grad_fn = autograd.grad(qnode, argnum=[0, 1, 2]) grad_auto = np.array([grad_fn(*params)]) # gradients computed with different methods must agree assert grad_fd1 == pytest.approx(grad_fd2, abs=tol) assert grad_fd1 == pytest.approx(grad_angle, abs=tol) assert grad_fd1 == pytest.approx(grad_auto, abs=tol)
Example #18
Source File: test_autograd.py From pennylane with Apache License 2.0 | 5 votes |
def test_multiple_expectation_jacobian_positional(self, tol, qubit_device_2_wires): """Tests that qnodes using positional arguments return correct gradients for multiple expectation values.""" par = [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)) circuit = to_autograd(QubitQNode(circuit, qubit_device_2_wires)) # compare our manual Jacobian computation to theoretical result expected_jac = self.expected_jacobian(*par) res = circuit.jacobian(par) assert expected_jac == pytest.approx(res, abs=tol) # compare our manual Jacobian computation to autograd # not sure if this is the intended usage of jacobian jac0 = autograd.jacobian(circuit, 0) jac1 = autograd.jacobian(circuit, 1) jac2 = autograd.jacobian(circuit, 2) res = np.stack([jac0(*par), jac1(*par), jac2(*par)]).T assert expected_jac == pytest.approx(res, abs=tol) #compare with what we get if argnum is a list jac = autograd.jacobian(circuit, argnum=[0, 1, 2]) #res2 = jac(*par) # FIXME this call gives a TypeError inside Autograd #assert res == pytest.approx(res2, abs=tol)
Example #19
Source File: ddp_gym.py From ddp-gym with BSD 3-Clause "New" or "Revised" License | 5 votes |
def __init__(self, next_state, running_cost, final_cost, umax, state_dim, pred_time=50): self.pred_time = pred_time self.umax = umax self.v = [0.0 for _ in range(pred_time + 1)] self.v_x = [np.zeros(state_dim) for _ in range(pred_time + 1)] self.v_xx = [np.zeros((state_dim, state_dim)) for _ in range(pred_time + 1)] self.f = next_state self.lf = final_cost self.lf_x = grad(self.lf) self.lf_xx = jacobian(self.lf_x) self.l_x = grad(running_cost, 0) self.l_u = grad(running_cost, 1) self.l_xx = jacobian(self.l_x, 0) self.l_uu = jacobian(self.l_u, 1) self.l_ux = jacobian(self.l_u, 0) self.f_x = jacobian(self.f, 0) self.f_u = jacobian(self.f, 1) self.f_xx = jacobian(self.f_x, 0) self.f_uu = jacobian(self.f_u, 1) self.f_ux = jacobian(self.f_u, 0)
Example #20
Source File: test_autograd.py From pennylane with Apache License 2.0 | 4 votes |
def test_differentiable_parameter_last(self): """Test that a differentiable parameter used as the last argument is correctly evaluated by QNode.jacobian, and that all other non-differentiable parameters are ignored""" dev = qml.device("default.qubit", wires=2) @qml.qnode(dev, interface="autograd") def circuit(data1, data2, weights): # non-differentiable quantum function qml.templates.AmplitudeEmbedding(data1, wires=[0, 1]) # differentiable quantum function qml.templates.StronglyEntanglingLayers(weights, wires=[0, 1]) # non-differentiable quantum function qml.templates.AngleEmbedding(data2, wires=[0, 1]) return qml.expval(qml.PauliZ(0)) # differentiating the circuit wrt the weights grad_fn = qml.grad(circuit) # input weights weights = qml.init.strong_ent_layers_normal(n_wires=2, n_layers=3) # input data data1 = qml.numpy.array([0, 1, 1, 0], requires_grad=False) / np.sqrt(2) data2 = qml.numpy.array([1, 1], requires_grad=False) res = grad_fn(data1, data2, weights) # we do not check for correctness, just that the output # is the correct shape assert len(res) == 1 assert res[0].shape == weights.shape # check that the last arg was marked as non-differentiable assert circuit.get_trainable_args() == {2} # Check that the parameter shift was not performed for the # non-differentiable elements of `data1` and `data2`. # First, extract the variable indices that the jacobian method # 'skipped' (those with grad_method="0"): non_diff_var_indices = sorted([k for k, v in circuit.par_to_grad_method.items() if v == "0"]) # Check that these indices corresponds to the elements of data1 and data2 # within the flattenened list [data1, data2, weights] assert non_diff_var_indices == [0, 1, 2, 3, 4, 5]
Example #21
Source File: test_autograd.py From pennylane with Apache License 2.0 | 4 votes |
def test_differentiable_parameter_middle(self): """Test that a differentiable parameter provided as the middle argument is correctly evaluated by QNode.jacobian, and that all other non-differentiable parameters are ignored""" dev = qml.device("default.qubit", wires=2) @qml.qnode(dev, interface="autograd") def circuit(data1, weights, data2): # non-differentiable quantum function qml.templates.AmplitudeEmbedding(data1, wires=[0, 1]) # differentiable quantum function qml.templates.StronglyEntanglingLayers(weights, wires=[0, 1]) # non-differentiable quantum function qml.templates.AngleEmbedding(data2, wires=[0, 1]) return qml.expval(qml.PauliZ(0)) # differentiating the circuit wrt the weights grad_fn = qml.grad(circuit) # input weights weights = qml.init.strong_ent_layers_normal(n_wires=2, n_layers=3) # input data data1 = qml.numpy.array([0, 1, 1, 0], requires_grad=False) / np.sqrt(2) data2 = qml.numpy.array([1, 1], requires_grad=False) res = grad_fn(data1, weights, data2) # we do not check for correctness, just that the output # is the correct shape assert len(res) == 1 assert res[0].shape == weights.shape # check that the second arg was marked as non-differentiable assert circuit.get_trainable_args() == {1} # Check that the gradient was not computed for the # non-differentiable elements of `data1` and `data2`. # First, extract the variable indices that the jacobian method # 'skipped' (those with grad_method="0"): non_diff_var_indices = sorted([k for k, v in circuit.par_to_grad_method.items() if v == "0"]) # Check that these indices corresponds to the elements of data1 and data2 # within the flattenened list [data1, weights, data2] assert non_diff_var_indices == [0, 1, 2, 3, 22, 23]
Example #22
Source File: test_autograd.py From pennylane with Apache License 2.0 | 4 votes |
def test_differentiable_parameter_first(self): """Test that a differentiable parameter used as the first argument is correctly evaluated by QNode.jacobian, and that all other non-differentiable parameters are ignored""" dev = qml.device("default.qubit", wires=2) @qml.qnode(dev, interface="autograd") def circuit(weights, data1, data2): # non-differentiable quantum function qml.templates.AmplitudeEmbedding(data1, wires=[0, 1]) # differentiable quantum function qml.templates.StronglyEntanglingLayers(weights, wires=[0, 1]) # non-differentiable quantum function qml.templates.AngleEmbedding(data2, wires=[0, 1]) return qml.expval(qml.PauliZ(0)) # differentiating the circuit wrt the weights grad_fn = qml.grad(circuit) # input weights weights = qml.init.strong_ent_layers_normal(n_wires=2, n_layers=3) # input data data1 = qml.numpy.array([0, 1, 1, 0], requires_grad=False) / np.sqrt(2) data2 = qml.numpy.array([1, 1], requires_grad=False) res = grad_fn(weights, data1, data2) # we do not check for correctness, just that the output # is the correct shape assert len(res) == 1 assert res[0].shape == weights.shape # check that the first arg was marked as non-differentiable assert circuit.get_trainable_args() == {0} # Check that the gradient was not computed for the # non-differentiable elements of `data1` and `data2`. # First, extract the variable indices that the jacobian method # 'skipped' (those with grad_method="0"): non_diff_var_indices = sorted([k for k, v in circuit.par_to_grad_method.items() if v == "0"]) # Check that these indices corresponds to the elements of data1 and data2 # within the flattenened list [weights, data1, data2] assert non_diff_var_indices == [18, 19, 20, 21, 22, 23]
Example #23
Source File: test_autograd.py From pennylane with Apache License 2.0 | 4 votes |
def test_array_parameters_autograd(self, tol, qubit_device_2_wires): """Test that gradients of array parameters give same results as positional arguments.""" par = [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) circuit1 = to_autograd(QubitQNode(circuit1, qubit_device_2_wires)) grad1 = autograd.grad(circuit1, argnum=[0, 1, 2]) # three positional parameters jac = circuit1.jacobian(par) ag = grad1(*par) ag = np.array([ag]) assert jac == pytest.approx(ag, abs=tol) circuit2 = to_autograd(QubitQNode(circuit2, qubit_device_2_wires)) grad2 = autograd.grad(circuit2, argnum=[0, 1]) # one scalar, one array temp = [par[0], np.array(par[1:])] jac = circuit2.jacobian(temp) ag = grad2(*temp) ag = np.r_[ag][np.newaxis, :] assert jac == pytest.approx(ag, abs=tol) circuit3 = to_autograd(QubitQNode(circuit3, qubit_device_2_wires)) grad3 = autograd.grad(circuit3, argnum=0) # one array temp = [np.array(par)] jac = circuit3.jacobian(temp) ag = grad3(*temp)[np.newaxis, :] assert jac == pytest.approx(ag, abs=tol)