builder
eigenkit.core.builder
A builder that creates a CircuitSpec one gate at a time.
The style follows Qiskit, Amazon Braket and CUDA Quantum: qc.rx(angle, qubit)
adds a gate to qc itself and returns qc, so that calls can be chained.
CircuitBuilder sits between the ready-made blocks and writing the circuit data
by hand. You can write a circuit gate by gate when that is the natural way, and
then, if you want, call .to_block() to combine the result with other blocks.
CircuitBuilder
Build a CircuitSpec one gate at a time.
Example
qc = CircuitBuilder(n_qubits=3)
weights = qc.add_weights(6)
inputs = qc.add_inputs(3)
for qubit in range(3):
qc.ry(inputs[qubit], qubit=qubit)
for depth in range(2):
for qubit in range(3):
qc.ry(weights[depth * 3 + qubit], qubit=qubit)
for qubit in range(2):
qc.cnot(qubit, qubit + 1)
spec = qc.build()
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_qubits
|
int
|
The number of qubits of the circuit being built. Every qubit
index that a gate uses must be between |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
n_inputs
property
The number of input features that add_inputs() has reserved so far.
The built CircuitSpec has the same number.
n_qubits
property
The number of qubits of the circuit, as given to the constructor.
Every qubit index that a gate uses must be smaller than this number, and the number never changes.
n_weights
property
The number of trainable weights that add_weights() has reserved so far.
The built CircuitSpec has the same number.
add_inputs(count)
Reserve count input features and return references to them.
This is the counterpart of add_weights() for data instead of trainable
parameters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
count
|
int
|
The number of input features to reserve. |
required |
Returns:
| Type | Description |
|---|---|
list[InputRef]
|
One |
add_weights(count)
Reserve count trainable weights and return references to them.
Pass a returned WeightRef wherever a gate takes an angle. The indices
are local to this builder and start at 0. When the block is combined
with others, assemble shifts them to their positions in the whole
circuit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
count
|
int
|
The number of weights to reserve. |
required |
Returns:
| Type | Description |
|---|---|
list[WeightRef]
|
One |
build()
Return the current state of the builder as an immutable CircuitSpec.
cnot(control, target)
Add a controlled-NOT (CNOT) gate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
control
|
int
|
The qubit that controls the flip. |
required |
target
|
int
|
The qubit that is flipped. |
required |
Returns:
| Type | Description |
|---|---|
'CircuitBuilder'
|
This builder, so that calls can be chained. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
cphase(angle, control, target)
Add a controlled phase shift gate.
The gate is symmetric: the control and the target play the same role.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
angle
|
ParameterLike
|
The phase. It can be a number or a symbolic reference. |
required |
control
|
int
|
One of the two qubits. |
required |
target
|
int
|
The other qubit. The gate acts in the same way if the two qubits are exchanged. |
required |
Returns:
| Type | Description |
|---|---|
'CircuitBuilder'
|
This builder, so that calls can be chained. |
cry(angle, control, target)
Add a controlled RY gate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
angle
|
ParameterLike
|
The rotation angle. It can be a number or a symbolic reference. |
required |
control
|
int
|
The qubit that controls the rotation. |
required |
target
|
int
|
The qubit that is rotated. |
required |
Returns:
| Type | Description |
|---|---|
'CircuitBuilder'
|
This builder, so that calls can be chained. |
h(qubit)
Add a Hadamard gate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
qubit
|
int
|
The target qubit. |
required |
Returns:
| Type | Description |
|---|---|
'CircuitBuilder'
|
This builder, so that calls can be chained. |
mcx(*qubits)
Add a multi-controlled X gate.
All the qubits except the last one are controls.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*qubits
|
int
|
Two or more distinct qubits. The controls come first, and the target is the last one. |
()
|
Returns:
| Type | Description |
|---|---|
'CircuitBuilder'
|
This builder, so that calls can be chained. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If fewer than two qubits are given, or if a qubit is repeated. |
mcz(*qubits)
Add a multi-controlled Z gate.
All the qubits except the last one are controls.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*qubits
|
int
|
Two or more distinct qubits. The controls come first, and the target is the last one. |
()
|
Returns:
| Type | Description |
|---|---|
'CircuitBuilder'
|
This builder, so that calls can be chained. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If fewer than two qubits are given, or if a qubit is repeated. |
pauli_exponential(paulis, angle, coefficient=1.0)
Add the exponential of a product of Pauli operators.
The gate is exp(-i * coefficient * angle * P), where P is the product of
paulis. Each element of paulis is a pair (op, qubit), where op is
"X", "Y" or "Z", and the qubits are distinct.
This is the Trotter building block that the quantum approximate
optimisation algorithm (QAOA) needs for its cost and mixer layers, and that
the unitary coupled-cluster singles and doubles (UCCSD) ansatz needs for
its excitation operators. It is built from the core gates only. First,
H gates (for X) and RX(π/2) gates (for Y) change each factor to the
Z basis. Then a ladder of controlled-NOT (CNOT) gates accumulates the
parity on the last qubit, and a central RZ(2 * coefficient * angle) is
applied (because RZ(φ) = exp(-i φ Z / 2)). Finally, the inverse of the
first steps is applied.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
paulis
|
Sequence[tuple[str, int]]
|
The Pauli product, as |
required |
angle
|
ParameterLike
|
The rotation angle. It can be a number or a symbolic reference. |
required |
coefficient
|
float
|
A number that multiplies the angle. This is where the
weight of a Hamiltonian term goes. Default: |
1.0
|
Returns:
| Type | Description |
|---|---|
'CircuitBuilder'
|
This builder, so that calls can be chained. |
phase_shift(angle, qubit)
Add a phase shift gate R(φ).
The gate multiplies |1⟩ by e^(iφ) and leaves |0⟩ unchanged.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
angle
|
ParameterLike
|
The phase |
required |
qubit
|
int
|
The target qubit. |
required |
Returns:
| Type | Description |
|---|---|
'CircuitBuilder'
|
This builder, so that calls can be chained. |
rx(angle, qubit)
Add a rotation about the X axis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
angle
|
ParameterLike
|
The rotation angle. It can be a number, or a |
required |
qubit
|
int
|
The target qubit. |
required |
Returns:
| Type | Description |
|---|---|
'CircuitBuilder'
|
This builder, so that calls can be chained. |
ry(angle, qubit)
Add a rotation about the Y axis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
angle
|
ParameterLike
|
The rotation angle. It can be a number, or a |
required |
qubit
|
int
|
The target qubit. |
required |
Returns:
| Type | Description |
|---|---|
'CircuitBuilder'
|
This builder, so that calls can be chained. |
rz(angle, qubit)
Add a rotation about the Z axis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
angle
|
ParameterLike
|
The rotation angle. It can be a number, or a |
required |
qubit
|
int
|
The target qubit. |
required |
Returns:
| Type | Description |
|---|---|
'CircuitBuilder'
|
This builder, so that calls can be chained. |
s(qubit)
Add an S gate, which is a quarter turn about the Z axis.
Its inverse is sdg().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
qubit
|
int
|
The target qubit. |
required |
Returns:
| Type | Description |
|---|---|
'CircuitBuilder'
|
This builder, so that calls can be chained. |
sdg(qubit)
Add an S-dagger gate (Sdg), which is the inverse of s().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
qubit
|
int
|
The target qubit. |
required |
Returns:
| Type | Description |
|---|---|
'CircuitBuilder'
|
This builder, so that calls can be chained. |
swap(qubit0, qubit1)
Add a SWAP gate, which exchanges the states of two qubits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
qubit0
|
int
|
The first qubit. |
required |
qubit1
|
int
|
The second qubit. |
required |
Returns:
| Type | Description |
|---|---|
'CircuitBuilder'
|
This builder, so that calls can be chained. |
to_block()
Wrap the current state of the builder in a CustomBlock.
This is useful to build a part of a circuit one gate at a time, and then to
combine it with other blocks. When the blocks are assembled, the indices of
the WeightRef and InputRef objects of this block are shifted to their
positions in the whole circuit.
x(qubit)
Add a Pauli X gate, which is a bit flip.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
qubit
|
int
|
The target qubit. |
required |
Returns:
| Type | Description |
|---|---|
'CircuitBuilder'
|
This builder, so that calls can be chained. |
z(qubit)
Add a Pauli Z gate, which is a phase flip.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
qubit
|
int
|
The target qubit. |
required |
Returns:
| Type | Description |
|---|---|
'CircuitBuilder'
|
This builder, so that calls can be chained. |