class_docstr: Simulator plugin based on ``"default.qubit.legacy"``, written using TensorFlow.
  
  **Short name:** ``default.qubit.tf``
  
  This device provides a pure-state qubit simulator written using TensorFlow.
  As a result, it supports classical backpropagation as a means to compute the Jacobian. This can
  be faster than the parameter-shift rule for analytic quantum gradients
  when the number of parameters to be optimized is large.
  
  To use this device, you will need to install TensorFlow:
  
  .. code-block:: console
  
      pip install tensorflow>=2.0
  
  **Example**
  
  The ``default.qubit.tf`` is designed to be used with end-to-end classical backpropagation
  (``diff_method="backprop"``) with the TensorFlow interface. This is the default method
  of differentiation when creating a QNode with this device.
  
  Using this method, the created QNode is a 'white-box', and is
  tightly integrated with your TensorFlow computation:
  
  >>> dev = qml.device("default.qubit.tf", wires=1)
  >>> @qml.qnode(dev, interface="tf", diff_method="backprop")
  ... def circuit(x):
  ...     qml.RX(x[1], wires=0)
  ...     qml.Rot(x[0], x[1], x[2], wires=0)
  ...     return qml.expval(qml.PauliZ(0))
  >>> weights = tf.Variable([0.2, 0.5, 0.1])
  >>> with tf.GradientTape() as tape:
  ...     res = circuit(weights)
  >>> print(tape.gradient(res, weights))
  tf.Tensor([-2.2526717e-01 -1.0086454e+00  1.3877788e-17], shape=(3,), dtype=float32)
  
  Autograph mode will also work when using classical backpropagation:
  
  >>> @tf.function
  ... def cost(weights):
  ...     return tf.reduce_sum(circuit(weights)**3) - 1
  >>> with tf.GradientTape() as tape:
  ...     res = cost(weights)
  >>> print(tape.gradient(res, weights))
  tf.Tensor([-3.5471588e-01 -1.5882589e+00  3.4694470e-17], shape=(3,), dtype=float32)
  
  There are a couple of things to keep in mind when using the ``"backprop"``
  differentiation method for QNodes:
  
  * You must use the ``"tf"`` interface for classical backpropagation, as TensorFlow is
    used as the device backend.
  
  * Only exact expectation values, variances, and probabilities are
    differentiable. Creation of a backpropagation QNode with finite shots
    raises an error. If you do try and take a derivative with finite shots on
    this device, the gradient will be ``None``.
  
  
  If you wish to use a different machine-learning interface, or prefer to calculate quantum
  gradients using the ``parameter-shift`` or ``finite-diff`` differentiation methods,
  consider using the ``default.qubit`` device instead.
  
  
  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.
          If ``shots > 0`` is used, the ``diff_method="backprop"``
          QNode differentiation method is not supported and it is recommended to consider
          switching device to ``default.qubit`` and using ``diff_method="parameter-shift"``.
docstr: Initialize the internal state vector in a specified state.
  
  Args:
      state (array[complex]): normalized input state of length ``2**len(wires)``
          or broadcasted state of shape ``(batch_size, 2**len(wires))``
      device_wires (Wires): wires that get initialized in the state
  
  This implementation only adds a check for parameter broadcasting when initializing
  a quantum state on subsystems of the device.
docstr_tok: ["Initialize","the","internal","state","vector","in","a","specified","state",".","Args",":","state","(","array","[","complex","]",")",":","normalized","input","state","of","length","``","2","*","*","len","(","wires",")","``","or","broadcasted","state","of","shape","``","(","batch_size",",","2","*","*","len","(","wires",")",")","``","device_wires","(","Wires",")",":","wires","that","get","initialized","in","the","state","This","implementation","only","adds","a","check","for","parameter","broadcasting","when","initializing","a","quantum","state","on","subsystems","of","the","device","."]
code: def _apply_state_vector(self, state, device_wires):
      """Initialize the internal state vector in a specified state.
  
      Args:
          state (array[complex]): normalized input state of length ``2**len(wires)``
              or broadcasted state of shape ``(batch_size, 2**len(wires))``
          device_wires (Wires): wires that get initialized in the state
  
      This implementation only adds a check for parameter broadcasting when initializing
      a quantum state on subsystems of the device.
      """
  
      # translate to wire labels used by device
      device_wires = self.map_wires(device_wires)
      dim = 2 ** len(device_wires)
  
      state = self._asarray(state, dtype=self.C_DTYPE)
      batch_size = self._get_batch_size(state, (dim,), dim)
      output_shape = [2] * self.num_wires
      if batch_size:
          output_shape.insert(0, batch_size)
  
      if not (state.shape in [(dim,), (batch_size, dim)]):
          raise ValueError(
              "State vector must have shape (2**wires,) or (batch_size, 2**wires)."
          )
  
      if not qml.math.is_abstract(state):
          norm = qml.math.linalg.norm(state, axis=-1, ord=2)
          if not qml.math.allclose(norm, 1.0, atol=tolerance):
              raise ValueError(
                  "Sum of amplitudes-squared does not equal one."
              )
  
      if (
          len(device_wires) == self.num_wires
          and sorted(device_wires) == device_wires
      ):
          # Initialize the entire device state with the input state
          self._state = self._reshape(state, output_shape)
          return
  
      # generate basis states on subset of qubits via the cartesian product
      basis_states = np.array(
          list(itertools.product([0, 1], repeat=len(device_wires)))
      )
  
      # get basis states to alter on full set of qubits
      unravelled_indices = np.zeros(
          (2 ** len(device_wires), self.num_wires), dtype=int
      )
      unravelled_indices[:, device_wires] = basis_states
  
      # get indices for which the state is changed to input state vector elements
      ravelled_indices = np.ravel_multi_index(
          unravelled_indices.T, [2] * self.num_wires
      )
  
      if batch_size:
          # This is the only logical branch that differs from DefaultQubitLegacy
          raise NotImplementedError(
              "Parameter broadcasting is not supported together with initializing the state "
              "vector of a subsystem of the device when using DefaultQubitTF."
          )
      # The following line is unchanged in the "else"-clause in DefaultQubitLegacy's implementation
      state = self._scatter(
          ravelled_indices, state, [2**self.num_wires]
      )
      state = self._reshape(state, output_shape)
      self._state = self._asarray(state, dtype=self.C_DTYPE)
  
file_path: pennylane/pennylane/devices/default_qubit_tf.py
imports: import itertools
  import numpy
  import semantic_version
  import pennylane
  from pennylane.math.single_dispatch import _ndim_tf
  from .None import DefaultQubitLegacy
  from .default_qubit_legacy import tolerance
label_desc: Use image node_id 7 for calling the DefaultQubitTF obj's underlying member method code with example usage: obj._apply_state_vector(state, device_wires) without return types