We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Issue when using batched data on StronglyEntanglingLayers template.[BUG]
### Expected behavior

I want to use the StronglyEntanglingLayers template to process batched data. the shape of the data is like [batch_size, layers, wires, 3]. 

### Actual behavior

Some errors happened: 
```
.../pennylane/templates/layers/strongly_entangling.py", line 209, in compute_decomposition
    weights[..., l, i, 0],
IndexError: index 10 is out of bounds for dimension 1 with size 10
```

### Additional information

I check the strongly_entangling.py and find this bug may comes from this code:
```
201 line:  n_layers = qml.math.shape(weights)[0]
```

the correct code may be 

```
201 line:  n_layers = qml.math.shape(weights)[-3]
```

### Source code

_No response_

### Tracebacks

_No response_

### System information

```shell
I run pennylane on the server, and the bug I think is not related to the system.
```


### Existing GitHub issues

- [X] I have searched existing GitHub issues to make sure the issue does not already exist.

--- 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/layers/strongly_entangling.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 StronglyEntanglingLayers template.
16 """
17 # pylint: disable-msg=too-many-branches,too-many-arguments,protected-access
18 import pennylane as qml
19 from pennylane.operation import AnyWires, Operation
20 
21 
22 class StronglyEntanglingLayers(Operation):
23     r"""Layers consisting of single qubit rotations and entanglers, inspired by the circuit-centric classifier design
24     `arXiv:1804.00633 <https://arxiv.org/abs/1804.00633>`_.
25 
26     The argument ``weights`` contains the weights for each layer. The number of layers :math:`L` is therefore derived
27     from the first dimension of ``weights``.
28 
29     The 2-qubit gates, whose type is specified by the ``imprimitive`` argument,
30     act chronologically on the :math:`M` wires, :math:`i = 1,...,M`. The second qubit of each gate is given by
31     :math:`(i+r)\mod M`, where :math:`r` is a  hyperparameter called the *range*, and :math:`0 < r < M`.
32     If applied to one qubit only, this template will use no imprimitive gates.
33 
34     This is an example of two 4-qubit strongly entangling layers (ranges :math:`r=1` and :math:`r=2`, respectively) with
35     rotations :math:`R` and CNOTs as imprimitives:
36 
37     .. figure:: ../../_static/layer_sec.png
38         :align: center
39         :width: 60%
40         :target: javascript:void(0);
41 
42     .. note::
43         The two-qubit gate used as the imprimitive or entangler must not depend on parameters.
44 
45     Args:
46 
47         weights (tensor_like): weight tensor of shape ``(L, M, 3)``
48         wires (Iterable): wires that the template acts on
49         ranges (Sequence[int]): sequence determining the range hyperparameter for each subsequent layer; if ``None``
50                                 using :math:`r=l \mod M` for the :math:`l` th layer and :math:`M` wires.
51         imprimitive (type of pennylane.ops.Operation): two-qubit gate to use, defaults to :class:`~pennylane.ops.CNOT`
52 
53     Example:
54 
55         There are multiple arguments that the user can use to customize the layer.
56 
57         The required arguments are ``weights`` and ``wires``.
58 
59         .. code-block:: python
60 
61             dev = qml.device('default.qubit', wires=4)
62 
63             @qml.qnode(dev)
64             def circuit(parameters):
65                 qml.StronglyEntanglingLayers(weights=parameters, wires=range(4))
66                 return qml.expval(qml.Z(0))
67 
68             shape = qml.StronglyEntanglingLayers.shape(n_layers=2, n_wires=4)
69             weights = np.random.random(size=shape)
70 
71         The shape of the ``weights`` argument decides the number of layers.
72 
73         The resulting circuit is:
74 
75         >>> print(qml.draw(circuit, expansion_strategy="device")(weights))
76         0: ──Rot(0.68,0.98,0.48)─╭●───────╭X──Rot(0.94,0.22,0.70)─╭●────╭X────┤  <Z>
77         1: ──Rot(0.91,0.19,0.15)─╰X─╭●────│───Rot(0.50,0.20,0.63)─│──╭●─│──╭X─┤
78         2: ──Rot(0.91,0.68,0.96)────╰X─╭●─│───Rot(0.14,0.05,0.16)─╰X─│──╰●─│──┤
79         3: ──Rot(0.46,0.56,0.80)───────╰X─╰●──Rot(0.87,0.04,0.22)────╰X────╰●─┤
80 
81         The default two-qubit gate used is :class:`~pennylane.ops.CNOT`. This can be changed by using the ``imprimitive`` argument.
82 
83         The ``ranges`` argument takes an integer sequence where each element
84         determines the range hyperparameter for each layer. This range hyperparameter
85         is the difference of the wire indices representing the two qubits the
86         ``imprimitive`` gate acts on. For example, for ``range=[2,3]`` the
87         first layer will have a range parameter of ``2`` and the second layer will
88         have a range parameter of ``3``.
89         Assuming ``wires=[0, 1, 2, 3]`` and a range parameter of ``2``, there will be
90         an imprimitive gate acting on:
91 
92         * qubits ``(0, 2)``;
93         * qubits ``(1, 3)``;
94         * qubits ``(2, 0)``;
95         * qubits ``(3, 1)``.
96 
97         .. code-block:: python
98 
99             dev = qml.device('default.qubit', wires=4)
100 
101             @qml.qnode(dev)
102             def circuit(parameters):
103                 qml.StronglyEntanglingLayers(weights=parameters, wires=range(4), ranges=[2, 3], imprimitive=qml.ops.CZ)
104                 return qml.expval(qml.Z(0))
105 
106             shape = qml.StronglyEntanglingLayers.shape(n_layers=2, n_wires=4)
107             weights = np.random.random(size=shape)
108 
109         The resulting circuit is:
110 
111         >>> print(qml.draw(circuit, expansion_strategy="device")(weights))
112         0: ──Rot(0.99,0.17,0.12)─╭●────╭Z──Rot(0.02,0.94,0.57)──────────────────────╭●─╭Z───────┤  <Z>
113         1: ──Rot(0.55,0.42,0.61)─│──╭●─│──╭Z────────────────────Rot(0.15,0.26,0.82)─│──╰●─╭Z────┤
114         2: ──Rot(0.79,0.93,0.27)─╰Z─│──╰●─│─────────────────────Rot(0.73,0.01,0.44)─│─────╰●─╭Z─┤
115         3: ──Rot(0.30,0.74,0.93)────╰Z────╰●────────────────────Rot(0.57,0.50,0.80)─╰Z───────╰●─┤
116 
117     .. details::
118         :title: Usage Details
119 
120         **Parameter shape**
121 
122         The expected shape for the weight tensor can be computed with the static method
123         :meth:`~.qml.StronglyEntanglingLayers.shape` and used when creating randomly
124         initialised weight tensors:
125 
126         .. code-block:: python
127 
128             shape = qml.StronglyEntanglingLayers.shape(n_layers=2, n_wires=2)
129             weights = np.random.random(size=shape)
130 
131     """
132 
133     num_wires = AnyWires
134     grad_method = None
135 
136     def __init__(self, weights, wires, ranges=None, imprimitive=None, id=None):
137         shape = qml.math.shape(weights)[-3:]
138 
139         if shape[1] != len(wires):
140             raise ValueError(
141                 f"Weights tensor must have second dimension of length {len(wires)}; got {shape[1]}"
142             )
143 
144         if shape[2] != 3:
145             raise ValueError(
146                 f"Weights tensor must have third dimension of length 3; got {shape[2]}"
147             )
148 
149         if ranges is None:
150             if len(wires) > 1:
151                 # tile ranges with iterations of range(1, n_wires)
152                 ranges = tuple((l % (len(wires) - 1)) + 1 for l in range(shape[0]))
153             else:
154                 ranges = (0,) * shape[0]
155         else:
156             ranges = tuple(ranges)
157             if len(ranges) != shape[0]:
158                 raise ValueError(f"Range sequence must be of length {shape[0]}; got {len(ranges)}")
159             for r in ranges:
160                 if r % len(wires) == 0:
161                     raise ValueError(
162                         f"Ranges must not be zero nor divisible by the number of wires; got {r}"
163                     )
164 
165         self._hyperparameters = {"ranges": ranges, "imprimitive": imprimitive or qml.CNOT}
166 
167         super().__init__(weights, wires=wires, id=id)
168 
169     @property
170     def num_params(self):
171         return 1
172 
173     @staticmethod
174     def compute_decomposition(
175         weights, wires, ranges, imprimitive
176     ):  # pylint: disable=arguments-differ
177         r"""Representation of the operator as a product of other operators.
178 
179         .. math:: O = O_1 O_2 \dots O_n.
180 
181 
182 
183         .. seealso:: :meth:`~.StronglyEntanglingLayers.decomposition`.
184 
185         Args:
186             weights (tensor_like): weight tensor
187             wires (Any or Iterable[Any]): wires that the operator acts on
188             ranges (Sequence[int]): sequence determining the range hyperparameter for each subsequent layer
189             imprimitive (pennylane.ops.Operation): two-qubit gate to use
190 
191         Returns:
192             list[.Operator]: decomposition of the operator
193 
194         **Example**
195 
196         >>> weights = torch.tensor([[-0.2, 0.1, -0.4], [1.2, -2., -0.4]])
197         >>> qml.StronglyEntanglingLayers.compute_decomposition(weights, wires=["a", "b"], ranges=[2], imprimitive=qml.CNOT)
198         [Rot(tensor(-0.2000), tensor(0.1000), tensor(-0.4000), wires=['a']),
199         Rot(tensor(1.2000), tensor(-2.), tensor(-0.4000), wires=['b']),
200         CNOT(wires=['a', 'a']),
201         CNOT(wires=['b', 'b'])]
202         """
203         n_layers = qml.math.shape(weights)[0]
204         wires = qml.wires.Wires(wires)
205         op_list = []
206 
207         for l in range(n_layers):
208             for i in range(len(wires)):  # pylint: disable=consider-using-enumerate
209                 op_list.append(
210                     qml.Rot(
211                         weights[..., l, i, 0],
212                         weights[..., l, i, 1],
213                         weights[..., l, i, 2],
214                         wires=wires[i],
215                     )
216                 )
217 
218             if len(wires) > 1:
219                 for i in range(len(wires)):
220                     act_on = wires.subset([i, i + ranges[l]], periodic_boundary=True)
221                     op_list.append(imprimitive(wires=act_on))
222 
223         return op_list
224 
225     @staticmethod
226     def shape(n_layers, n_wires):
227         r"""Returns the expected shape of the weights tensor.
228 
229         Args:
230             n_layers (int): number of layers
231             n_wires (int): number of wires
232 
233         Returns:
234             tuple[int]: shape
235         """
236 
237         return n_layers, n_wires, 3
238
```
--- 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/layers/strongly_entangling.py b/pennylane/templates/layers/strongly_entangling.py
--- a/pennylane/templates/layers/strongly_entangling.py
+++ b/pennylane/templates/layers/strongly_entangling.py
@@ -200,7 +200,7 @@
         CNOT(wires=['a', 'a']),
         CNOT(wires=['b', 'b'])]
         """
-        n_layers = qml.math.shape(weights)[0]
+        n_layers = qml.math.shape(weights)[-3]
         wires = qml.wires.Wires(wires)
         op_list = []

{"golden_diff": "diff --git a/pennylane/templates/layers/strongly_entangling.py b/pennylane/templates/layers/strongly_entangling.py\n--- a/pennylane/templates/layers/strongly_entangling.py\n+++ b/pennylane/templates/layers/strongly_entangling.py\n@@ -200,7 +200,7 @@\n         CNOT(wires=['a', 'a']),\n         CNOT(wires=['b', 'b'])]\n         \"\"\"\n-        n_layers = qml.math.shape(weights)[0]\n+        n_layers = qml.math.shape(weights)[-3]\n         wires = qml.wires.Wires(wires)\n         op_list = []\n", "issue": "Issue when using batched data on StronglyEntanglingLayers template.[BUG]\n### Expected behavior\n\nI want to use the StronglyEntanglingLayers template to process batched data. the shape of the data is like [batch_size, layers, wires, 3]. \n\n### Actual behavior\n\nSome errors happened: \r\n```\r\n.../pennylane/templates/layers/strongly_entangling.py\", line 209, in compute_decomposition\r\n    weights[..., l, i, 0],\r\nIndexError: index 10 is out of bounds for dimension 1 with size 10\r\n```\n\n### Additional information\n\nI check the strongly_entangling.py and find this bug may comes from this code:\r\n```\r\n201 line:  n_layers = qml.math.shape(weights)[0]\r\n```\r\n\r\nthe correct code may be \r\n\r\n```\r\n201 line:  n_layers = qml.math.shape(weights)[-3]\r\n```\n\n### Source code\n\n_No response_\n\n### Tracebacks\n\n_No response_\n\n### System information\n\n```shell\nI run pennylane on the server, and the bug I think is not related to the system.\n```\n\n\n### Existing GitHub issues\n\n- [X] I have searched existing GitHub issues to make sure the issue does not already exist.\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 StronglyEntanglingLayers template.\n\"\"\"\n# pylint: disable-msg=too-many-branches,too-many-arguments,protected-access\nimport pennylane as qml\nfrom pennylane.operation import AnyWires, Operation\n\n\nclass StronglyEntanglingLayers(Operation):\n    r\"\"\"Layers consisting of single qubit rotations and entanglers, inspired by the circuit-centric classifier design\n    `arXiv:1804.00633 <https://arxiv.org/abs/1804.00633>`_.\n\n    The argument ``weights`` contains the weights for each layer. The number of layers :math:`L` is therefore derived\n    from the first dimension of ``weights``.\n\n    The 2-qubit gates, whose type is specified by the ``imprimitive`` argument,\n    act chronologically on the :math:`M` wires, :math:`i = 1,...,M`. The second qubit of each gate is given by\n    :math:`(i+r)\\mod M`, where :math:`r` is a  hyperparameter called the *range*, and :math:`0 < r < M`.\n    If applied to one qubit only, this template will use no imprimitive gates.\n\n    This is an example of two 4-qubit strongly entangling layers (ranges :math:`r=1` and :math:`r=2`, respectively) with\n    rotations :math:`R` and CNOTs as imprimitives:\n\n    .. figure:: ../../_static/layer_sec.png\n        :align: center\n        :width: 60%\n        :target: javascript:void(0);\n\n    .. note::\n        The two-qubit gate used as the imprimitive or entangler must not depend on parameters.\n\n    Args:\n\n        weights (tensor_like): weight tensor of shape ``(L, M, 3)``\n        wires (Iterable): wires that the template acts on\n        ranges (Sequence[int]): sequence determining the range hyperparameter for each subsequent layer; if ``None``\n                                using :math:`r=l \\mod M` for the :math:`l` th layer and :math:`M` wires.\n        imprimitive (type of pennylane.ops.Operation): two-qubit gate to use, defaults to :class:`~pennylane.ops.CNOT`\n\n    Example:\n\n        There are multiple arguments that the user can use to customize the layer.\n\n        The required arguments are ``weights`` and ``wires``.\n\n        .. code-block:: python\n\n            dev = qml.device('default.qubit', wires=4)\n\n            @qml.qnode(dev)\n            def circuit(parameters):\n                qml.StronglyEntanglingLayers(weights=parameters, wires=range(4))\n                return qml.expval(qml.Z(0))\n\n            shape = qml.StronglyEntanglingLayers.shape(n_layers=2, n_wires=4)\n            weights = np.random.random(size=shape)\n\n        The shape of the ``weights`` argument decides the number of layers.\n\n        The resulting circuit is:\n\n        >>> print(qml.draw(circuit, expansion_strategy=\"device\")(weights))\n        0: \u2500\u2500Rot(0.68,0.98,0.48)\u2500\u256d\u25cf\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256dX\u2500\u2500Rot(0.94,0.22,0.70)\u2500\u256d\u25cf\u2500\u2500\u2500\u2500\u256dX\u2500\u2500\u2500\u2500\u2524  <Z>\n        1: \u2500\u2500Rot(0.91,0.19,0.15)\u2500\u2570X\u2500\u256d\u25cf\u2500\u2500\u2500\u2500\u2502\u2500\u2500\u2500Rot(0.50,0.20,0.63)\u2500\u2502\u2500\u2500\u256d\u25cf\u2500\u2502\u2500\u2500\u256dX\u2500\u2524\n        2: \u2500\u2500Rot(0.91,0.68,0.96)\u2500\u2500\u2500\u2500\u2570X\u2500\u256d\u25cf\u2500\u2502\u2500\u2500\u2500Rot(0.14,0.05,0.16)\u2500\u2570X\u2500\u2502\u2500\u2500\u2570\u25cf\u2500\u2502\u2500\u2500\u2524\n        3: \u2500\u2500Rot(0.46,0.56,0.80)\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2570X\u2500\u2570\u25cf\u2500\u2500Rot(0.87,0.04,0.22)\u2500\u2500\u2500\u2500\u2570X\u2500\u2500\u2500\u2500\u2570\u25cf\u2500\u2524\n\n        The default two-qubit gate used is :class:`~pennylane.ops.CNOT`. This can be changed by using the ``imprimitive`` argument.\n\n        The ``ranges`` argument takes an integer sequence where each element\n        determines the range hyperparameter for each layer. This range hyperparameter\n        is the difference of the wire indices representing the two qubits the\n        ``imprimitive`` gate acts on. For example, for ``range=[2,3]`` the\n        first layer will have a range parameter of ``2`` and the second layer will\n        have a range parameter of ``3``.\n        Assuming ``wires=[0, 1, 2, 3]`` and a range parameter of ``2``, there will be\n        an imprimitive gate acting on:\n\n        * qubits ``(0, 2)``;\n        * qubits ``(1, 3)``;\n        * qubits ``(2, 0)``;\n        * qubits ``(3, 1)``.\n\n        .. code-block:: python\n\n            dev = qml.device('default.qubit', wires=4)\n\n            @qml.qnode(dev)\n            def circuit(parameters):\n                qml.StronglyEntanglingLayers(weights=parameters, wires=range(4), ranges=[2, 3], imprimitive=qml.ops.CZ)\n                return qml.expval(qml.Z(0))\n\n            shape = qml.StronglyEntanglingLayers.shape(n_layers=2, n_wires=4)\n            weights = np.random.random(size=shape)\n\n        The resulting circuit is:\n\n        >>> print(qml.draw(circuit, expansion_strategy=\"device\")(weights))\n        0: \u2500\u2500Rot(0.99,0.17,0.12)\u2500\u256d\u25cf\u2500\u2500\u2500\u2500\u256dZ\u2500\u2500Rot(0.02,0.94,0.57)\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256d\u25cf\u2500\u256dZ\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524  <Z>\n        1: \u2500\u2500Rot(0.55,0.42,0.61)\u2500\u2502\u2500\u2500\u256d\u25cf\u2500\u2502\u2500\u2500\u256dZ\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500Rot(0.15,0.26,0.82)\u2500\u2502\u2500\u2500\u2570\u25cf\u2500\u256dZ\u2500\u2500\u2500\u2500\u2524\n        2: \u2500\u2500Rot(0.79,0.93,0.27)\u2500\u2570Z\u2500\u2502\u2500\u2500\u2570\u25cf\u2500\u2502\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500Rot(0.73,0.01,0.44)\u2500\u2502\u2500\u2500\u2500\u2500\u2500\u2570\u25cf\u2500\u256dZ\u2500\u2524\n        3: \u2500\u2500Rot(0.30,0.74,0.93)\u2500\u2500\u2500\u2500\u2570Z\u2500\u2500\u2500\u2500\u2570\u25cf\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500Rot(0.57,0.50,0.80)\u2500\u2570Z\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2570\u25cf\u2500\u2524\n\n    .. details::\n        :title: Usage Details\n\n        **Parameter shape**\n\n        The expected shape for the weight tensor can be computed with the static method\n        :meth:`~.qml.StronglyEntanglingLayers.shape` and used when creating randomly\n        initialised weight tensors:\n\n        .. code-block:: python\n\n            shape = qml.StronglyEntanglingLayers.shape(n_layers=2, n_wires=2)\n            weights = np.random.random(size=shape)\n\n    \"\"\"\n\n    num_wires = AnyWires\n    grad_method = None\n\n    def __init__(self, weights, wires, ranges=None, imprimitive=None, id=None):\n        shape = qml.math.shape(weights)[-3:]\n\n        if shape[1] != len(wires):\n            raise ValueError(\n                f\"Weights tensor must have second dimension of length {len(wires)}; got {shape[1]}\"\n            )\n\n        if shape[2] != 3:\n            raise ValueError(\n                f\"Weights tensor must have third dimension of length 3; got {shape[2]}\"\n            )\n\n        if ranges is None:\n            if len(wires) > 1:\n                # tile ranges with iterations of range(1, n_wires)\n                ranges = tuple((l % (len(wires) - 1)) + 1 for l in range(shape[0]))\n            else:\n                ranges = (0,) * shape[0]\n        else:\n            ranges = tuple(ranges)\n            if len(ranges) != shape[0]:\n                raise ValueError(f\"Range sequence must be of length {shape[0]}; got {len(ranges)}\")\n            for r in ranges:\n                if r % len(wires) == 0:\n                    raise ValueError(\n                        f\"Ranges must not be zero nor divisible by the number of wires; got {r}\"\n                    )\n\n        self._hyperparameters = {\"ranges\": ranges, \"imprimitive\": imprimitive or qml.CNOT}\n\n        super().__init__(weights, wires=wires, id=id)\n\n    @property\n    def num_params(self):\n        return 1\n\n    @staticmethod\n    def compute_decomposition(\n        weights, wires, ranges, imprimitive\n    ):  # pylint: disable=arguments-differ\n        r\"\"\"Representation of the operator as a product of other operators.\n\n        .. math:: O = O_1 O_2 \\dots O_n.\n\n\n\n        .. seealso:: :meth:`~.StronglyEntanglingLayers.decomposition`.\n\n        Args:\n            weights (tensor_like): weight tensor\n            wires (Any or Iterable[Any]): wires that the operator acts on\n            ranges (Sequence[int]): sequence determining the range hyperparameter for each subsequent layer\n            imprimitive (pennylane.ops.Operation): two-qubit gate to use\n\n        Returns:\n            list[.Operator]: decomposition of the operator\n\n        **Example**\n\n        >>> weights = torch.tensor([[-0.2, 0.1, -0.4], [1.2, -2., -0.4]])\n        >>> qml.StronglyEntanglingLayers.compute_decomposition(weights, wires=[\"a\", \"b\"], ranges=[2], imprimitive=qml.CNOT)\n        [Rot(tensor(-0.2000), tensor(0.1000), tensor(-0.4000), wires=['a']),\n        Rot(tensor(1.2000), tensor(-2.), tensor(-0.4000), wires=['b']),\n        CNOT(wires=['a', 'a']),\n        CNOT(wires=['b', 'b'])]\n        \"\"\"\n        n_layers = qml.math.shape(weights)[0]\n        wires = qml.wires.Wires(wires)\n        op_list = []\n\n        for l in range(n_layers):\n            for i in range(len(wires)):  # pylint: disable=consider-using-enumerate\n                op_list.append(\n                    qml.Rot(\n                        weights[..., l, i, 0],\n                        weights[..., l, i, 1],\n                        weights[..., l, i, 2],\n                        wires=wires[i],\n                    )\n                )\n\n            if len(wires) > 1:\n                for i in range(len(wires)):\n                    act_on = wires.subset([i, i + ranges[l]], periodic_boundary=True)\n                    op_list.append(imprimitive(wires=act_on))\n\n        return op_list\n\n    @staticmethod\n    def shape(n_layers, n_wires):\n        r\"\"\"Returns the expected shape of the weights tensor.\n\n        Args:\n            n_layers (int): number of layers\n            n_wires (int): number of wires\n\n        Returns:\n            tuple[int]: shape\n        \"\"\"\n\n        return n_layers, n_wires, 3\n", "path": "pennylane/templates/layers/strongly_entangling.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 StronglyEntanglingLayers template.\n\"\"\"\n# pylint: disable-msg=too-many-branches,too-many-arguments,protected-access\nimport pennylane as qml\nfrom pennylane.operation import AnyWires, Operation\n\n\nclass StronglyEntanglingLayers(Operation):\n    r\"\"\"Layers consisting of single qubit rotations and entanglers, inspired by the circuit-centric classifier design\n    `arXiv:1804.00633 <https://arxiv.org/abs/1804.00633>`_.\n\n    The argument ``weights`` contains the weights for each layer. The number of layers :math:`L` is therefore derived\n    from the first dimension of ``weights``.\n\n    The 2-qubit gates, whose type is specified by the ``imprimitive`` argument,\n    act chronologically on the :math:`M` wires, :math:`i = 1,...,M`. The second qubit of each gate is given by\n    :math:`(i+r)\\mod M`, where :math:`r` is a  hyperparameter called the *range*, and :math:`0 < r < M`.\n    If applied to one qubit only, this template will use no imprimitive gates.\n\n    This is an example of two 4-qubit strongly entangling layers (ranges :math:`r=1` and :math:`r=2`, respectively) with\n    rotations :math:`R` and CNOTs as imprimitives:\n\n    .. figure:: ../../_static/layer_sec.png\n        :align: center\n        :width: 60%\n        :target: javascript:void(0);\n\n    .. note::\n        The two-qubit gate used as the imprimitive or entangler must not depend on parameters.\n\n    Args:\n\n        weights (tensor_like): weight tensor of shape ``(L, M, 3)``\n        wires (Iterable): wires that the template acts on\n        ranges (Sequence[int]): sequence determining the range hyperparameter for each subsequent layer; if ``None``\n                                using :math:`r=l \\mod M` for the :math:`l` th layer and :math:`M` wires.\n        imprimitive (type of pennylane.ops.Operation): two-qubit gate to use, defaults to :class:`~pennylane.ops.CNOT`\n\n    Example:\n\n        There are multiple arguments that the user can use to customize the layer.\n\n        The required arguments are ``weights`` and ``wires``.\n\n        .. code-block:: python\n\n            dev = qml.device('default.qubit', wires=4)\n\n            @qml.qnode(dev)\n            def circuit(parameters):\n                qml.StronglyEntanglingLayers(weights=parameters, wires=range(4))\n                return qml.expval(qml.Z(0))\n\n            shape = qml.StronglyEntanglingLayers.shape(n_layers=2, n_wires=4)\n            weights = np.random.random(size=shape)\n\n        The shape of the ``weights`` argument decides the number of layers.\n\n        The resulting circuit is:\n\n        >>> print(qml.draw(circuit, expansion_strategy=\"device\")(weights))\n        0: \u2500\u2500Rot(0.68,0.98,0.48)\u2500\u256d\u25cf\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256dX\u2500\u2500Rot(0.94,0.22,0.70)\u2500\u256d\u25cf\u2500\u2500\u2500\u2500\u256dX\u2500\u2500\u2500\u2500\u2524  <Z>\n        1: \u2500\u2500Rot(0.91,0.19,0.15)\u2500\u2570X\u2500\u256d\u25cf\u2500\u2500\u2500\u2500\u2502\u2500\u2500\u2500Rot(0.50,0.20,0.63)\u2500\u2502\u2500\u2500\u256d\u25cf\u2500\u2502\u2500\u2500\u256dX\u2500\u2524\n        2: \u2500\u2500Rot(0.91,0.68,0.96)\u2500\u2500\u2500\u2500\u2570X\u2500\u256d\u25cf\u2500\u2502\u2500\u2500\u2500Rot(0.14,0.05,0.16)\u2500\u2570X\u2500\u2502\u2500\u2500\u2570\u25cf\u2500\u2502\u2500\u2500\u2524\n        3: \u2500\u2500Rot(0.46,0.56,0.80)\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2570X\u2500\u2570\u25cf\u2500\u2500Rot(0.87,0.04,0.22)\u2500\u2500\u2500\u2500\u2570X\u2500\u2500\u2500\u2500\u2570\u25cf\u2500\u2524\n\n        The default two-qubit gate used is :class:`~pennylane.ops.CNOT`. This can be changed by using the ``imprimitive`` argument.\n\n        The ``ranges`` argument takes an integer sequence where each element\n        determines the range hyperparameter for each layer. This range hyperparameter\n        is the difference of the wire indices representing the two qubits the\n        ``imprimitive`` gate acts on. For example, for ``range=[2,3]`` the\n        first layer will have a range parameter of ``2`` and the second layer will\n        have a range parameter of ``3``.\n        Assuming ``wires=[0, 1, 2, 3]`` and a range parameter of ``2``, there will be\n        an imprimitive gate acting on:\n\n        * qubits ``(0, 2)``;\n        * qubits ``(1, 3)``;\n        * qubits ``(2, 0)``;\n        * qubits ``(3, 1)``.\n\n        .. code-block:: python\n\n            dev = qml.device('default.qubit', wires=4)\n\n            @qml.qnode(dev)\n            def circuit(parameters):\n                qml.StronglyEntanglingLayers(weights=parameters, wires=range(4), ranges=[2, 3], imprimitive=qml.ops.CZ)\n                return qml.expval(qml.Z(0))\n\n            shape = qml.StronglyEntanglingLayers.shape(n_layers=2, n_wires=4)\n            weights = np.random.random(size=shape)\n\n        The resulting circuit is:\n\n        >>> print(qml.draw(circuit, expansion_strategy=\"device\")(weights))\n        0: \u2500\u2500Rot(0.99,0.17,0.12)\u2500\u256d\u25cf\u2500\u2500\u2500\u2500\u256dZ\u2500\u2500Rot(0.02,0.94,0.57)\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256d\u25cf\u2500\u256dZ\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524  <Z>\n        1: \u2500\u2500Rot(0.55,0.42,0.61)\u2500\u2502\u2500\u2500\u256d\u25cf\u2500\u2502\u2500\u2500\u256dZ\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500Rot(0.15,0.26,0.82)\u2500\u2502\u2500\u2500\u2570\u25cf\u2500\u256dZ\u2500\u2500\u2500\u2500\u2524\n        2: \u2500\u2500Rot(0.79,0.93,0.27)\u2500\u2570Z\u2500\u2502\u2500\u2500\u2570\u25cf\u2500\u2502\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500Rot(0.73,0.01,0.44)\u2500\u2502\u2500\u2500\u2500\u2500\u2500\u2570\u25cf\u2500\u256dZ\u2500\u2524\n        3: \u2500\u2500Rot(0.30,0.74,0.93)\u2500\u2500\u2500\u2500\u2570Z\u2500\u2500\u2500\u2500\u2570\u25cf\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500Rot(0.57,0.50,0.80)\u2500\u2570Z\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2570\u25cf\u2500\u2524\n\n    .. details::\n        :title: Usage Details\n\n        **Parameter shape**\n\n        The expected shape for the weight tensor can be computed with the static method\n        :meth:`~.qml.StronglyEntanglingLayers.shape` and used when creating randomly\n        initialised weight tensors:\n\n        .. code-block:: python\n\n            shape = qml.StronglyEntanglingLayers.shape(n_layers=2, n_wires=2)\n            weights = np.random.random(size=shape)\n\n    \"\"\"\n\n    num_wires = AnyWires\n    grad_method = None\n\n    def __init__(self, weights, wires, ranges=None, imprimitive=None, id=None):\n        shape = qml.math.shape(weights)[-3:]\n\n        if shape[1] != len(wires):\n            raise ValueError(\n                f\"Weights tensor must have second dimension of length {len(wires)}; got {shape[1]}\"\n            )\n\n        if shape[2] != 3:\n            raise ValueError(\n                f\"Weights tensor must have third dimension of length 3; got {shape[2]}\"\n            )\n\n        if ranges is None:\n            if len(wires) > 1:\n                # tile ranges with iterations of range(1, n_wires)\n                ranges = tuple((l % (len(wires) - 1)) + 1 for l in range(shape[0]))\n            else:\n                ranges = (0,) * shape[0]\n        else:\n            ranges = tuple(ranges)\n            if len(ranges) != shape[0]:\n                raise ValueError(f\"Range sequence must be of length {shape[0]}; got {len(ranges)}\")\n            for r in ranges:\n                if r % len(wires) == 0:\n                    raise ValueError(\n                        f\"Ranges must not be zero nor divisible by the number of wires; got {r}\"\n                    )\n\n        self._hyperparameters = {\"ranges\": ranges, \"imprimitive\": imprimitive or qml.CNOT}\n\n        super().__init__(weights, wires=wires, id=id)\n\n    @property\n    def num_params(self):\n        return 1\n\n    @staticmethod\n    def compute_decomposition(\n        weights, wires, ranges, imprimitive\n    ):  # pylint: disable=arguments-differ\n        r\"\"\"Representation of the operator as a product of other operators.\n\n        .. math:: O = O_1 O_2 \\dots O_n.\n\n\n\n        .. seealso:: :meth:`~.StronglyEntanglingLayers.decomposition`.\n\n        Args:\n            weights (tensor_like): weight tensor\n            wires (Any or Iterable[Any]): wires that the operator acts on\n            ranges (Sequence[int]): sequence determining the range hyperparameter for each subsequent layer\n            imprimitive (pennylane.ops.Operation): two-qubit gate to use\n\n        Returns:\n            list[.Operator]: decomposition of the operator\n\n        **Example**\n\n        >>> weights = torch.tensor([[-0.2, 0.1, -0.4], [1.2, -2., -0.4]])\n        >>> qml.StronglyEntanglingLayers.compute_decomposition(weights, wires=[\"a\", \"b\"], ranges=[2], imprimitive=qml.CNOT)\n        [Rot(tensor(-0.2000), tensor(0.1000), tensor(-0.4000), wires=['a']),\n        Rot(tensor(1.2000), tensor(-2.), tensor(-0.4000), wires=['b']),\n        CNOT(wires=['a', 'a']),\n        CNOT(wires=['b', 'b'])]\n        \"\"\"\n        n_layers = qml.math.shape(weights)[-3]\n        wires = qml.wires.Wires(wires)\n        op_list = []\n\n        for l in range(n_layers):\n            for i in range(len(wires)):  # pylint: disable=consider-using-enumerate\n                op_list.append(\n                    qml.Rot(\n                        weights[..., l, i, 0],\n                        weights[..., l, i, 1],\n                        weights[..., l, i, 2],\n                        wires=wires[i],\n                    )\n                )\n\n            if len(wires) > 1:\n                for i in range(len(wires)):\n                    act_on = wires.subset([i, i + ranges[l]], periodic_boundary=True)\n                    op_list.append(imprimitive(wires=act_on))\n\n        return op_list\n\n    @staticmethod\n    def shape(n_layers, n_wires):\n        r\"\"\"Returns the expected shape of the weights tensor.\n\n        Args:\n            n_layers (int): number of layers\n            n_wires (int): number of wires\n\n        Returns:\n            tuple[int]: shape\n        \"\"\"\n\n        return n_layers, n_wires, 3\n", "path": "pennylane/templates/layers/strongly_entangling.py"}]}