qml.templates.layers.SimplifiedTwoDesign

SimplifiedTwoDesign(initial_layer_weights, weights, wires)[source]

Layers consisting of a simplified 2-design architecture of Pauli-Y rotations and controlled-Z entanglers proposed in Cerezo et al. (2020).

A 2-design is an ensemble of unitaries whose statistical properties are the same as sampling random unitaries with respect to the Haar measure up to the first 2 moments.

The template is not a strict 2-design, since it does not consist of universal 2-qubit gates as building blocks, but has been shown in Cerezo et al. (2020) to exhibit important properties to study “barren plateaus” in quantum optimization landscapes.

The template starts with an initial layer of single qubit Pauli-Y rotations, before the main \(L\) layers are applied. The basic building block of the main layers are controlled-Z entanglers followed by a pair of Pauli-Y rotation gates (one for each wire). Each layer consists of an “even” part whose entanglers start with the first qubit, and an “odd” part that starts with the second qubit.

This is an example of two layers, including the initial layer:

../../_images/simplified_two_design.png

The argument initial_layer_weights contains the rotation angles of the initial layer of Pauli-Y rotations, while weights contains the pairs of Pauli-Y rotation angles of the respective layers. Each layer takes \(\lfloor M/2 \rfloor + \lfloor (M-1)/2 \rfloor = M-1\) pairs of angles, where \(M\) is the number of wires. The number of layers \(L\) is derived from the first dimension of weights.

Parameters
  • initial_layer_weights (array[float]) – array of weights for the initial rotation block, shape (M,)

  • weights (array[float]) – array of rotation angles for the layers, shape (L, M-1, 2)

  • wires (Sequence[int] or int) – qubit indices that the template acts on

Raises

ValueError – if inputs do not have the correct format

template - here shown for two layers - is used inside a QNode:

import pennylane as qml
from pennylane.templates import SimplifiedTwoDesign
from math import pi

n_wires = 3
dev = qml.device('default.qubit', wires=n_wires)

@qml.qnode(dev)
def circuit(init_weights, weights):
    SimplifiedTwoDesign(initial_layer_weights=init_weights, weights=weights, wires=range(n_wires))
    return [qml.expval(qml.PauliZ(wires=i)) for i in range(n_wires)]

init_weights = [pi, pi, pi]
weights_layer1 = [[0., pi],
                  [0., pi]]
weights_layer2 = [[pi, 0.],
                  [pi, 0.]]
weights = [weights_layer1, weights_layer2]

>>> circuit(init_weights, weights)
[1., -1., 1.]

Parameter initialization function

The init module contains four parameter initialization functions:

  • simplified_two_design_initial_layer_normal

  • simplified_two_design_initial_layer_uniform

  • simplified_two_design_weights_normal.

  • simplified_two_design_weights_uniform.

They can be used as follows:

from pennylane.init import (simplified_two_design_initial_layer_normal,
                            simplified_two_design_weights_normal)

n_layers = 4
init_weights = simplified_two_design_initial_layer_normal(n_wires)
weights = simplified_two_design_weights_normal(n_layers, n_wires)

>>> circuit(initial_layer_weights, weights)