We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Casting to complex in Amplitude Embedding
If I do not batch the parameters in `qml.AmplitudeEmbedding`, the parameter is preprocessed to be `np.compex128`:

```
>>> data = np.random.random(8)
>>> op = qml.templates.AmplitudeEmbedding(data, wires=[0, 1, 2], normalize=True)
>>> op.parameters
[tensor([0.45477115+0.j, 0.01693656+0.j, 0.07562024+0.j, 0.54867405+0.j,
         0.36355761+0.j, 0.50257082+0.j, 0.31384676+0.j, 0.05369689+0.j], requires_grad=True)]
```

But if I add a batch dimension, an warning is raised:
```
pennylane/pennylane/templates/embeddings/amplitude.py:208: ComplexWarning: Casting complex values to real discards the imaginary part
```

and the resulting parameters are purely real:

```
>>> batch_size = 5
>>> data = np.random.random((batch_size, 8))
>>> op = qml.templates.AmplitudeEmbedding(data, wires=[0, 1, 2], normalize=True)
>>> op.parameters
[tensor([[0.0016901 , 0.5075714 , 0.54801605, 0.03162948, 0.55714217,
          0.20436995, 0.00293922, 0.29809946],
         [0.3872195 , 0.22144908, 0.23615862, 0.18293768, 0.24939231,
          0.34098754, 0.51028387, 0.52242283],
         [0.3192768 , 0.30626548, 0.14370121, 0.5928348 , 0.12077899,
          0.06004839, 0.05753843, 0.64082493],
         [0.63251121, 0.02695029, 0.31892484, 0.29212886, 0.08482609,
          0.29508076, 0.56160044, 0.04987735],
         [0.01995247, 0.3879382 , 0.04970833, 0.36439654, 0.54700921,
          0.41374685, 0.48902248, 0.06558638]], requires_grad=True)]
```

I came across this problem when trying to clean warnings from the transform tests, so it is not currently breaking anything, but I would consider it unexpected behaviour.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pennylane/templates/embeddings/amplitude.py`
Content:
```
1 # Copyright 2018-2021 Xanadu Quantum Technologies Inc.
2 
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 r"""
15 Contains the AmplitudeEmbedding template.
16 """
17 # pylint: disable-msg=too-many-branches,too-many-arguments,protected-access
18 import numpy as np
19 
20 import pennylane as qml
21 from pennylane.operation import Operation, AnyWires
22 from pennylane.ops import QubitStateVector
23 from pennylane.wires import Wires
24 
25 # tolerance for normalization
26 TOLERANCE = 1e-10
27 
28 
29 class AmplitudeEmbedding(Operation):
30     r"""Encodes :math:`2^n` features into the amplitude vector of :math:`n` qubits.
31 
32     By setting ``pad_with`` to a real or complex number, ``features`` is automatically padded to dimension
33     :math:`2^n` where :math:`n` is the number of qubits used in the embedding.
34 
35     To represent a valid quantum state vector, the L2-norm of ``features`` must be one.
36     The argument ``normalize`` can be set to ``True`` to automatically normalize the features.
37 
38     If both automatic padding and normalization are used, padding is executed *before* normalizing.
39 
40     .. note::
41 
42         On some devices, ``AmplitudeEmbedding`` must be the first operation of a quantum circuit.
43 
44     .. warning::
45 
46         At the moment, the ``features`` argument is **not differentiable** when using the template, and
47         gradients with respect to the features cannot be computed by PennyLane.
48 
49     Args:
50         features (tensor_like): input tensor of dimension ``(2^n,)``, or less if `pad_with` is specified
51         wires (Iterable): wires that the template acts on
52         pad_with (float or complex): if not None, the input is padded with this constant to size :math:`2^n`
53         normalize (bool): whether to automatically normalize the features
54 
55     Example:
56 
57         Amplitude embedding encodes a normalized :math:`2^n`-dimensional feature vector into the state
58         of :math:`n` qubits:
59 
60         .. code-block:: python
61 
62             import pennylane as qml
63 
64             dev = qml.device('default.qubit', wires=2)
65 
66             @qml.qnode(dev)
67             def circuit(f=None):
68                 qml.AmplitudeEmbedding(features=f, wires=range(2))
69                 return qml.expval(qml.PauliZ(0))
70 
71             circuit(f=[1/2, 1/2, 1/2, 1/2])
72 
73         The final state of the device is - up to a global phase - equivalent to the input passed to the circuit:
74 
75         >>> dev.state
76         [0.5+0.j 0.5+0.j 0.5+0.j 0.5+0.j]
77 
78         **Differentiating with respect to the features**
79 
80         Due to non-trivial classical processing to construct the state preparation circuit,
81         the features argument is in general **not differentiable**.
82 
83         **Normalization**
84 
85         The template will raise an error if the feature input is not normalized.
86         One can set ``normalize=True`` to automatically normalize it:
87 
88         .. code-block:: python
89 
90             @qml.qnode(dev)
91             def circuit(f=None):
92                 qml.AmplitudeEmbedding(features=f, wires=range(2), normalize=True)
93                 return qml.expval(qml.PauliZ(0))
94 
95             circuit(f=[15, 15, 15, 15])
96 
97         >>> dev.state
98         [0.5 + 0.j, 0.5 + 0.j, 0.5 + 0.j, 0.5 + 0.j]
99 
100         **Padding**
101 
102         If the dimension of the feature vector is smaller than the number of amplitudes,
103         one can automatically pad it with a constant for the missing dimensions using the ``pad_with`` option:
104 
105         .. code-block:: python
106 
107             from math import sqrt
108 
109             @qml.qnode(dev)
110             def circuit(f=None):
111                 qml.AmplitudeEmbedding(features=f, wires=range(2), pad_with=0.)
112                 return qml.expval(qml.PauliZ(0))
113 
114             circuit(f=[1/sqrt(2), 1/sqrt(2)])
115 
116         >>> dev.state
117         [0.70710678 + 0.j, 0.70710678 + 0.j, 0.0 + 0.j, 0.0 + 0.j]
118 
119     """
120 
121     num_wires = AnyWires
122     grad_method = None
123 
124     def __init__(self, features, wires, pad_with=None, normalize=False, do_queue=True, id=None):
125 
126         wires = Wires(wires)
127         self.pad_with = pad_with
128         self.normalize = normalize
129 
130         features = self._preprocess(features, wires, pad_with, normalize)
131         super().__init__(features, wires=wires, do_queue=do_queue, id=id)
132 
133     @property
134     def num_params(self):
135         return 1
136 
137     def adjoint(self):  # pylint: disable=arguments-differ
138         return qml.adjoint(qml.MottonenStatePreparation)(self.parameters[0], wires=self.wires)
139 
140     def expand(self):
141 
142         with qml.tape.QuantumTape() as tape:
143             QubitStateVector(self.parameters[0], wires=self.wires)
144 
145         return tape
146 
147     @staticmethod
148     def _preprocess(features, wires, pad_with, normalize):
149         """Validate and pre-process inputs as follows:
150 
151         * If features is batched, the processing that follows is applied to each feature set in the batch.
152         * Check that the features tensor is one-dimensional.
153         * If pad_with is None, check that the first dimension of the features tensor
154           has length :math:`2^n` where :math:`n` is the number of qubits. Else check that the
155           first dimension of the features tensor is not larger than :math:`2^n` and pad features
156           with value if necessary.
157         * If normalize is false, check that first dimension of features is normalised to one. Else, normalise the
158           features tensor.
159         """
160 
161         # check if features is batched
162         batched = len(qml.math.shape(features)) > 1
163 
164         features_batch = features if batched else [features]
165 
166         # apply pre-processing to each features tensor in the batch
167         for i, feature_set in enumerate(features_batch):
168             shape = qml.math.shape(feature_set)
169 
170             # check shape
171             if len(shape) != 1:
172                 raise ValueError(f"Features must be a one-dimensional tensor; got shape {shape}.")
173 
174             n_features = shape[0]
175             if pad_with is None and n_features != 2 ** len(wires):
176                 raise ValueError(
177                     f"Features must be of length {2 ** len(wires)}; got length {n_features}. "
178                     f"Use the 'pad_with' argument for automated padding."
179                 )
180 
181             if pad_with is not None and n_features > 2 ** len(wires):
182                 raise ValueError(
183                     f"Features must be of length {2 ** len(wires)} or "
184                     f"smaller to be padded; got length {n_features}."
185                 )
186 
187             # pad
188             if pad_with is not None and n_features < 2 ** len(wires):
189                 padding = [pad_with] * (2 ** len(wires) - n_features)
190                 feature_set = qml.math.concatenate([feature_set, padding], axis=0)
191 
192             # normalize
193             norm = qml.math.sum(qml.math.abs(feature_set) ** 2)
194 
195             if qml.math.is_abstract(norm):
196                 if normalize or pad_with:
197                     feature_set = feature_set / qml.math.sqrt(norm)
198 
199             elif not qml.math.allclose(norm, 1.0, atol=TOLERANCE):
200                 if normalize or pad_with:
201                     feature_set = feature_set / qml.math.sqrt(norm)
202                 else:
203                     raise ValueError(
204                         f"Features must be a vector of norm 1.0; got norm {norm}."
205                         "Use 'normalize=True' to automatically normalize."
206                     )
207 
208             features_batch[i] = qml.math.cast(feature_set, np.complex128)
209 
210         return features_batch if batched else features_batch[0]
211
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pennylane/templates/embeddings/amplitude.py b/pennylane/templates/embeddings/amplitude.py
--- a/pennylane/templates/embeddings/amplitude.py
+++ b/pennylane/templates/embeddings/amplitude.py
@@ -205,6 +205,6 @@
                         "Use 'normalize=True' to automatically normalize."
                     )
 
-            features_batch[i] = qml.math.cast(feature_set, np.complex128)
+            features_batch[i] = feature_set
 
-        return features_batch if batched else features_batch[0]
+        return qml.math.cast(features_batch if batched else features_batch[0], np.complex128)

{"golden_diff": "diff --git a/pennylane/templates/embeddings/amplitude.py b/pennylane/templates/embeddings/amplitude.py\n--- a/pennylane/templates/embeddings/amplitude.py\n+++ b/pennylane/templates/embeddings/amplitude.py\n@@ -205,6 +205,6 @@\n                         \"Use 'normalize=True' to automatically normalize.\"\n                     )\n \n-            features_batch[i] = qml.math.cast(feature_set, np.complex128)\n+            features_batch[i] = feature_set\n \n-        return features_batch if batched else features_batch[0]\n+        return qml.math.cast(features_batch if batched else features_batch[0], np.complex128)\n", "issue": "Casting to complex in Amplitude Embedding\nIf I do not batch the parameters in `qml.AmplitudeEmbedding`, the parameter is preprocessed to be `np.compex128`:\r\n\r\n```\r\n>>> data = np.random.random(8)\r\n>>> op = qml.templates.AmplitudeEmbedding(data, wires=[0, 1, 2], normalize=True)\r\n>>> op.parameters\r\n[tensor([0.45477115+0.j, 0.01693656+0.j, 0.07562024+0.j, 0.54867405+0.j,\r\n         0.36355761+0.j, 0.50257082+0.j, 0.31384676+0.j, 0.05369689+0.j], requires_grad=True)]\r\n```\r\n\r\nBut if I add a batch dimension, an warning is raised:\r\n```\r\npennylane/pennylane/templates/embeddings/amplitude.py:208: ComplexWarning: Casting complex values to real discards the imaginary part\r\n```\r\n\r\nand the resulting parameters are purely real:\r\n\r\n```\r\n>>> batch_size = 5\r\n>>> data = np.random.random((batch_size, 8))\r\n>>> op = qml.templates.AmplitudeEmbedding(data, wires=[0, 1, 2], normalize=True)\r\n>>> op.parameters\r\n[tensor([[0.0016901 , 0.5075714 , 0.54801605, 0.03162948, 0.55714217,\r\n          0.20436995, 0.00293922, 0.29809946],\r\n         [0.3872195 , 0.22144908, 0.23615862, 0.18293768, 0.24939231,\r\n          0.34098754, 0.51028387, 0.52242283],\r\n         [0.3192768 , 0.30626548, 0.14370121, 0.5928348 , 0.12077899,\r\n          0.06004839, 0.05753843, 0.64082493],\r\n         [0.63251121, 0.02695029, 0.31892484, 0.29212886, 0.08482609,\r\n          0.29508076, 0.56160044, 0.04987735],\r\n         [0.01995247, 0.3879382 , 0.04970833, 0.36439654, 0.54700921,\r\n          0.41374685, 0.48902248, 0.06558638]], requires_grad=True)]\r\n```\r\n\r\nI came across this problem when trying to clean warnings from the transform tests, so it is not currently breaking anything, but I would consider it unexpected behaviour.\n", "before_files": [{"content": "# Copyright 2018-2021 Xanadu Quantum Technologies Inc.\n\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n\n#     http://www.apache.org/licenses/LICENSE-2.0\n\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nr\"\"\"\nContains the AmplitudeEmbedding template.\n\"\"\"\n# pylint: disable-msg=too-many-branches,too-many-arguments,protected-access\nimport numpy as np\n\nimport pennylane as qml\nfrom pennylane.operation import Operation, AnyWires\nfrom pennylane.ops import QubitStateVector\nfrom pennylane.wires import Wires\n\n# tolerance for normalization\nTOLERANCE = 1e-10\n\n\nclass AmplitudeEmbedding(Operation):\n    r\"\"\"Encodes :math:`2^n` features into the amplitude vector of :math:`n` qubits.\n\n    By setting ``pad_with`` to a real or complex number, ``features`` is automatically padded to dimension\n    :math:`2^n` where :math:`n` is the number of qubits used in the embedding.\n\n    To represent a valid quantum state vector, the L2-norm of ``features`` must be one.\n    The argument ``normalize`` can be set to ``True`` to automatically normalize the features.\n\n    If both automatic padding and normalization are used, padding is executed *before* normalizing.\n\n    .. note::\n\n        On some devices, ``AmplitudeEmbedding`` must be the first operation of a quantum circuit.\n\n    .. warning::\n\n        At the moment, the ``features`` argument is **not differentiable** when using the template, and\n        gradients with respect to the features cannot be computed by PennyLane.\n\n    Args:\n        features (tensor_like): input tensor of dimension ``(2^n,)``, or less if `pad_with` is specified\n        wires (Iterable): wires that the template acts on\n        pad_with (float or complex): if not None, the input is padded with this constant to size :math:`2^n`\n        normalize (bool): whether to automatically normalize the features\n\n    Example:\n\n        Amplitude embedding encodes a normalized :math:`2^n`-dimensional feature vector into the state\n        of :math:`n` qubits:\n\n        .. code-block:: python\n\n            import pennylane as qml\n\n            dev = qml.device('default.qubit', wires=2)\n\n            @qml.qnode(dev)\n            def circuit(f=None):\n                qml.AmplitudeEmbedding(features=f, wires=range(2))\n                return qml.expval(qml.PauliZ(0))\n\n            circuit(f=[1/2, 1/2, 1/2, 1/2])\n\n        The final state of the device is - up to a global phase - equivalent to the input passed to the circuit:\n\n        >>> dev.state\n        [0.5+0.j 0.5+0.j 0.5+0.j 0.5+0.j]\n\n        **Differentiating with respect to the features**\n\n        Due to non-trivial classical processing to construct the state preparation circuit,\n        the features argument is in general **not differentiable**.\n\n        **Normalization**\n\n        The template will raise an error if the feature input is not normalized.\n        One can set ``normalize=True`` to automatically normalize it:\n\n        .. code-block:: python\n\n            @qml.qnode(dev)\n            def circuit(f=None):\n                qml.AmplitudeEmbedding(features=f, wires=range(2), normalize=True)\n                return qml.expval(qml.PauliZ(0))\n\n            circuit(f=[15, 15, 15, 15])\n\n        >>> dev.state\n        [0.5 + 0.j, 0.5 + 0.j, 0.5 + 0.j, 0.5 + 0.j]\n\n        **Padding**\n\n        If the dimension of the feature vector is smaller than the number of amplitudes,\n        one can automatically pad it with a constant for the missing dimensions using the ``pad_with`` option:\n\n        .. code-block:: python\n\n            from math import sqrt\n\n            @qml.qnode(dev)\n            def circuit(f=None):\n                qml.AmplitudeEmbedding(features=f, wires=range(2), pad_with=0.)\n                return qml.expval(qml.PauliZ(0))\n\n            circuit(f=[1/sqrt(2), 1/sqrt(2)])\n\n        >>> dev.state\n        [0.70710678 + 0.j, 0.70710678 + 0.j, 0.0 + 0.j, 0.0 + 0.j]\n\n    \"\"\"\n\n    num_wires = AnyWires\n    grad_method = None\n\n    def __init__(self, features, wires, pad_with=None, normalize=False, do_queue=True, id=None):\n\n        wires = Wires(wires)\n        self.pad_with = pad_with\n        self.normalize = normalize\n\n        features = self._preprocess(features, wires, pad_with, normalize)\n        super().__init__(features, wires=wires, do_queue=do_queue, id=id)\n\n    @property\n    def num_params(self):\n        return 1\n\n    def adjoint(self):  # pylint: disable=arguments-differ\n        return qml.adjoint(qml.MottonenStatePreparation)(self.parameters[0], wires=self.wires)\n\n    def expand(self):\n\n        with qml.tape.QuantumTape() as tape:\n            QubitStateVector(self.parameters[0], wires=self.wires)\n\n        return tape\n\n    @staticmethod\n    def _preprocess(features, wires, pad_with, normalize):\n        \"\"\"Validate and pre-process inputs as follows:\n\n        * If features is batched, the processing that follows is applied to each feature set in the batch.\n        * Check that the features tensor is one-dimensional.\n        * If pad_with is None, check that the first dimension of the features tensor\n          has length :math:`2^n` where :math:`n` is the number of qubits. Else check that the\n          first dimension of the features tensor is not larger than :math:`2^n` and pad features\n          with value if necessary.\n        * If normalize is false, check that first dimension of features is normalised to one. Else, normalise the\n          features tensor.\n        \"\"\"\n\n        # check if features is batched\n        batched = len(qml.math.shape(features)) > 1\n\n        features_batch = features if batched else [features]\n\n        # apply pre-processing to each features tensor in the batch\n        for i, feature_set in enumerate(features_batch):\n            shape = qml.math.shape(feature_set)\n\n            # check shape\n            if len(shape) != 1:\n                raise ValueError(f\"Features must be a one-dimensional tensor; got shape {shape}.\")\n\n            n_features = shape[0]\n            if pad_with is None and n_features != 2 ** len(wires):\n                raise ValueError(\n                    f\"Features must be of length {2 ** len(wires)}; got length {n_features}. \"\n                    f\"Use the 'pad_with' argument for automated padding.\"\n                )\n\n            if pad_with is not None and n_features > 2 ** len(wires):\n                raise ValueError(\n                    f\"Features must be of length {2 ** len(wires)} or \"\n                    f\"smaller to be padded; got length {n_features}.\"\n                )\n\n            # pad\n            if pad_with is not None and n_features < 2 ** len(wires):\n                padding = [pad_with] * (2 ** len(wires) - n_features)\n                feature_set = qml.math.concatenate([feature_set, padding], axis=0)\n\n            # normalize\n            norm = qml.math.sum(qml.math.abs(feature_set) ** 2)\n\n            if qml.math.is_abstract(norm):\n                if normalize or pad_with:\n                    feature_set = feature_set / qml.math.sqrt(norm)\n\n            elif not qml.math.allclose(norm, 1.0, atol=TOLERANCE):\n                if normalize or pad_with:\n                    feature_set = feature_set / qml.math.sqrt(norm)\n                else:\n                    raise ValueError(\n                        f\"Features must be a vector of norm 1.0; got norm {norm}.\"\n                        \"Use 'normalize=True' to automatically normalize.\"\n                    )\n\n            features_batch[i] = qml.math.cast(feature_set, np.complex128)\n\n        return features_batch if batched else features_batch[0]\n", "path": "pennylane/templates/embeddings/amplitude.py"}], "after_files": [{"content": "# Copyright 2018-2021 Xanadu Quantum Technologies Inc.\n\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n\n#     http://www.apache.org/licenses/LICENSE-2.0\n\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nr\"\"\"\nContains the AmplitudeEmbedding template.\n\"\"\"\n# pylint: disable-msg=too-many-branches,too-many-arguments,protected-access\nimport numpy as np\n\nimport pennylane as qml\nfrom pennylane.operation import Operation, AnyWires\nfrom pennylane.ops import QubitStateVector\nfrom pennylane.wires import Wires\n\n# tolerance for normalization\nTOLERANCE = 1e-10\n\n\nclass AmplitudeEmbedding(Operation):\n    r\"\"\"Encodes :math:`2^n` features into the amplitude vector of :math:`n` qubits.\n\n    By setting ``pad_with`` to a real or complex number, ``features`` is automatically padded to dimension\n    :math:`2^n` where :math:`n` is the number of qubits used in the embedding.\n\n    To represent a valid quantum state vector, the L2-norm of ``features`` must be one.\n    The argument ``normalize`` can be set to ``True`` to automatically normalize the features.\n\n    If both automatic padding and normalization are used, padding is executed *before* normalizing.\n\n    .. note::\n\n        On some devices, ``AmplitudeEmbedding`` must be the first operation of a quantum circuit.\n\n    .. warning::\n\n        At the moment, the ``features`` argument is **not differentiable** when using the template, and\n        gradients with respect to the features cannot be computed by PennyLane.\n\n    Args:\n        features (tensor_like): input tensor of dimension ``(2^n,)``, or less if `pad_with` is specified\n        wires (Iterable): wires that the template acts on\n        pad_with (float or complex): if not None, the input is padded with this constant to size :math:`2^n`\n        normalize (bool): whether to automatically normalize the features\n\n    Example:\n\n        Amplitude embedding encodes a normalized :math:`2^n`-dimensional feature vector into the state\n        of :math:`n` qubits:\n\n        .. code-block:: python\n\n            import pennylane as qml\n\n            dev = qml.device('default.qubit', wires=2)\n\n            @qml.qnode(dev)\n            def circuit(f=None):\n                qml.AmplitudeEmbedding(features=f, wires=range(2))\n                return qml.expval(qml.PauliZ(0))\n\n            circuit(f=[1/2, 1/2, 1/2, 1/2])\n\n        The final state of the device is - up to a global phase - equivalent to the input passed to the circuit:\n\n        >>> dev.state\n        [0.5+0.j 0.5+0.j 0.5+0.j 0.5+0.j]\n\n        **Differentiating with respect to the features**\n\n        Due to non-trivial classical processing to construct the state preparation circuit,\n        the features argument is in general **not differentiable**.\n\n        **Normalization**\n\n        The template will raise an error if the feature input is not normalized.\n        One can set ``normalize=True`` to automatically normalize it:\n\n        .. code-block:: python\n\n            @qml.qnode(dev)\n            def circuit(f=None):\n                qml.AmplitudeEmbedding(features=f, wires=range(2), normalize=True)\n                return qml.expval(qml.PauliZ(0))\n\n            circuit(f=[15, 15, 15, 15])\n\n        >>> dev.state\n        [0.5 + 0.j, 0.5 + 0.j, 0.5 + 0.j, 0.5 + 0.j]\n\n        **Padding**\n\n        If the dimension of the feature vector is smaller than the number of amplitudes,\n        one can automatically pad it with a constant for the missing dimensions using the ``pad_with`` option:\n\n        .. code-block:: python\n\n            from math import sqrt\n\n            @qml.qnode(dev)\n            def circuit(f=None):\n                qml.AmplitudeEmbedding(features=f, wires=range(2), pad_with=0.)\n                return qml.expval(qml.PauliZ(0))\n\n            circuit(f=[1/sqrt(2), 1/sqrt(2)])\n\n        >>> dev.state\n        [0.70710678 + 0.j, 0.70710678 + 0.j, 0.0 + 0.j, 0.0 + 0.j]\n\n    \"\"\"\n\n    num_wires = AnyWires\n    grad_method = None\n\n    def __init__(self, features, wires, pad_with=None, normalize=False, do_queue=True, id=None):\n\n        wires = Wires(wires)\n        self.pad_with = pad_with\n        self.normalize = normalize\n\n        features = self._preprocess(features, wires, pad_with, normalize)\n        super().__init__(features, wires=wires, do_queue=do_queue, id=id)\n\n    @property\n    def num_params(self):\n        return 1\n\n    def adjoint(self):  # pylint: disable=arguments-differ\n        return qml.adjoint(qml.MottonenStatePreparation)(self.parameters[0], wires=self.wires)\n\n    def expand(self):\n\n        with qml.tape.QuantumTape() as tape:\n            QubitStateVector(self.parameters[0], wires=self.wires)\n\n        return tape\n\n    @staticmethod\n    def _preprocess(features, wires, pad_with, normalize):\n        \"\"\"Validate and pre-process inputs as follows:\n\n        * If features is batched, the processing that follows is applied to each feature set in the batch.\n        * Check that the features tensor is one-dimensional.\n        * If pad_with is None, check that the first dimension of the features tensor\n          has length :math:`2^n` where :math:`n` is the number of qubits. Else check that the\n          first dimension of the features tensor is not larger than :math:`2^n` and pad features\n          with value if necessary.\n        * If normalize is false, check that first dimension of features is normalised to one. Else, normalise the\n          features tensor.\n        \"\"\"\n\n        # check if features is batched\n        batched = len(qml.math.shape(features)) > 1\n\n        features_batch = features if batched else [features]\n\n        # apply pre-processing to each features tensor in the batch\n        for i, feature_set in enumerate(features_batch):\n            shape = qml.math.shape(feature_set)\n\n            # check shape\n            if len(shape) != 1:\n                raise ValueError(f\"Features must be a one-dimensional tensor; got shape {shape}.\")\n\n            n_features = shape[0]\n            if pad_with is None and n_features != 2 ** len(wires):\n                raise ValueError(\n                    f\"Features must be of length {2 ** len(wires)}; got length {n_features}. \"\n                    f\"Use the 'pad_with' argument for automated padding.\"\n                )\n\n            if pad_with is not None and n_features > 2 ** len(wires):\n                raise ValueError(\n                    f\"Features must be of length {2 ** len(wires)} or \"\n                    f\"smaller to be padded; got length {n_features}.\"\n                )\n\n            # pad\n            if pad_with is not None and n_features < 2 ** len(wires):\n                padding = [pad_with] * (2 ** len(wires) - n_features)\n                feature_set = qml.math.concatenate([feature_set, padding], axis=0)\n\n            # normalize\n            norm = qml.math.sum(qml.math.abs(feature_set) ** 2)\n\n            if qml.math.is_abstract(norm):\n                if normalize or pad_with:\n                    feature_set = feature_set / qml.math.sqrt(norm)\n\n            elif not qml.math.allclose(norm, 1.0, atol=TOLERANCE):\n                if normalize or pad_with:\n                    feature_set = feature_set / qml.math.sqrt(norm)\n                else:\n                    raise ValueError(\n                        f\"Features must be a vector of norm 1.0; got norm {norm}.\"\n                        \"Use 'normalize=True' to automatically normalize.\"\n                    )\n\n            features_batch[i] = feature_set\n\n        return qml.math.cast(features_batch if batched else features_batch[0], np.complex128)\n", "path": "pennylane/templates/embeddings/amplitude.py"}]}