qml.templates.layers.RandomLayers¶

RandomLayers
(weights, wires, ratio_imprim=0.3, imprimitive=<class 'pennylane.ops.qubit.CNOT'>, rotations=None, seed=42)[source]¶ Layers of randomly chosen single qubit rotations and 2qubit entangling gates, acting on randomly chosen qubits.
Warning
This template uses random number generation inside qnodes. Find more details about how to invoke the desired random behaviour in the “Usage Details” section below.
The argument
weights
contains the weights for each layer. The number of layers \(L\) is therefore derived from the first dimension ofweights
.The twoqubit gates of type
imprimitive
and the rotations are distributed randomly in the circuit. The number of random rotations is derived from the second dimension ofweights
. The number of twoqubit gates is determined byratio_imprim
. For example, a ratio of0.3
with30
rotations will lead to the use of10
twoqubit gates.Note
If applied to one qubit only, this template will use no imprimitive gates.
This is an example of two 4qubit random layers with four PauliY/PauliZ rotations \(R_y, R_z\), controlledZ gates as imprimitives, as well as
ratio_imprim=0.3
: Parameters
weights (array[float]) – array of weights of shape
(L, k)
,wires (Sequence[int]) – sequence of qubit indices that the template acts on
ratio_imprim (float) – value between 0 and 1 that determines the ratio of imprimitive to rotation gates
imprimitive (pennylane.ops.Operation) – twoqubit gate to use, defaults to
CNOT
rotations (list[pennylane.ops.Operation]) – List of PauliX, PauliY and/or PauliZ gates. The frequency determines how often a particular rotation type is used. Defaults to the use of all three rotations with equal frequency.
seed (int) – seed to generate random architecture, defaults to 42
 Raises
ValueError – if inputs do not have the correct format
Usage Details
Default seed
RandomLayers
always uses a seed to initialize the construction of a random circuit. This means that the template creates the same circuit every time it is called. If no seed is provided, the default seed of42
is used.import pennylane as qml import numpy as np from pennylane.templates.layers import RandomLayers dev = qml.device("default.qubit", wires=2) weights = [[0.1, 2.1, 1.4]] @qml.qnode(dev) def circuit1(weights): RandomLayers(weights=weights, wires=range(2)) return qml.expval(qml.PauliZ(0)) @qml.qnode(dev) def circuit2(weights): RandomLayers(weights=weights, wires=range(2)) return qml.expval(qml.PauliZ(0))
>>> np.allclose(circuit1(weights), circuit2(weights)) >>> True
You can verify this by drawing the circuits.
>>> print(circuit1.draw()) >>> 0: ──RX(0.1)──RX(2.1)──╭X──╭X───────────┤ ⟨Z⟩ ... 1: ─────────────────────╰C──╰C──RZ(1.4)──┤
>>> print(circuit2.draw()) >>> 0: ──RX(0.1)──RX(2.1)──╭X──╭X───────────┤ ⟨Z⟩ ... 1: ─────────────────────╰C──╰C──RZ(1.4)──┤
Changing the seed
To change the randomly generated circuit architecture, you have to change the seed passed to the template. For example, these two calls of
RandomLayers
do not create the same circuit:@qml.qnode(dev) def circuit_9(weights): RandomLayers(weights=weights, wires=range(2), seed=9) return qml.expval(qml.PauliZ(0)) @qml.qnode(dev) def circuit_12(weights): RandomLayers(weights=weights, wires=range(2), seed=12) return qml.expval(qml.PauliZ(0))
>>> np.allclose(circuit_9(weights), circuit_12(weights)) >>> False
>>> print(circuit_9.draw()) >>> 0: ──╭X──RY(2.1)──RX(1.4)──┤ ⟨Z⟩ ... 1: ──╰C──RX(0.1)────────────┤
>>> print(circuit_12.draw()) >>> 0: ──╭X──RX(2.1)──╭C──╭X──RZ(1.4)──┤ ⟨Z⟩ ... 1: ──╰C──RZ(0.1)───╰X──╰C───────────┤
Automatically creating random circuits
To automate the process of creating different circuits with
RandomLayers
, you can setseed=None
to avoid specifying a seed. However, in this case care needs to be taken. In the default setting, a quantum node is mutable, which means that the quantum function is reevaluated every time it is called. This means that the circuit is reconstructed from scratch each time you call the qnode:@qml.qnode(dev) def circuit_rnd(weights): RandomLayers(weights=weights, wires=range(2), seed=None) return qml.expval(qml.PauliZ(0)) first_call = circuit_rnd(weights) second_call = circuit_rnd(weights)
>>> np.allclose(first_call, second_call) >>> False
This can be rectified by making the quantum node immutable.
@qml.qnode(dev, mutable=False) def circuit_rnd(weights): RandomLayers(weights=weights, wires=range(2), seed=None) return qml.expval(qml.PauliZ(0)) first_call = circuit_rnd(weights) second_call = circuit_rnd(weights)
>>> np.allclose(first_call, second_call) >>> True
Contents
Using PennyLane
Development
API
Downloads