class_docstr: Default qubit device for PennyLane.
  
  .. warning::
  
      This is the legacy implementation of DefaultQubit. It has been replaced by
      ``qml.devices.DefaultQubit``, which can be accessed with the familiar constructor,
      ``qml.device("default.qubit")``.
  
      This change will not alter device behaviour for most workflows, but may have implications for
      plugin developers and users who directly interact with device methods. Please consult
      :class:`pennylane.devices.Device` and the implementation in
      :class:`pennylane.devices.DefaultQubit` for more information on what the new
      interface will look like and be prepared to make updates in a coming release. If you have any
      feedback on these changes, please create an
      `issue <https://github.com/PennyLaneAI/pennylane/issues>`_ or post in our
      `discussion forum <https://discuss.pennylane.ai/>`_.
  
  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): How many times the circuit should be evaluated (or sampled) to estimate
          the expectation values. Defaults to ``None`` if not specified, which means that the device
          returns analytical results.
class_docstr_tok: ["Default","qubit","device","for","PennyLane",".","..","warning",":",":","This","is","the","legacy","implementation","of","DefaultQubit",".","It","has","been","replaced","by","``","qml.devices.DefaultQubit","``",",","which","can","be","accessed","with","the","familiar","constructor",",","``","qml.device","(","``","default.qubit","''",")","``",".","This","change","will","not","alter","device","behaviour","for","most","workflows",",","but","may","have","implications","for","plugin","developers","and","users","who","directly","interact","with","device","methods",".","Please","consult",":","class",":","`","pennylane.devices.Device","`","and","the","implementation","in",":","class",":","`","pennylane.devices.DefaultQubit","`","for","more","information","on","what","the","new","interface","will","look","like","and","be","prepared","to","make","updates","in","a","coming","release",".","If","you","have","any","feedback","on","these","changes",",","please","create","an","`","issue","<","https",":","\/\/github.com\/PennyLaneAI\/pennylane\/issues",">","`","_","or","post","in","our","`","discussion","forum","<","https",":","\/\/discuss.pennylane.ai\/",">","`","_",".","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",")",":","How","many","times","the","circuit","should","be","evaluated","(","or","sampled",")","to","estimate","the","expectation","values",".","Defaults","to","``","None","``","if","not","specified",",","which","means","that","the","device","returns","analytical","results","."]
docstr: Returns the expectation value of a Hamiltonian observable. When the observable is a
  ``Hamiltonian`` or ``SparseHamiltonian`` object, the expectation value is computed directly
  from the sparse matrix representation, which leads to faster execution.
  
  Args:
      observable (~.Observable): a PennyLane observable
      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:
      float: returns the expectation value of the observable
  
  .. warning::
  
      This function does not support broadcasting if ``observable`` is a
      :class:``~.Hamiltonian`` and the device interface or the interface of the
      Hamiltonian is not NumPy or Autograd
code: def expval(self, observable, shot_range=None, bin_size=None):
      """Returns the expectation value of a Hamiltonian observable. When the observable is a
      ``Hamiltonian`` or ``SparseHamiltonian`` object, the expectation value is computed directly
      from the sparse matrix representation, which leads to faster execution.
  
      Args:
          observable (~.Observable): a PennyLane observable
          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:
          float: returns the expectation value of the observable
  
      .. warning::
  
          This function does not support broadcasting if ``observable`` is a
          :class:``~.Hamiltonian`` and the device interface or the interface of the
          Hamiltonian is not NumPy or Autograd
  
      """
      is_state_batched = self._ndim(self.state) == 2
      # intercept Sums
      if isinstance(observable, Sum) and not self.shots:
          return measure(
              ExpectationMP(observable.map_wires(self.wire_map)),
              self._pre_rotated_state,
              is_state_batched,
          )
  
      # intercept other Hamiltonians
      # TODO: Ideally, this logic should not live in the Device, but be moved
      # to a component that can be re-used by devices as needed.
      if observable.name not in ("Hamiltonian", "SparseHamiltonian"):
          return super().expval(
              observable, shot_range=shot_range, bin_size=bin_size
          )
  
      assert (
          self.shots is None
      ), f"{observable.name} must be used with shots=None"
  
      self.map_wires(observable.wires)
      backprop_mode = (
          not isinstance(self.state, np.ndarray)
          or any(
              not isinstance(d, (float, np.ndarray))
              for d in observable.data
          )
      ) and observable.name == "Hamiltonian"
  
      if backprop_mode:
          # TODO[dwierichs]: This branch is not adapted to broadcasting yet
          if is_state_batched:
              raise NotImplementedError(
                  "Expectation values of Hamiltonians for interface!=None are "
                  "not supported together with parameter broadcasting yet"
              )
          # We must compute the expectation value assuming that the Hamiltonian
          # coefficients *and* the quantum states are tensor objects.
  
          # Compute  <psi| H |psi> via sum_i coeff_i * <psi| PauliWord |psi> using a sparse
          # representation of the Pauliword
          res = qml.math.cast(
              qml.math.convert_like(0.0, observable.data), dtype=complex
          )
          interface = qml.math.get_interface(self.state)
  
          # Note: it is important that we use the Hamiltonian's data and not the coeffs
          # attribute. This is because the .data attribute may be 'unwrapped' as required by
          # the interfaces, whereas the .coeff attribute will always be the same input dtype
          # that the user provided.
          for op, coeff in zip(observable.ops, observable.data):
              # extract a scipy.sparse.coo_matrix representation of this Pauli word
              coo = qml.operation.Tensor(op).sparse_matrix(
                  wire_order=self.wires, format="coo"
              )
              Hmat = qml.math.cast(
                  qml.math.convert_like(coo.data, self.state),
                  self.C_DTYPE,
              )
  
              product = (
                  self._gather(self._conj(self.state), coo.row)
                  * Hmat
                  * self._gather(self.state, coo.col)
              )
              c = qml.math.convert_like(coeff, product)
  
              if interface == "tensorflow":
                  c = qml.math.cast(c, "complex128")
  
              res = qml.math.convert_like(res, product) + qml.math.sum(
                  c * product
              )
  
      else:
          # Coefficients and the state are not trainable, we can be more
          # efficient in how we compute the Hamiltonian sparse matrix.
          Hmat = observable.sparse_matrix(wire_order=self.wires)
  
          state = qml.math.toarray(self.state)
          if is_state_batched:
              res = qml.math.array(
                  [
                      csr_matrix.dot(
                          csr_matrix(self._conj(_state)),
                          csr_matrix.dot(
                              Hmat, csr_matrix(_state[..., None])
                          ),
                      ).toarray()[0]
                      for _state in state
                  ]
              )
          else:
              res = csr_matrix.dot(
                  csr_matrix(self._conj(state)),
                  csr_matrix.dot(Hmat, csr_matrix(state[..., None])),
              ).toarray()[0]
  
      if observable.name == "Hamiltonian":
          res = qml.math.squeeze(res)
  
      return self._real(res)
  
imports: import functools
  import itertools
  from string import ascii_letters
  from typing import List
  import numpy
  from scipy.sparse import csr_matrix
  import pennylane
  from pennylane import BasisState, DeviceError, QubitDevice, StatePrep, Snapshot
  from pennylane.devices.qubit import measure
  from pennylane.operation import Operation
  from pennylane.ops import Sum
  from pennylane.ops.qubit.attributes import diagonal_in_z_basis
  from pennylane.pulse import ParametrizedEvolution
  from pennylane.measurements import ExpectationMP
  from pennylane.typing import TensorLike
  from pennylane.wires import WireError
  from .._version import __version__
label_desc: Use image node_id 22 for calling the DefaultQubitLegacy obj's underlying member method code with example usage: obj.expval(observable, shot_range, bin_size) and returns: self, measure, super