class_docstr: Quantum natural SPSA (QNSPSA) optimizer. QNSPSA is a second-order SPSA algorithm, which
  updates the ansatz parameters with the following equation:
  
  .. math::
  
      \mathbf{x}^{(t + 1)} = \mathbf{x}^{(t)} -
      \eta \widehat{\mathbf{g}}^{-1}(\mathbf{x}^{(t)})\widehat{\nabla f}(\mathbf{x}^{(t)}),
  
  where :math:`f(\mathbf{x})` is the objective function with input parameters :math:`\mathbf{x}`,
  while :math:`\nabla f` is the gradient, :math:`\mathbf{g}` is the second-order Fubini-Study metric
  tensor. With QNSPSA algorithm, both the gradient and the metric tensor are estimated
  stochastically, with :math:`\widehat{\nabla f}` and :math:`\widehat{\mathbf{g}}`. This stochastic
  approach requires only a fixed number of circuit executions per optimization step,
  independent of the problem size. This preferred scaling makes
  it a promising candidate for the optimization tasks for high-dimensional ansatzes. On the
  other hand, the introduction of the Fubini-Study metric into the optimization helps to find
  better minima and allows for faster convergence.
  
  The gradient is estimated similarly as the `SPSA optimizer
  <https://pennylane.readthedocs.io/en/stable/code/api/pennylane.SPSAOptimizer.html>`_, with a
  pair of perturbations:
  
  .. math::
  
      \widehat{\nabla f}(\mathbf{x}) = \widehat{\nabla f}(\mathbf{x}, \mathbf{h})
      \approx \frac{1}{2\epsilon}\big(f(\mathbf{x} + \epsilon \mathbf{h}) - f(\mathbf{x} - \epsilon \mathbf{h})\big),
  
  where :math:`\epsilon` is the finite-difference step size specified by the user, and
  :math:`\mathbf{h}` is a randomly sampled direction vector to perform the perturbation.
  
  The Fubini-Study metric tensor is estimated with another two pairs of perturbations along
  randomly sampled directions :math:`\mathbf{h_1}` and :math:`\mathbf{h_2}`:
  
  .. math::
  
      \widehat{\mathbf{g}}(\mathbf{x}) = \widehat{\mathbf{g}}(\mathbf{x}, \mathbf{h}_1, \mathbf{h}_2)
      \approx \frac{\delta F}{8 \epsilon^2}\Big(\mathbf{h}_1 \mathbf{h}_2^\intercal + \mathbf{h}_2 \mathbf{h}_1^\intercal\Big),
  
  where :math:`F(\mathbf{x}', \mathbf{x}) = \bigr\rvert\langle \phi(\mathbf{x}') | \phi(\mathbf{x}) \rangle \bigr\rvert ^ 2`
  measures the state overlap between :math:`\phi(\mathbf{x}')` and :math:`\phi(\mathbf{x})`,
  where :math:`\phi` is the parameterized ansatz. The finite difference :math:`\delta F` is
  computed from the two perturbations:
  
  .. math::
  
      \delta F = F(\mathbf{x, \mathbf{x} + \epsilon \mathbf{h}_1} + \epsilon \mathbf{h}_2)
      - F (\mathbf{x, \mathbf{x} + \epsilon \mathbf{h}_1}) - F(\mathbf{x, \mathbf{x}
      - \epsilon \mathbf{h}_1} + \epsilon \mathbf{h}_2)
      + F(\mathbf{x, \mathbf{x} - \epsilon \mathbf{h}_1}).
  
  For more details, see:
  
      Julien Gacon, Christa Zoufal, Giuseppe Carleo, and Stefan Woerner.
      "Simultaneous Perturbation Stochastic Approximation of the Quantum Fisher Information."
      `Quantum, 5, 567 <https://quantum-journal.org/papers/q-2021-10-20-567/>`_, 2021.
  
  You can also find a walkthrough of the implementation in this `tutorial <https://pennylane.ai/qml/demos/qnspsa.html>`_.
  
  **Examples:**
  
  For VQE/VQE-like problems, the objective function can be defined within a qnode:
  
  >>> num_qubits = 2
  >>> dev = qml.device("default.qubit", wires=num_qubits)
  >>> @qml.qnode(dev)
  ... def cost(params):
  ...     qml.RX(params[0], wires=0)
  ...     qml.CRY(params[1], wires=[0, 1])
  ...     return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))
  
  Once constructed, the qnode can be passed directly to the ``step`` or ``step_and_cost``
  function of the optimizer.
  
  >>> params = np.random.rand(2)
  >>> opt = QNSPSAOptimizer(stepsize=5e-2)
  >>> for i in range(51):
  >>>     params, loss = opt.step_and_cost(cost, params)
  >>>     if i % 10 == 0:
  ...         print(f"Step {i}: cost = {loss:.4f}")
  Step 0: cost = 0.9987
  Step 10: cost = 0.9841
  Step 20: cost = 0.8921
  Step 30: cost = 0.0910
  Step 40: cost = -0.9369
  Step 50: cost = -0.9984
  
  Keyword Args:
      stepsize (float): the user-defined hyperparameter :math:`\eta` for learning rate (default: 1e-3)
      regularization (float): regularitzation term :math:`\beta` to the Fubini-Study metric tensor
          for numerical stability (default: 1e-3)
      finite_diff_step (float): step size :math:`\epsilon` to compute the finite difference
          gradient and the Fubini-Study metric tensor (default: 1e-2)
      resamplings (int): the number of samples to average for each parameter update (default: 1)
      blocking (boolean): when set to be True, the optimizer only accepts updates that lead to a
          loss value no larger than the loss value before update, plus a tolerance. The tolerance
          is set with the hyperparameter ``history_length``. The ``blocking`` option is
          observed to help the optimizer to converge significantly faster (default: True)
      history_length (int): when ``blocking`` is True, the tolerance is set to be the average of
          the cost values in the last ``history_length`` steps (default: 5)
      seed (int): seed for the random sampling (default: None)
class_docstr_tok: ["Quantum","natural","SPSA","(","QNSPSA",")","optimizer",".","QNSPSA","is","a","second-order","SPSA","algorithm",",","which","updates","the","ansatz","parameters","with","the","following","equation",":","..","math",":",":","\\mathbf","{","x","}","^","{","(","t","+","1",")","}","=","\\mathbf","{","x","}","^","{","(","t",")","}","-","\\eta","\\widehat","{","\\mathbf","{","g","}","}","^","{","-1","}","(","\\mathbf","{","x","}","^","{","(","t",")","}",")","\\widehat","{","\\nabla","f","}","(","\\mathbf","{","x","}","^","{","(","t",")","}",")",",","where",":","math",":","`","f","(","\\mathbf","{","x","}",")","`","is","the","objective","function","with","input","parameters",":","math",":","`","\\mathbf","{","x","}","`",",","while",":","math",":","`","\\nabla","f","`","is","the","gradient",",",":","math",":","`","\\mathbf","{","g","}","`","is","the","second-order","Fubini-Study","metric","tensor",".","With","QNSPSA","algorithm",",","both","the","gradient","and","the","metric","tensor","are","estimated","stochastically",",","with",":","math",":","`","\\widehat","{","\\nabla","f","}","`","and",":","math",":","`","\\widehat","{","\\mathbf","{","g","}","}","`",".","This","stochastic","approach","requires","only","a","fixed","number","of","circuit","executions","per","optimization","step",",","independent","of","the","problem","size",".","This","preferred","scaling","makes","it","a","promising","candidate","for","the","optimization","tasks","for","high-dimensional","ansatzes",".","On","the","other","hand",",","the","introduction","of","the","Fubini-Study","metric","into","the","optimization","helps","to","find","better","minima","and","allows","for","faster","convergence",".","The","gradient","is","estimated","similarly","as","the","`","SPSA","optimizer","<","https",":","\/\/pennylane.readthedocs.io\/en\/stable\/code\/api\/pennylane.SPSAOptimizer.html",">","`","_",",","with","a","pair","of","perturbations",":","..","math",":",":","\\widehat","{","\\nabla","f","}","(","\\mathbf","{","x","}",")","=","\\widehat","{","\\nabla","f","}","(","\\mathbf","{","x","}",",","\\mathbf","{","h","}",")","\\approx","\\frac","{","1","}","{","2\\epsilon","}","\\big","(","f","(","\\mathbf","{","x","}","+","\\epsilon","\\mathbf","{","h","}",")","-","f","(","\\mathbf","{","x","}","-","\\epsilon","\\mathbf","{","h","}",")","\\big",")",",","where",":","math",":","`","\\epsilon","`","is","the","finite-difference","step","size","specified","by","the","user",",","and",":","math",":","`","\\mathbf","{","h","}","`","is","a","randomly","sampled","direction","vector","to","perform","the","perturbation",".","The","Fubini-Study","metric","tensor","is","estimated","with","another","two","pairs","of","perturbations","along","randomly","sampled","directions",":","math",":","`","\\mathbf","{","h_1","}","`","and",":","math",":","`","\\mathbf","{","h_2","}","`",":","..","math",":",":","\\widehat","{","\\mathbf","{","g","}","}","(","\\mathbf","{","x","}",")","=","\\widehat","{","\\mathbf","{","g","}","}","(","\\mathbf","{","x","}",",","\\mathbf","{","h","}","_1",",","\\mathbf","{","h","}","_2",")","\\approx","\\frac","{","\\delta","F","}","{","8","\\epsilon^2","}","\\Big","(","\\mathbf","{","h","}","_1","\\mathbf","{","h","}","_2^\\intercal","+","\\mathbf","{","h","}","_2","\\mathbf","{","h","}","_1^\\intercal\\Big",")",",","where",":","math",":","`","F","(","\\mathbf","{","x","}","'",",","\\mathbf","{","x","}",")","=","\\bigr\\rvert\\langle","\\phi","(","\\mathbf","{","x","}","'",")","|","\\phi","(","\\mathbf","{","x","}",")","\\rangle","\\bigr\\rvert","^","2","`","measures","the","state","overlap","between",":","math",":","`","\\phi","(","\\mathbf","{","x","}","'",")","`","and",":","math",":","`","\\phi","(","\\mathbf","{","x","}",")","`",",","where",":","math",":","`","\\phi","`","is","the","parameterized","ansatz",".","The","finite","difference",":","math",":","`","\\delta","F","`","is","computed","from","the","two","perturbations",":","..","math",":",":","\\delta","F","=","F","(","\\mathbf","{","x",",","\\mathbf","{","x","}","+","\\epsilon","\\mathbf","{","h","}","_1","}","+","\\epsilon","\\mathbf","{","h","}","_2",")","-","F","(","\\mathbf","{","x",",","\\mathbf","{","x","}","+","\\epsilon","\\mathbf","{","h","}","_1","}",")","-","F","(","\\mathbf","{","x",",","\\mathbf","{","x","}","-","\\epsilon","\\mathbf","{","h","}","_1","}","+","\\epsilon","\\mathbf","{","h","}","_2",")","+","F","(","\\mathbf","{","x",",","\\mathbf","{","x","}","-","\\epsilon","\\mathbf","{","h","}","_1","}",")",".","For","more","details",",","see",":","Julien","Gacon",",","Christa","Zoufal",",","Giuseppe","Carleo",",","and","Stefan","Woerner",".","``","Simultaneous","Perturbation","Stochastic","Approximation","of","the","Quantum","Fisher","Information",".","''","`","Quantum",",","5",",","567","<","https",":","\/\/quantum-journal.org\/papers\/q-2021-10-20-567\/",">","`","_",",","2021",".","You","can","also","find","a","walkthrough","of","the","implementation","in","this","`","tutorial","<","https",":","\/\/pennylane.ai\/qml\/demos\/qnspsa.html",">","`","_",".","*","*","Examples",":","*","*","For","VQE\/VQE-like","problems",",","the","objective","function","can","be","defined","within","a","qnode",":",">",">",">","num_qubits","=","2",">",">",">","dev","=","qml.device","(","``","default.qubit","''",",","wires=num_qubits",")",">",">",">","@","qml.qnode","(","dev",")","...","def","cost","(","params",")",":","...","qml.RX","(","params","[","0","]",",","wires=0",")","...","qml.CRY","(","params","[","1","]",",","wires=","[","0",",","1","]",")","...","return","qml.expval","(","qml.PauliZ","(","0",")","@","qml.PauliZ","(","1",")",")","Once","constructed",",","the","qnode","can","be","passed","directly","to","the","``","step","``","or","``","step_and_cost","``","function","of","the","optimizer",".",">",">",">","params","=","np.random.rand","(","2",")",">",">",">","opt","=","QNSPSAOptimizer","(","stepsize=5e-2",")",">",">",">","for","i","in","range","(","51",")",":",">",">",">","params",",","loss","=","opt.step_and_cost","(","cost",",","params",")",">",">",">","if","i","%","10","==","0",":","...","print","(","f","''","Step","{","i","}",":","cost","=","{","loss",":",".4f","}","''",")","Step","0",":","cost","=","0.9987","Step","10",":","cost","=","0.9841","Step","20",":","cost","=","0.8921","Step","30",":","cost","=","0.0910","Step","40",":","cost","=","-0.9369","Step","50",":","cost","=","-0.9984","Keyword","Args",":","stepsize","(","float",")",":","the","user-defined","hyperparameter",":","math",":","`","\\eta","`","for","learning","rate","(","default",":","1e-3",")","regularization","(","float",")",":","regularitzation","term",":","math",":","`","\\beta","`","to","the","Fubini-Study","metric","tensor","for","numerical","stability","(","default",":","1e-3",")","finite_diff_step","(","float",")",":","step","size",":","math",":","`","\\epsilon","`","to","compute","the","finite","difference","gradient","and","the","Fubini-Study","metric","tensor","(","default",":","1e-2",")","resamplings","(","int",")",":","the","number","of","samples","to","average","for","each","parameter","update","(","default",":","1",")","blocking","(","boolean",")",":","when","set","to","be","True",",","the","optimizer","only","accepts","updates","that","lead","to","a","loss","value","no","larger","than","the","loss","value","before","update",",","plus","a","tolerance",".","The","tolerance","is","set","with","the","hyperparameter","``","history_length","``",".","The","``","blocking","``","option","is","observed","to","help","the","optimizer","to","converge","significantly","faster","(","default",":","True",")","history_length","(","int",")",":","when","``","blocking","``","is","True",",","the","tolerance","is","set","to","be","the","average","of","the","cost","values","in","the","last","``","history_length","``","steps","(","default",":","5",")","seed","(","int",")",":","seed","for","the","random","sampling","(","default",":","None",")"]
docstr: Update trainable parameters with one step of the optimizer and return
  the corresponding objective function value after the step.
  
  Args:
      cost (QNode): the QNode wrapper for the objective function for optimization
      args : variable length argument list for qnode
      kwargs : variable length of keyword arguments for the qnode
  
  Returns:
      (np.array, float): the new variable values :math:`x^{(t+1)}` and the objective
      function output prior to the step
docstr_tok: ["Update","trainable","parameters","with","one","step","of","the","optimizer","and","return","the","corresponding","objective","function","value","after","the","step",".","Args",":","cost","(","QNode",")",":","the","QNode","wrapper","for","the","objective","function","for","optimization","args",":","variable","length","argument","list","for","qnode","kwargs",":","variable","length","of","keyword","arguments","for","the","qnode","Returns",":","(","np.array",",","float",")",":","the","new","variable","values",":","math",":","`","x^","{","(","t+1",")","}","`","and","the","objective","function","output","prior","to","the","step"]
code: def step_and_cost(self, cost, *args, **kwargs):
      r"""Update trainable parameters with one step of the optimizer and return
      the corresponding objective function value after the step.
  
      Args:
          cost (QNode): the QNode wrapper for the objective function for optimization
          args : variable length argument list for qnode
          kwargs : variable length of keyword arguments for the qnode
  
      Returns:
          (np.array, float): the new variable values :math:`x^{(t+1)}` and the objective
          function output prior to the step
      """
      params_next = self._step_core(cost, args, kwargs)
  
      if not self.blocking:
          loss_curr = cost(*args, **kwargs)
          return params_next, loss_curr
  
      params_next, loss_curr = self._apply_blocking(
          cost, args, kwargs, params_next
      )
      return params_next, loss_curr
  
file_path: pennylane/pennylane/optimize/qnspsa.py
imports: import warnings
  from scipy.linalg import sqrtm
  import numpy
  import pennylane
label_desc: Use image node_id 3 for calling the QNSPSAOptimizer obj's underlying member method code with example usage: obj.step_and_cost(cost) and returns: params_next,  loss_curr, params_next,  loss_curr