class_docstr: Abstract base class for PennyLane qubit devices.
  
  The following abstract method **must** be defined:
  
  * :meth:`~.apply`: append circuit operations, compile the circuit (if applicable),
    and perform the quantum computation.
  
  Devices that generate their own samples (such as hardware) may optionally
  overwrite :meth:`~.probability`. This method otherwise automatically
  computes the probabilities from the generated samples, and **must**
  overwrite the following method:
  
  * :meth:`~.generate_samples`: Generate samples from the device from the
    exact or approximate probability distribution.
  
  Analytic devices **must** overwrite the following method:
  
  * :meth:`~.analytic_probability`: returns the probability or marginal probability from the
    device after circuit execution. :meth:`~.marginal_prob` may be used here.
  
  This device contains common utility methods for qubit-based devices. These
  do not need to be overwritten. Utility methods include:
  
  * :meth:`~.expval`, :meth:`~.var`, :meth:`~.sample`: return expectation values,
    variances, and samples of observables after the circuit has been rotated
    into the observable eigenbasis.
  
  Args:
      wires (int, Iterable[Number, str]]): Number of subsystems represented by the device,
          or iterable that contains unique labels for the subsystems as numbers (i.e., ``[-1, 0, 2]``)
          or strings (``['ancilla', 'q1', 'q2']``). Default 1 if not specified.
      shots (None, int, list[int]): Number of circuit evaluations/random samples used to estimate
          expectation values of observables. If ``None``, the device calculates probability, expectation values,
          and variances analytically. If an integer, it specifies the number of samples to estimate these quantities.
          If a list of integers is passed, the circuit evaluations are batched over the list of shots.
      r_dtype: Real floating point precision type.
      c_dtype: Complex floating point precision type.
docstr: Return the marginal probability of the computational basis
  states by summing the probabiliites on the non-specified wires.
  
  If no wires are specified, then all the basis states representable by
  the device are considered and no marginalization takes place.
  
  .. note::
  
      If the provided wires are not in the order as they appear on the device,
      the returned marginal probabilities take this permutation into account.
  
      For example, if the addressable wires on this device are ``Wires([0, 1, 2])`` and
      this function gets passed ``wires=[2, 0]``, then the returned marginal
      probability vector will take this 'reversal' of the two wires
      into account:
  
      .. math::
  
          \mathbb{P}^{(2, 0)}
                      = \left[
                         |00\rangle, |10\rangle, |01\rangle, |11\rangle
                        \right]
  
  Args:
      prob: The probabilities to return the marginal probabilities
          for
      wires (Iterable[Number, str], Number, str, Wires): wires to return
          marginal probabilities for. Wires not provided
          are traced out of the system.
  
  Returns:
      array[float]: array of the resulting marginal probabilities.
docstr_tok: ["Return","the","marginal","probability","of","the","computational","basis","states","by","summing","the","probabiliites","on","the","non-specified","wires",".","If","no","wires","are","specified",",","then","all","the","basis","states","representable","by","the","device","are","considered","and","no","marginalization","takes","place",".","..","note",":",":","If","the","provided","wires","are","not","in","the","order","as","they","appear","on","the","device",",","the","returned","marginal","probabilities","take","this","permutation","into","account",".","For","example",",","if","the","addressable","wires","on","this","device","are","``","Wires","(","[","0",",","1",",","2","]",")","``","and","this","function","gets","passed","``","wires=","[","2",",","0","]","``",",","then","the","returned","marginal","probability","vector","will","take","this","'reversal","'","of","the","two","wires","into","account",":","..","math",":",":","\\mathbb","{","P","}","^","{","(","2",",","0",")","}","=","\\left","[","|00\\rangle",",","|10\\rangle",",","|01\\rangle",",","|11\\rangle","\\right","]","Args",":","prob",":","The","probabilities","to","return","the","marginal","probabilities","for","wires","(","Iterable","[","Number",",","str","]",",","Number",",","str",",","Wires",")",":","wires","to","return","marginal","probabilities","for",".","Wires","not","provided","are","traced","out","of","the","system",".","Returns",":","array","[","float","]",":","array","of","the","resulting","marginal","probabilities","."]
code: def marginal_prob(self, prob, wires=None):
      r"""Return the marginal probability of the computational basis
      states by summing the probabiliites on the non-specified wires.
  
      If no wires are specified, then all the basis states representable by
      the device are considered and no marginalization takes place.
  
      .. note::
  
          If the provided wires are not in the order as they appear on the device,
          the returned marginal probabilities take this permutation into account.
  
          For example, if the addressable wires on this device are ``Wires([0, 1, 2])`` and
          this function gets passed ``wires=[2, 0]``, then the returned marginal
          probability vector will take this 'reversal' of the two wires
          into account:
  
          .. math::
  
              \mathbb{P}^{(2, 0)}
                          = \left[
                             |00\rangle, |10\rangle, |01\rangle, |11\rangle
                            \right]
  
      Args:
          prob: The probabilities to return the marginal probabilities
              for
          wires (Iterable[Number, str], Number, str, Wires): wires to return
              marginal probabilities for. Wires not provided
              are traced out of the system.
  
      Returns:
          array[float]: array of the resulting marginal probabilities.
      """
      dim = 2**self.num_wires
      batch_size = self._get_batch_size(
          prob, (dim,), dim
      )  # pylint: disable=assignment-from-none
  
      if wires is None:
          # no need to marginalize
          return prob
  
      wires = Wires(wires)
      # determine which subsystems are to be summed over
      inactive_wires = Wires.unique_wires([self.wires, wires])
  
      # translate to wire labels used by device
      device_wires = self.map_wires(wires)
      inactive_device_wires = self.map_wires(inactive_wires)
  
      # hotfix to catch when default.qubit uses this method
      # since then device_wires is a list
      if isinstance(inactive_device_wires, Wires):
          inactive_device_wires = inactive_device_wires.labels
  
      # reshape the probability so that each axis corresponds to a wire
      shape = [2] * self.num_wires
      desired_axes = np.argsort(np.argsort(device_wires))
      flat_shape = (-1,)
      if batch_size is not None:
          # prob now is reshaped to have self.num_wires+1 axes in the case of broadcasting
          shape.insert(0, batch_size)
          inactive_device_wires = [
              idx + 1 for idx in inactive_device_wires
          ]
          desired_axes = np.insert(desired_axes + 1, 0, 0)
          flat_shape = (batch_size, -1)
  
      prob = self._reshape(prob, shape)
      # sum over all inactive wires
      prob = self._reduce_sum(prob, inactive_device_wires)
      # rearrange wires to desired order
      prob = self._transpose(prob, desired_axes)
      # flatten and return probabilities
      return self._reshape(prob, flat_shape)
  
imports: import abc
  import itertools
  import warnings
  from collections import defaultdict
  from typing import Union, List
  import inspect
  import logging
  import numpy
  import pennylane
  from pennylane import Device, DeviceError
  from pennylane.workflow import set_shots
  from pennylane.math import multiply
  from pennylane.math import sum
  from pennylane.measurements import ClassicalShadowMP, CountsMP, ExpectationMP, MeasurementProcess, MeasurementTransform, MeasurementValue, MutualInfoMP, ProbabilityMP, SampleMeasurement, SampleMP, ShadowExpvalMP, StateMeasurement, StateMP, VarianceMP, VnEntropyMP, Shots
  from pennylane.resource import Resources
  from pennylane.operation import operation_derivative, Operation
  from pennylane.tape import QuantumTape
  from pennylane.wires import Wires
label_desc: Use image node_id 32 for calling the QubitDevice obj's underlying member method code with example usage: obj.marginal_prob(prob, wires) and returns: self, prob