class_docstr: Encodes :math:`2^n` features into the amplitude vector of :math:`n` qubits.
  
  By setting ``pad_with`` to a real or complex number, ``features`` is automatically padded to dimension
  :math:`2^n` where :math:`n` is the number of qubits used in the embedding.
  
  To represent a valid quantum state vector, the L2-norm of ``features`` must be one.
  The argument ``normalize`` can be set to ``True`` to automatically normalize the features.
  
  If both automatic padding and normalization are used, padding is executed *before* normalizing.
  
  .. note::
  
      On some devices, ``AmplitudeEmbedding`` must be the first operation of a quantum circuit.
  
  .. warning::
  
      At the moment, the ``features`` argument is **not differentiable** when using the template, and
      gradients with respect to the features cannot be computed by PennyLane.
  
  Args:
      features (tensor_like): input tensor of dimension ``(2^len(wires),)``, or less if `pad_with` is specified
      wires (Any or Iterable[Any]): wires that the template acts on
      pad_with (float or complex): if not None, the input is padded with this constant to size :math:`2^n`
      normalize (bool): whether to automatically normalize the features
      id (str): custom label given to an operator instance,
          can be useful for some applications where the instance has to be identified.
  
  Example:
  
      Amplitude embedding encodes a normalized :math:`2^n`-dimensional feature vector into the state
      of :math:`n` qubits:
  
      .. code-block:: python
  
          import pennylane as qml
  
          dev = qml.device('default.qubit', wires=2)
  
          @qml.qnode(dev)
          def circuit(f=None):
              qml.AmplitudeEmbedding(features=f, wires=range(2))
              return qml.expval(qml.PauliZ(0)), qml.state()
  
          res, state = circuit(f=[1/2, 1/2, 1/2, 1/2])
  
      The final state of the device is - up to a global phase - equivalent to the input passed to the circuit:
  
      >>> state
      tensor([0.5+0.j, 0.5+0.j, 0.5+0.j, 0.5+0.j], requires_grad=True)
  
      **Differentiating with respect to the features**
  
      Due to non-trivial classical processing to construct the state preparation circuit,
      the features argument is in general **not differentiable**.
  
      **Normalization**
  
      The template will raise an error if the feature input is not normalized.
      One can set ``normalize=True`` to automatically normalize it:
  
      .. code-block:: python
  
          @qml.qnode(dev)
          def circuit(f=None):
              qml.AmplitudeEmbedding(features=f, wires=range(2), normalize=True)
              return qml.expval(qml.PauliZ(0)), qml.state()
  
          res, state = circuit(f=[15, 15, 15, 15])
  
      >>> state
      tensor([0.5+0.j, 0.5+0.j, 0.5+0.j, 0.5+0.j], requires_grad=True)
  
      **Padding**
  
      If the dimension of the feature vector is smaller than the number of amplitudes,
      one can automatically pad it with a constant for the missing dimensions using the ``pad_with`` option:
  
      .. code-block:: python
  
          from math import sqrt
  
          @qml.qnode(dev)
          def circuit(f=None):
              qml.AmplitudeEmbedding(features=f, wires=range(2), pad_with=0.)
              return qml.expval(qml.PauliZ(0)), qml.state()
  
          res, state = circuit(f=[1/sqrt(2), 1/sqrt(2)])
  
      >>> state
      tensor([0.70710678+0.j, 0.70710678+0.j, 0.        +0.j, 0.        +0.j], requires_grad=True)
docstr: Validate and pre-process inputs as follows:
  
  * If features is batched, the processing that follows is applied to each feature set in the batch.
  * Check that the features tensor is one-dimensional.
  * If pad_with is None, check that the last dimension of the features tensor
    has length :math:`2^n` where :math:`n` is the number of qubits. Else check that the
    last dimension of the features tensor is not larger than :math:`2^n` and pad features
    with value if necessary.
  * If normalize is false, check that last dimension of features is normalised to one. Else, normalise the
    features tensor.
docstr_tok: ["Validate","and","pre-process","inputs","as","follows",":","*","If","features","is","batched",",","the","processing","that","follows","is","applied","to","each","feature","set","in","the","batch",".","*","Check","that","the","features","tensor","is","one-dimensional",".","*","If","pad_with","is","None",",","check","that","the","last","dimension","of","the","features","tensor","has","length",":","math",":","`","2^n","`","where",":","math",":","`","n","`","is","the","number","of","qubits",".","Else","check","that","the","last","dimension","of","the","features","tensor","is","not","larger","than",":","math",":","`","2^n","`","and","pad","features","with","value","if","necessary",".","*","If","normalize","is","false",",","check","that","last","dimension","of","features","is","normalised","to","one",".","Else",",","normalise","the","features","tensor","."]
code: def _preprocess(features, wires, pad_with, normalize):
      """Validate and pre-process inputs as follows:
  
      * If features is batched, the processing that follows is applied to each feature set in the batch.
      * Check that the features tensor is one-dimensional.
      * If pad_with is None, check that the last dimension of the features tensor
        has length :math:`2^n` where :math:`n` is the number of qubits. Else check that the
        last dimension of the features tensor is not larger than :math:`2^n` and pad features
        with value if necessary.
      * If normalize is false, check that last dimension of features is normalised to one. Else, normalise the
        features tensor.
      """
      shape = qml.math.shape(features)
  
      # check shape
      if len(shape) not in (1, 2):
          raise ValueError(
              f"Features must be a one-dimensional tensor, or two-dimensional with batching; got shape {shape}."
          )
  
      n_features = shape[-1]
      dim = 2 ** len(wires)
      if pad_with is None and n_features != dim:
          raise ValueError(
              f"Features must be of length {dim}; got length {n_features}. "
              f"Use the 'pad_with' argument for automated padding."
          )
  
      if pad_with is not None:
          if n_features > dim:
              raise ValueError(
                  f"Features must be of length {dim} or "
                  f"smaller to be padded; got length {n_features}."
              )
  
          # pad
          if n_features < dim:
              padding = [pad_with] * (dim - n_features)
              if len(shape) > 1:
                  padding = [padding] * shape[0]
              padding = qml.math.convert_like(padding, features)
              features = qml.math.hstack([features, padding])
  
      # normalize
      norm = qml.math.sum(qml.math.abs(features) ** 2, axis=-1)
  
      if qml.math.is_abstract(norm):
          if normalize or pad_with:
              features = features / qml.math.reshape(
                  qml.math.sqrt(norm), (*shape[:-1], 1)
              )
  
      elif not qml.math.allclose(norm, 1.0, atol=TOLERANCE):
          if normalize or pad_with:
              features = features / qml.math.reshape(
                  qml.math.sqrt(norm), (*shape[:-1], 1)
              )
          else:
              raise ValueError(
                  f"Features must be a vector of norm 1.0; got norm {norm}. "
                  "Use 'normalize=True' to automatically normalize."
              )
  
      return features
  
imports: import pennylane
  from pennylane.ops import StatePrep
  from pennylane.wires import Wires
label_desc: Use image node_id 3 for calling the AmplitudeEmbedding obj's underlying member method code with example usage: obj._preprocess(features, wires, pad_with, normalize) and returns: features