class_docstr: Class for classical shadow post-processing expectation values, approximate states, and entropies.
  
  A ``ClassicalShadow`` is a classical description of a quantum state that is capable of reproducing expectation values of local Pauli observables, see `2002.08953 <https://arxiv.org/abs/2002.08953>`_.
  
  The idea is to capture :math:`T` local snapshots (given by the ``shots`` set in the device) of the state by performing measurements in random Pauli bases at each qubit.
  The measurement outcomes, denoted ``bits``, as well as the choices of measurement bases, ``recipes``, are recorded in two ``(T, len(wires))`` integer tensors, respectively.
  
  From the :math:`t`-th measurement, we can reconstruct the ``local_snapshots`` (see methods)
  
  .. math:: \rho^{(t)} = \bigotimes_{i=1}^{n} 3 U^\dagger_i |b_i \rangle \langle b_i | U_i - \mathbb{I},
  
  where :math:`U_i` is the rotation corresponding to the measurement (e.g. :math:`U_i=H` for measurement in :math:`X`) of qubit :math:`i` at snapshot :math:`t` and :math:`|b_i\rangle = (1 - b_i, b_i)`
  the corresponding computational basis state given the output bit :math:`b_i`.
  
  From these local snapshots, one can compute expectation values of local Pauli strings, where locality refers to the number of non-Identity operators.
  The accuracy of the procedure is determined by the number of measurements :math:`T` (``shots``).
  To target an error :math:`\epsilon`, one needs of order :math:`T = \mathcal{O}\left( \log(M) 4^\ell/\epsilon^2 \right)` measurements to determine :math:`M` different,
  :math:`\ell`-local observables.
  
  One can in principle also reconstruct the global state :math:`\sum_t \rho^{(t)}/T`, though it is not advisable nor practical for larger systems due to its exponential scaling.
  
  .. note:: As per `arXiv:2103.07510 <https://arxiv.org/abs/2103.07510>`_, when computing multiple expectation values it is advisable to directly estimate the desired observables by simultaneously measuring
      qubit-wise-commuting terms. One way of doing this in PennyLane is via :class:`~pennylane.Hamiltonian` and setting ``grouping_type="qwc"``. For more details on this topic, see our demo
      on `estimating expectation values with classical shadows <https://pennylane.ai/qml/demos/tutorial_diffable_shadows.html>`_.
  
  Args:
      bits (tensor): recorded measurement outcomes in random Pauli bases.
      recipes (tensor): recorded measurement bases.
      wire_map (list[int]): list of the measured wires in the order that
          they appear in the columns of ``bits`` and ``recipes``. If None, defaults
          to ``range(n)``, where ``n`` is the number of measured wires.
  
  .. seealso:: Demo on `Estimating observables with classical shadows in the Pauli basis <https://pennylane.ai/qml/demos/tutorial_diffable_shadows.html>`_, :func:`~.pennylane.classical_shadow`
  
  **Example**
  
  We obtain the ``bits`` and ``recipes`` via :func:`~.pennylane.classical_shadow` measurement:
  
  .. code-block:: python3
  
      dev = qml.device("default.qubit", wires=range(2), shots=1000)
      @qml.qnode(dev)
      def qnode(x):
          qml.Hadamard(0)
          qml.CNOT((0,1))
          qml.RX(x, wires=0)
          return qml.classical_shadow(wires=range(2))
  
      bits, recipes = qnode(0)
      shadow = qml.ClassicalShadow(bits, recipes)
  
  After recording these ``T=1000`` quantum measurements, we can post-process the results to arbitrary local expectation values of Pauli strings.
  For example, we can compute the expectation value of a Pauli string
  
  >>> shadow.expval(qml.PauliX(0) @ qml.PauliX(1), k=1)
  array(0.972)
  
  or of a Hamiltonian:
  
  >>> H = qml.Hamiltonian([1., 1.], [qml.PauliZ(0) @ qml.PauliZ(1), qml.PauliX(0) @ qml.PauliX(1)])
  >>> shadow.expval(H, k=1)
  array(1.917)
  
  The parameter ``k`` is used to estimate the expectation values via the `median of means` algorithm (see `2002.08953 <https://arxiv.org/abs/2002.08953>`_). The case ``k=1`` corresponds to simply taking the mean
  value over all local snapshots. ``k>1`` corresponds to splitting the ``T`` local snapshots into ``k`` equal parts, and taking the median of their individual means. For the case of measuring only in the Pauli basis,
  there is no advantage expected from setting ``k>1``.
class_docstr_tok: ["Class","for","classical","shadow","post-processing","expectation","values",",","approximate","states",",","and","entropies",".","A","``","ClassicalShadow","``","is","a","classical","description","of","a","quantum","state","that","is","capable","of","reproducing","expectation","values","of","local","Pauli","observables",",","see","`","2002.08953","<","https",":","\/\/arxiv.org\/abs\/2002.08953",">","`","_",".","The","idea","is","to","capture",":","math",":","`","T","`","local","snapshots","(","given","by","the","``","shots","``","set","in","the","device",")","of","the","state","by","performing","measurements","in","random","Pauli","bases","at","each","qubit",".","The","measurement","outcomes",",","denoted","``","bits","``",",","as","well","as","the","choices","of","measurement","bases",",","``","recipes","``",",","are","recorded","in","two","``","(","T",",","len","(","wires",")",")","``","integer","tensors",",","respectively",".","From","the",":","math",":","`","t","`","-th","measurement",",","we","can","reconstruct","the","``","local_snapshots","``","(","see","methods",")","..","math",":",":","\\rho^","{","(","t",")","}","=","\\bigotimes_","{","i=1","}","^","{","n","}","3","U^\\dagger_i","|b_i","\\rangle","\\langle","b_i","|","U_i","-","\\mathbb","{","I","}",",","where",":","math",":","`","U_i","`","is","the","rotation","corresponding","to","the","measurement","(","e.g",".",":","math",":","`","U_i=H","`","for","measurement","in",":","math",":","`","X","`",")","of","qubit",":","math",":","`","i","`","at","snapshot",":","math",":","`","t","`","and",":","math",":","`","|b_i\\rangle","=","(","1","-","b_i",",","b_i",")","`","the","corresponding","computational","basis","state","given","the","output","bit",":","math",":","`","b_i","`",".","From","these","local","snapshots",",","one","can","compute","expectation","values","of","local","Pauli","strings",",","where","locality","refers","to","the","number","of","non-Identity","operators",".","The","accuracy","of","the","procedure","is","determined","by","the","number","of","measurements",":","math",":","`","T","`","(","``","shots","``",")",".","To","target","an","error",":","math",":","`","\\epsilon","`",",","one","needs","of","order",":","math",":","`","T","=","\\mathcal","{","O","}","\\left","(","\\log","(","M",")","4^\\ell\/\\epsilon^2","\\right",")","`","measurements","to","determine",":","math",":","`","M","`","different",",",":","math",":","`","\\ell","`","-local","observables",".","One","can","in","principle","also","reconstruct","the","global","state",":","math",":","`","\\sum_t","\\rho^","{","(","t",")","}","\/T","`",",","though","it","is","not","advisable","nor","practical","for","larger","systems","due","to","its","exponential","scaling",".","..","note",":",":","As","per","`","arXiv:2103.07510","<","https",":","\/\/arxiv.org\/abs\/2103.07510",">","`","_",",","when","computing","multiple","expectation","values","it","is","advisable","to","directly","estimate","the","desired","observables","by","simultaneously","measuring","qubit-wise-commuting","terms",".","One","way","of","doing","this","in","PennyLane","is","via",":","class",":","`","~pennylane.Hamiltonian","`","and","setting","``","grouping_type=","''","qwc","''","``",".","For","more","details","on","this","topic",",","see","our","demo","on","`","estimating","expectation","values","with","classical","shadows","<","https",":","\/\/pennylane.ai\/qml\/demos\/tutorial_diffable_shadows.html",">","`","_",".","Args",":","bits","(","tensor",")",":","recorded","measurement","outcomes","in","random","Pauli","bases",".","recipes","(","tensor",")",":","recorded","measurement","bases",".","wire_map","(","list","[","int","]",")",":","list","of","the","measured","wires","in","the","order","that","they","appear","in","the","columns","of","``","bits","``","and","``","recipes","``",".","If","None",",","defaults","to","``","range","(","n",")","``",",","where","``","n","``","is","the","number","of","measured","wires",".","..","seealso",":",":","Demo","on","`","Estimating","observables","with","classical","shadows","in","the","Pauli","basis","<","https",":","\/\/pennylane.ai\/qml\/demos\/tutorial_diffable_shadows.html",">","`","_",",",":","func",":","`","~.pennylane.classical_shadow","`","*","*","Example","*","*","We","obtain","the","``","bits","``","and","``","recipes","``","via",":","func",":","`","~.pennylane.classical_shadow","`","measurement",":","..","code-block",":",":","python3","dev","=","qml.device","(","``","default.qubit","''",",","wires=range","(","2",")",",","shots=1000",")","@","qml.qnode","(","dev",")","def","qnode","(","x",")",":","qml.Hadamard","(","0",")","qml.CNOT","(","(","0,1",")",")","qml.RX","(","x",",","wires=0",")","return","qml.classical_shadow","(","wires=range","(","2",")",")","bits",",","recipes","=","qnode","(","0",")","shadow","=","qml.ClassicalShadow","(","bits",",","recipes",")","After","recording","these","``","T=1000","``","quantum","measurements",",","we","can","post-process","the","results","to","arbitrary","local","expectation","values","of","Pauli","strings",".","For","example",",","we","can","compute","the","expectation","value","of","a","Pauli","string",">",">",">","shadow.expval","(","qml.PauliX","(","0",")","@","qml.PauliX","(","1",")",",","k=1",")","array","(","0.972",")","or","of","a","Hamiltonian",":",">",">",">","H","=","qml.Hamiltonian","(","[","1.",",","1",".","]",",","[","qml.PauliZ","(","0",")","@","qml.PauliZ","(","1",")",",","qml.PauliX","(","0",")","@","qml.PauliX","(","1",")","]",")",">",">",">","shadow.expval","(","H",",","k=1",")","array","(","1.917",")","The","parameter","``","k","``","is","used","to","estimate","the","expectation","values","via","the","`","median","of","means","`","algorithm","(","see","`","2002.08953","<","https",":","\/\/arxiv.org\/abs\/2002.08953",">","`","_",")",".","The","case","``","k=1","``","corresponds","to","simply","taking","the","mean","value","over","all","local","snapshots",".","``","k",">","1","``","corresponds","to","splitting","the","``","T","``","local","snapshots","into","``","k","``","equal","parts",",","and","taking","the","median","of","their","individual","means",".","For","the","case","of","measuring","only","in","the","Pauli","basis",",","there","is","no","advantage","expected","from","setting","``","k",">","1","``","."]
docstr: Compute the T x 2**n x 2**n global snapshots
  
  .. warning::
  
      Classical shadows are not intended to reconstruct global quantum states.
      This method requires exponential scaling of measurements for accurate representations. Further, the output scales exponentially in the output dimension,
      and is therefore not practical for larger systems. A warning is raised for systems of sizes ``n>16``.
  
  Args:
      wires (Iterable[int]): The wires over which to compute the snapshots. For ``wires=None`` (default) all ``n`` qubits are used.
      snapshots (Iterable[int] or int): Only compute a subset of local snapshots. For ``snapshots=None`` (default), all local snapshots are taken.
          In case of an integer, a random subset of that size is taken. The subset can also be explicitly fixed by passing an Iterable with the corresponding indices.
  
  Returns:
      tensor: The global snapshots tensor of shape ``(T, 2**n, 2**n)`` containing the density matrices for each snapshot measurement.
  
  **Example**
  
  We can approximately reconstruct a Bell state:
  
  .. code-block:: python3
  
      dev = qml.device("default.qubit", wires=range(2), shots=1000)
      @qml.qnode(dev)
      def qnode():
          qml.Hadamard(0)
          qml.CNOT((0,1))
          return classical_shadow(wires=range(2))
  
      bits, recipes = qnode()
      shadow = ClassicalShadow(bits, recipes)
      shadow_state = np.mean(shadow.global_snapshots(), axis=0)
  
      bell_state = np.array([[0.5, 0, 0, 0.5], [0, 0, 0, 0], [0, 0, 0, 0], [0.5, 0, 0, 0.5]])
  
  >>> np.allclose(bell_state, shadow_state, atol=1e-1)
  True
docstr_tok: ["Compute","the","T","x","2","*","*","n","x","2","*","*","n","global","snapshots","..","warning",":",":","Classical","shadows","are","not","intended","to","reconstruct","global","quantum","states",".","This","method","requires","exponential","scaling","of","measurements","for","accurate","representations",".","Further",",","the","output","scales","exponentially","in","the","output","dimension",",","and","is","therefore","not","practical","for","larger","systems",".","A","warning","is","raised","for","systems","of","sizes","``","n",">","16","``",".","Args",":","wires","(","Iterable","[","int","]",")",":","The","wires","over","which","to","compute","the","snapshots",".","For","``","wires=None","``","(","default",")","all","``","n","``","qubits","are","used",".","snapshots","(","Iterable","[","int","]","or","int",")",":","Only","compute","a","subset","of","local","snapshots",".","For","``","snapshots=None","``","(","default",")",",","all","local","snapshots","are","taken",".","In","case","of","an","integer",",","a","random","subset","of","that","size","is","taken",".","The","subset","can","also","be","explicitly","fixed","by","passing","an","Iterable","with","the","corresponding","indices",".","Returns",":","tensor",":","The","global","snapshots","tensor","of","shape","``","(","T",",","2","*","*","n",",","2","*","*","n",")","``","containing","the","density","matrices","for","each","snapshot","measurement",".","*","*","Example","*","*","We","can","approximately","reconstruct","a","Bell","state",":","..","code-block",":",":","python3","dev","=","qml.device","(","``","default.qubit","''",",","wires=range","(","2",")",",","shots=1000",")","@","qml.qnode","(","dev",")","def","qnode","(",")",":","qml.Hadamard","(","0",")","qml.CNOT","(","(","0,1",")",")","return","classical_shadow","(","wires=range","(","2",")",")","bits",",","recipes","=","qnode","(",")","shadow","=","ClassicalShadow","(","bits",",","recipes",")","shadow_state","=","np.mean","(","shadow.global_snapshots","(",")",",","axis=0",")","bell_state","=","np.array","(","[","[","0.5",",","0",",","0",",","0.5","]",",","[","0",",","0",",","0",",","0","]",",","[","0",",","0",",","0",",","0","]",",","[","0.5",",","0",",","0",",","0.5","]","]",")",">",">",">","np.allclose","(","bell_state",",","shadow_state",",","atol=1e-1",")","True"]
code: def global_snapshots(self, wires=None, snapshots=None):
      r"""Compute the T x 2**n x 2**n global snapshots
  
      .. warning::
  
          Classical shadows are not intended to reconstruct global quantum states.
          This method requires exponential scaling of measurements for accurate representations. Further, the output scales exponentially in the output dimension,
          and is therefore not practical for larger systems. A warning is raised for systems of sizes ``n>16``.
  
      Args:
          wires (Iterable[int]): The wires over which to compute the snapshots. For ``wires=None`` (default) all ``n`` qubits are used.
          snapshots (Iterable[int] or int): Only compute a subset of local snapshots. For ``snapshots=None`` (default), all local snapshots are taken.
              In case of an integer, a random subset of that size is taken. The subset can also be explicitly fixed by passing an Iterable with the corresponding indices.
  
      Returns:
          tensor: The global snapshots tensor of shape ``(T, 2**n, 2**n)`` containing the density matrices for each snapshot measurement.
  
      **Example**
  
      We can approximately reconstruct a Bell state:
  
      .. code-block:: python3
  
          dev = qml.device("default.qubit", wires=range(2), shots=1000)
          @qml.qnode(dev)
          def qnode():
              qml.Hadamard(0)
              qml.CNOT((0,1))
              return classical_shadow(wires=range(2))
  
          bits, recipes = qnode()
          shadow = ClassicalShadow(bits, recipes)
          shadow_state = np.mean(shadow.global_snapshots(), axis=0)
  
          bell_state = np.array([[0.5, 0, 0, 0.5], [0, 0, 0, 0], [0, 0, 0, 0], [0.5, 0, 0, 0.5]])
  
      >>> np.allclose(bell_state, shadow_state, atol=1e-1)
      True
  
      """
      local_snapshot = self.local_snapshots(wires, snapshots)
  
      if local_snapshot.shape[1] > 16:
          warnings.warn(
              "Querying density matrices for n_wires > 16 is not recommended, operation will take a long time",
              UserWarning,
          )
  
      T, n = local_snapshot.shape[:2]
  
      transposed_snapshots = np.transpose(
          local_snapshot, axes=(1, 0, 2, 3)
      )
  
      old_indices = [f"a{ABC[1 + 2 * i: 3 + 2 * i]}" for i in range(n)]
      new_indices = f"a{ABC[1:2 * n + 1:2]}{ABC[2:2 * n + 1:2]}"
  
      return np.reshape(
          np.einsum(
              f'{",".join(old_indices)}->{new_indices}',
              *transposed_snapshots,
          ),
          (T, 2**n, 2**n),
      )
  
file_path: pennylane/pennylane/shadows/classical_shadow.py
imports: import warnings
  from collections.abc import Iterable
  from string import ascii_letters
  import numpy
  import pennylane
label_desc: Use image node_id 4 for calling the ClassicalShadow obj's underlying member method code with example usage: obj.global_snapshots(wires, snapshots) and returns: np