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 estimated probability of each computational basis state
  using the generated samples.
  
  Args:
      wires (Iterable[Number, str], Number, str, Wires): wires to calculate
          marginal probabilities for. Wires not provided are traced out of the system.
      shot_range (tuple[int]): 2-tuple of integers specifying the range of samples
          to use. If not specified, all samples are used.
      bin_size (int): Divides the shot range into bins of size ``bin_size``, and
          returns the measurement statistic separately over each bin. If not
          provided, the entire shot range is treated as a single bin.
  
  Returns:
      array[float]: list of the probabilities
docstr_tok: ["Return","the","estimated","probability","of","each","computational","basis","state","using","the","generated","samples",".","Args",":","wires","(","Iterable","[","Number",",","str","]",",","Number",",","str",",","Wires",")",":","wires","to","calculate","marginal","probabilities","for",".","Wires","not","provided","are","traced","out","of","the","system",".","shot_range","(","tuple","[","int","]",")",":","2-tuple","of","integers","specifying","the","range","of","samples","to","use",".","If","not","specified",",","all","samples","are","used",".","bin_size","(","int",")",":","Divides","the","shot","range","into","bins","of","size","``","bin_size","``",",","and","returns","the","measurement","statistic","separately","over","each","bin",".","If","not","provided",",","the","entire","shot","range","is","treated","as","a","single","bin",".","Returns",":","array","[","float","]",":","list","of","the","probabilities"]
code: def estimate_probability(
      self, wires=None, shot_range=None, bin_size=None
  ):
      """Return the estimated probability of each computational basis state
      using the generated samples.
  
      Args:
          wires (Iterable[Number, str], Number, str, Wires): wires to calculate
              marginal probabilities for. Wires not provided are traced out of the system.
          shot_range (tuple[int]): 2-tuple of integers specifying the range of samples
              to use. If not specified, all samples are used.
          bin_size (int): Divides the shot range into bins of size ``bin_size``, and
              returns the measurement statistic separately over each bin. If not
              provided, the entire shot range is treated as a single bin.
  
      Returns:
          array[float]: list of the probabilities
      """
  
      wires = wires or self.wires
      # convert to a Wires object
      wires = Wires(wires)
      # translate to wire labels used by device
      device_wires = self.map_wires(wires)
      num_wires = len(device_wires)
  
      if shot_range is None:
          # The Ellipsis (...) corresponds to broadcasting and shots dimensions or only shots
          samples = self._samples[..., device_wires]
      else:
          # The Ellipsis (...) corresponds to the broadcasting dimension or no axis at all
          samples = self._samples[..., slice(*shot_range), device_wires]
  
      # convert samples from a list of 0, 1 integers, to base 10 representation
      powers_of_two = 2 ** np.arange(num_wires)[::-1]
      indices = samples @ powers_of_two
  
      # `self._samples` typically has two axes ((shots, wires)) but can also have three with
      # broadcasting ((batch_size, shots, wires)) so that we simply read out the batch_size.
      batch_size = (
          self._samples.shape[0]
          if np.ndim(self._samples) == 3
          else None
      )
      dim = 2**num_wires
      # count the basis state occurrences, and construct the probability vector
      if bin_size is not None:
          num_bins = samples.shape[-2] // bin_size
          prob = self._count_binned_samples(
              indices, batch_size, dim, bin_size, num_bins
          )
      else:
          prob = self._count_unbinned_samples(indices, batch_size, dim)
  
      return self._asarray(prob, dtype=self.R_DTYPE)
  
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 27 for calling the QubitDevice obj's underlying member method code with example usage: obj.estimate_probability(wires, shot_range, bin_size) and returns: self