Variational
These blocks are trainable, parametrised layers. There are two kinds:
Variationalapplies rotations about one axis and a ladder of controlled-NOT (CNOT) gates, repeateddepthtimes.StrongVariationalapplies the rotationsRZ,RYandRZand a ladder of CNOT gates, repeateddepthtimes.
from eigenkit import Variational, StrongVariational
basic = Variational(depth=2, rotation="RY")
strong = StrongVariational(depth=2)
Variational
| Parameter | Type | Default | Description |
|---|---|---|---|
depth |
int |
Required | The number of repetitions. |
rotation |
"RX" | "RY" | "RZ" |
"RY" |
The rotation gate applied to each qubit in each repetition. |
Each repetition applies one rotation to each qubit, followed by a ladder of CNOT
gates (CNOT(0, 1), CNOT(1, 2), ...). The total number of trainable weights is
depth * n_qubits.
The block is the middle box: one RY(θ) on every qubit, then
CNOT(0, 1), CNOT(1, 2), ..., and the bracket shows how many times this repeats. The
encoding on the left and the measurement of each qubit on the right are not part of
the block. A layer such as Basic adds them around it.
StrongVariational
| Parameter | Type | Default | Description |
|---|---|---|---|
depth |
int |
Required | The number of repetitions. |
Each repetition applies RZ, RY and RZ to every qubit, followed by a ladder of
CNOT gates. The total number of trainable weights is 3 * depth * n_qubits.
The same picture with strong in place of basic, on two qubits. Each Rot box is
the three rotations RZ, RY and RZ, so it has three weights where Variational
has one, and the CNOT ladder after it is unchanged. It is drawn after an RY
encoding, with a single expectation value measured on the first qubit.
StrongVariational is more expressive than Variational at the same depth, but it
has three times as many parameters. The block adds all the RZ gates, then all the
RY gates, then all the RZ gates, in place of three rotations per qubit in turn.
This lets the backends that work layer by layer apply each layer of rotations in one
fast call.
Choosing the depth
Each repetition uses a new set of trainable weights. A larger depth gives more expressivity, but it adds parameters and makes training slower.
# Minimal expressivity, fast training.
Variational(depth=1, rotation="RY")
# More expressive; useful for harder classification tasks.
Variational(depth=3, rotation="RY")
depth must be positive
Both blocks check it when they are created: Variational(depth=0) and
StrongVariational(depth=0) raise
ValueError: depth must be positive, got 0, and so does any negative value.
Variational also checks rotation at that point. Reuploading makes the same
checks on depth, in_features and both of its rotation arguments.
API reference
eigenkit.configs.Variational
dataclass
depth trainable layers of single-qubit rotations and entangling gates.
Each layer applies one trainable rotation to every qubit, then a controlled-NOT
(CNOT) gate from each qubit to the next one. The block takes
depth * n_qubits weights and no inputs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
depth
|
int
|
The number of layers. It must be positive, and a |
required |
rotation
|
GateName
|
The rotation gate of the trainable layer: |
'RY'
|
build(n_qubits)
Build the gates of this block for a circuit with n_qubits qubits.
The layers act on every qubit of the circuit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_qubits
|
int
|
The number of qubits of the circuit being assembled, which is the number of qubits of the widest block in the list. |
required |
Returns:
| Type | Description |
|---|---|
IRFragment
|
The gates of the block, as an |
from_dict(d)
classmethod
Rebuild a block from the output of to_dict().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
dict
|
A dictionary returned by |
required |
Returns:
| Type | Description |
|---|---|
'BasicVariational'
|
The rebuilt |
required_qubits()
Return 1, because the block extends to all the qubits of the circuit.
to_dict()
Return a description of this block that can be saved as JSON.
When a saved model is loaded, the type key selects the block class whose
from_dict() rebuilds the block.
Returns:
| Type | Description |
|---|---|
dict
|
The fields of the block, and its |
eigenkit.configs.StrongVariational
dataclass
depth trainable layers of RZ, RY and RZ rotations and entangling gates.
Each layer applies the rotations RZ, RY and RZ to every qubit, then a
controlled-NOT (CNOT) gate from each qubit to the next one. The block is
modelled on PennyLane's StronglyEntanglingLayers.
The gates are added one layer at a time: all the RZ rotations, then all the
RY rotations, then all the RZ rotations, then the CNOT gates. They are not
added as three rotations per qubit. The result is the same, because rotations
on different qubits commute. The layered order lets the backends that support
it apply each layer of rotations in one fast call, in place of 3 * n_qubits
calls on single qubits.
The block takes 3 * depth * n_qubits weights and no inputs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
depth
|
int
|
The number of layers. It must be positive, and a |
required |
build(n_qubits)
Build the gates of this block for a circuit with n_qubits qubits.
The layers act on every qubit of the circuit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_qubits
|
int
|
The number of qubits of the circuit being assembled, which is the number of qubits of the widest block in the list. |
required |
Returns:
| Type | Description |
|---|---|
IRFragment
|
The gates of the block, as an |
from_dict(d)
classmethod
Rebuild a block from the output of to_dict().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
dict
|
A dictionary returned by |
required |
Returns:
| Type | Description |
|---|---|
'StrongVariational'
|
The rebuilt |
required_qubits()
Return 1, because the block extends to all the qubits of the circuit.
to_dict()
Return a description of this block that can be saved as JSON.
When a saved model is loaded, the type key selects the block class whose
from_dict() rebuilds the block.
Returns:
| Type | Description |
|---|---|
dict
|
The fields of the block, and its |