PennyLane provides a growing library of pre-coded templates of common variational circuit architectures that can be used to easily build, evaluate, and train more complex models. In the literature, such architectures are commonly known as an ansatz. Templates can be used to embed data into quantum states, to define trainable layers of quantum gates, to prepare quantum states as the first operation in a circuit, or simply as general subroutines that a circuit is built from.
The following is a gallery of built-in templates provided by PennyLane.
Embeddings encode input features into the quantum state of the circuit. Hence, they usually take a data sample such as a feature vector as an argument. Embeddings can also depend on trainable parameters, and they may be constructed from repeated layers.
Layer architectures define sequences of trainable gates that are repeated like the layers in a
neural network. Note that arbitrary templates or operations can also be repeated using the
State preparation templates transform the zero state \(|0\dots 0 \rangle\) to another initial state. In contrast to embeddings that can in principle be used anywhere in a circuit, state preparation is typically used as the first operation.
Other useful templates which do not belong to the previous categories can be found here.
PennyLane offers a broadcasting function to easily construct templates:
takes either quantum gates or templates and applies them to wires in a specific pattern.
While the broadcasting function can make template construction very convenient, it adds an overhead and is therefore not recommended when speed is a major concern.
Templates that take a weight parameter tensor usually provide methods that return the shape of this tensor. The shape can for example be used to construct random weights at the beginning of training.
import pennylane as qml from pennylane.templates import BasicEntanglerLayers from pennylane import numpy as np n_wires = 3 dev = qml.device('default.qubit', wires=n_wires) @qml.qnode(dev) def circuit(weights): BasicEntanglerLayers(weights=weights, wires=range(n_wires)) return qml.expval(qml.PauliZ(0)) shape = BasicEntanglerLayers.shape(n_layers=2, n_wires=n_wires) np.random.seed(42) # to make the result reproducable weights = np.random.random(size=shape)
>>> circuit(weights) 0.7258859204630561
If a template takes more than one weight tensor, the
shape method returns a list of shape tuples.
Creating a custom template can be as simple as defining a function that creates operations and does not have a return statement:
from pennylane import numpy as np def MyTemplate(a, b, wires): c = np.sin(a) + b qml.RX(c, wires=wires) n_wires = 3 dev = qml.device('default.qubit', wires=n_wires) @qml.qnode(dev) def circuit(a, b): MyTemplate(a, b, wires=range(n_wires)) return qml.expval(qml.PauliZ(0))
>>> circuit(2, 3) -0.7195065654396784
Make sure that classical processing is compatible with the autodifferentiation library you are using. For example,
MyTemplate is to be used with the torch framework, we would have to change
math library contains some advanced functionality for
As suggested by the camel-case naming, built-in templates in PennyLane are classes. Classes are more complex data structures than functions, since they can define properties and methods of templates (such as gradient recipes or matrix representations). Consult the Contributing templates page to learn how to code up your own template class, and how to add it to the PennyLane template library.