docstr: Test step_and_cost() function with the multi-input qnode.
docstr_tok: ["Test","step_and_cost","(",")","function","with","the","multi-input","qnode","."]
code: def test_step_and_cost_from_multi_input(self, finite_diff_step, seed):
      """Test step_and_cost() function with the multi-input qnode."""
      regularization = 1e-3
      stepsize = 1e-2
      opt = qml.QNSPSAOptimizer(
          stepsize=stepsize,
          regularization=regularization,
          finite_diff_step=finite_diff_step,
          resamplings=1,
          blocking=True,
          history_length=5,
          seed=seed,
      )
      # target opt is used to reproduce the random sampling result
      target_opt = deepcopy(opt)
  
      qnode = get_multi_input_qnode()
      params = [np.array(1.0) for _ in range(2)]
      # this single-step result will be different from the one from the single-input qnode, due to the
      # different order in sampling perturbation directions.
      new_params_res, qnode_res = opt.step_and_cost(qnode, *params)
  
      # test the expectation value
      qnode_expected = np.cos(params[0] / 2) ** 2 - np.sin(
          params[0] / 2
      ) ** 2 * np.cos(params[1])
      assert np.allclose(qnode_res, qnode_expected)
  
      # test the next-step parameter
      _, grad_dirs = target_opt._get_spsa_grad_tapes(qnode, params, {})
      _, tensor_dirs = target_opt._get_tensor_tapes(qnode, params, {})
      qnode_finite_diff = get_grad_finite_diff(
          params, finite_diff_step, grad_dirs
      )
      grad_expected = [
          qnode_finite_diff / (2 * finite_diff_step) * grad_dir
          for grad_dir in grad_dirs
      ]
      # reshape the params list into a tensor to reuse the
      # get_metric_from_single_input_qnode helper function
      params_tensor = np.array(params).reshape(1, len(params))
      metric_tensor_expected = get_metric_from_single_input_qnode(
          params_tensor, finite_diff_step, tensor_dirs
      )
  
      # regularize raw metric tensor
      identity = np.identity(metric_tensor_expected.shape[0])
      avg_metric_tensor = 0.5 * (identity + metric_tensor_expected)
      tensor_reg = np.real(
          sqrtm(np.matmul(avg_metric_tensor, avg_metric_tensor))
      )
      tensor_reg = (tensor_reg + regularization * identity) / (
          1 + regularization
      )
  
      inv_metric_tensor = np.linalg.inv(tensor_reg)
      grad_tensor = np.array(grad_expected).reshape(
          inv_metric_tensor.shape[0],
      )
      new_params_tensor_expected = params_tensor - stepsize * np.matmul(
          inv_metric_tensor, grad_tensor
      )
  
      assert np.allclose(
          np.array(new_params_res).reshape(
              new_params_tensor_expected.shape
          ),
          new_params_tensor_expected,
      )
  
file_path: pennylane/tests/optimize/test_qnspsa.py
imports: from copy import deepcopy
  import pytest
  from scipy.linalg import sqrtm
  import pennylane
  from pennylane import numpy
label_desc: Use image node_id 6 for calling the TestQNSPSAOptimizer obj's underlying member method code with example usage: obj.test_step_and_cost_from_multi_input(finite_diff_step, seed) without return types