Expose standard-library quantum callables.
The reader-facing circuit API is function-oriented: use :func:qft,
:func:iqft, :func:qpe, :func:qsvt, state-preparation helpers, arithmetic
helpers, and :func:mcx inside qkernels. Factories that must also expose
algorithm metadata may return frozen non-callable descriptors; invoke the
descriptor’s documented qkernel field rather than the descriptor itself.
Internally these functions emit named callables with Qamomile bodies and
optional backend-native implementations.
Standard composites use the same composite_gate mechanism as user
callables; there is no separate class-based gate hierarchy.
Example:
import qamomile.circuit as qmc
@qmc.qkernel
def my_algorithm(qubits: qmc.Vector[qmc.Qubit]) -> qmc.Vector[qmc.Qubit]:
qubits = qmc.qft(qubits)
return qmc.iqft(qubits)Overview¶
| Function | Description |
|---|---|
grover_iteration_count | Return the optimal Grover iteration count floor((pi/4) sqrt(N/m)). |
grover_search | Run the Grover amplitude-amplification loop on reg. |
iqft | Apply the inverse quantum Fourier transform. |
Constants¶
mcx=multi_controlled_xShort public alias for :func:multi_controlled_x.
Functions¶
grover_iteration_count [source]¶
def grover_iteration_count(
num_qubits: int | np.integer[Any] | sp.Expr,
num_marked: int | np.integer[Any] | sp.Expr = 1,
) -> int | sp.ExprReturn the optimal Grover iteration count floor((pi/4) sqrt(N/m)).
Parameters:
| Name | Type | Description |
|---|---|---|
num_qubits | int | np.integer[Any] | sp.Expr | Number of search qubits n (search space N = 2**n). May be a Python or NumPy integer, or a symbolic expression. |
num_marked | int | np.integer[Any] | sp.Expr | Number of marked solutions m. Defaults to 1. |
Returns:
int | sp.Expr — int | sp.Expr: Concrete iteration count when both arguments are concrete
Python or NumPy integers, otherwise the symbolic expression
floor((pi/4) sqrt(2**n / m)). SymPy integers remain SymPy
expressions.
Raises:
TypeError— Ifnum_qubitsornum_markedis a boolean.ValueError— If concretenum_qubitsornum_markedis not positive.
Example:
>>> grover_iteration_count(4, 1)
3grover_search [source]¶
def grover_search(
reg: Vector[Qubit],
oracle: Oracle | QKernelLike,
iterations: int | qmc.UInt,
) -> Vector[Qubit]Run the Grover amplitude-amplification loop on reg.
Prepares the uniform superposition, then applies iterations rounds of
oracle followed by the diffusion operator. Leaving iterations
symbolic makes resource estimation report the universal O(sqrt(N/m))
query complexity: the oracle’s opaque cost contributes the per-query gate
cost and the diffusion contributes O(n) gates, both summed over the
symbolic iteration count.
Parameters:
| Name | Type | Description |
|---|---|---|
reg | Vector[Qubit] | Search register in the all-zero state on entry. |
oracle | Oracle | QKernelLike | Phase oracle marking the solution(s). Supply a costed opaque box (e.g. qmc.opaque(..., cost=...)) so the estimator can cost each query. |
iterations | int | qmc.UInt | Number of Grover iterations. Use :func:grover_iteration_count to obtain the optimal value; leave it as an unbound UInt parameter for symbolic estimation. |
Returns:
Vector[Qubit] — Vector[Qubit]: Register after amplitude amplification.
Example:
>>> import qamomile.circuit as qmc
>>> from qamomile.circuit.stdlib import grover_search, grover_iteration_count
>>> mark = qmc.opaque("mark", num_qubits=3)
>>> @qmc.qkernel
... def search(reg: qmc.Vector[qmc.Qubit]) -> qmc.Vector[qmc.Qubit]:
... return grover_search(reg, mark, grover_iteration_count(3))iqft [source]¶
def iqft(qubits: Vector[Qubit]) -> Vector[Qubit]Apply the inverse quantum Fourier transform.
Parameters:
| Name | Type | Description |
|---|---|---|
qubits | Vector[Qubit] | Register to transform. |
Returns:
Vector[Qubit] — Vector[Qubit]: Transformed register.
qamomile.circuit.stdlib.arithmetic¶
Expose standard-library arithmetic callables.
The package groups arithmetic primitives by implementation strategy while keeping the original arithmetic-module import surface stable. Public callables are re-exported here; selected internal helpers remain available for Qamomile’s algorithm implementations and focused tests.
Overview¶
| Function | Description |
|---|---|
add_const | Add a classical constant to an extended quantum register. |
controlled_add_const | Condition a classical constant addition on one qubit. |
controlled_modular_add | Condition a modular addition on one qubit. |
controlled_modular_add_const | Condition a constant modular addition on one qubit. |
controlled_modular_add_const_modulus | Condition a quantum-register addition modulo a classical constant. |
lookup_xor | XOR a modular multiplication lookup into a clean target register. |
modmul_const | Apply constant modular multiplication |x> -> |a*x mod N>. |
modular_add | Add one register into another modulo a preserved modulus register. |
modular_add_const | Add a classical constant to a quantum register modulo a constant. |
ripple_carry_add | Add left into right with a reversible ripple-carry network. |
Functions¶
add_const [source]¶
def add_const(
target: Vector[Qubit],
overflow: Qubit,
value: UInt,
) -> tuple[Vector[Qubit], Qubit]Add a classical constant to an extended quantum register.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Vector[Qubit] | Little-endian low bits to update. |
overflow | Qubit | Most-significant bit of the extended value. |
value | UInt | Classical non-negative value to add. |
Returns:
tuple[Vector[Qubit], Qubit] — tuple[Vector[Qubit], Qubit]: Updated low bits and overflow bit.
controlled_add_const [source]¶
def controlled_add_const(
control: Qubit,
target: Vector[Qubit],
overflow: Qubit,
value: UInt,
) -> tuple[Qubit, Vector[Qubit], Qubit]Condition a classical constant addition on one qubit.
Parameters:
| Name | Type | Description |
|---|---|---|
control | Qubit | Quantum control preserved by the operation. |
target | Vector[Qubit] | Little-endian low bits to update. |
overflow | Qubit | Most-significant bit of the extended value. |
value | UInt | Classical non-negative value to add. |
Returns:
tuple[Qubit, Vector[Qubit], Qubit] — tuple[Qubit, Vector[Qubit], Qubit]: Updated control, low bits, and
overflow bit.
controlled_modular_add [source]¶
def controlled_modular_add(
control: Qubit,
addend: Vector[Qubit],
modulus: Vector[Qubit],
target: Vector[Qubit],
carry: Qubit,
overflow: Qubit,
flag: Qubit,
) -> tuple[Qubit, Vector[Qubit], Vector[Qubit], Vector[Qubit], Qubit, Qubit, Qubit]Condition a modular addition on one qubit.
Parameters:
| Name | Type | Description |
|---|---|---|
control | Qubit | Control qubit preserved by the operation. |
addend | Vector[Qubit] | Value to add when control is one. |
modulus | Vector[Qubit] | Modulus value, preserved on return. |
target | Vector[Qubit] | Modular accumulator register. |
carry | Qubit | Clean ripple-carry workspace. |
overflow | Qubit | Clean high bit for underflow detection. |
flag | Qubit | Clean conditional-restoration flag. |
Returns:
Qubit — tuple[Qubit, Vector[Qubit], Vector[Qubit], Vector[Qubit], Qubit, Qubit,
Vector[Qubit] — Qubit]: Preserved control and constants, conditionally updated target,
and restored workspaces.
controlled_modular_add_const [source]¶
def controlled_modular_add_const(
control: Qubit,
target: Vector[Qubit],
overflow: Qubit,
flag: Qubit,
addend: UInt,
modulus: UInt,
) -> tuple[Qubit, Vector[Qubit], Qubit, Qubit]Condition a constant modular addition on one qubit.
Parameters:
| Name | Type | Description |
|---|---|---|
control | Qubit | Quantum control preserved by the operation. |
target | Vector[Qubit] | Modular target register. |
overflow | Qubit | Clean high-bit workspace restored on return. |
flag | Qubit | Clean modular-reduction flag restored on return. |
addend | UInt | Classical value to add when enabled. |
modulus | UInt | Classical modulus. |
Returns:
tuple[Qubit, Vector[Qubit], Qubit, Qubit] — tuple[Qubit, Vector[Qubit], Qubit, Qubit]: Updated control, modular
target, and restored workspace qubits.
controlled_modular_add_const_modulus [source]¶
def controlled_modular_add_const_modulus(
control: Qubit,
addend: Vector[Qubit],
target: Vector[Qubit],
carry: Qubit,
overflow: Qubit,
flag: Qubit,
modulus: UInt,
) -> tuple[Qubit, Vector[Qubit], Vector[Qubit], Qubit, Qubit, Qubit]Condition a quantum-register addition modulo a classical constant.
Parameters:
| Name | Type | Description |
|---|---|---|
control | Qubit | Control for the modular addition. |
addend | Vector[Qubit] | Quantum addend preserved on return. |
target | Vector[Qubit] | Modular target register. |
carry | Qubit | Clean carry workspace restored on return. |
overflow | Qubit | Clean high-bit workspace restored on return. |
flag | Qubit | Clean reduction flag restored on return. |
modulus | UInt | Classical modulus. |
Returns:
tuple[Qubit, Vector[Qubit], Vector[Qubit], Qubit, Qubit, Qubit] — tuple[Qubit, Vector[Qubit], Vector[Qubit], Qubit, Qubit, Qubit]:
Preserved control and addend, modular target, and workspaces.
lookup_xor [source]¶
def lookup_xor(
address: Vector[Qubit],
target: Vector[Qubit],
scale: UInt,
modulus: UInt,
) -> tuple[Vector[Qubit], Vector[Qubit]]XOR a modular multiplication lookup into a clean target register.
The table maps j to (scale * j) % modulus. Its body is expressed
entirely in Qamomile operations, so resource estimation counts the actual
candidate-enumeration lookup network rather than an opaque table-cost
formula.
Parameters:
| Name | Type | Description |
|---|---|---|
address | Vector[Qubit] | Little-endian lookup address, preserved. |
target | Vector[Qubit] | Register XORed with the selected table value. |
scale | UInt | Classical scale factor applied to each address. |
modulus | UInt | Classical modulus applied to each table value. |
Returns:
tuple[Vector[Qubit], Vector[Qubit]] — tuple[Vector[Qubit], Vector[Qubit]]: Preserved address and updated
lookup target.
modmul_const [source]¶
def modmul_const(
reg: Vector[Qubit],
*,
multiplier: int | UInt,
modulus: int | UInt,
window_size: int = 2,
inverse_multiplier: int | UInt | None = None,
control: Qubit | None = None,
) -> Vector[Qubit] | tuple[Qubit, Vector[Qubit]]Apply constant modular multiplication |x> -> |a*x mod N>.
The standard implementation uses lookup windows and reversible modular
additions. Resource estimation walks this same executable body; it never
substitutes an external arithmetic cost formula. Basis states x >= N
are left unchanged so the operation is a unitary permutation over the full
register space. The FTQC body contains measurement and reset operations;
condition it through the control argument rather than wrapping the
complete operation with :func:qamomile.circuit.control.
Parameters:
| Name | Type | Description |
|---|---|---|
reg | Vector[Qubit] | Little-endian register to multiply in place. Its width must be known when the qkernel is traced. |
multiplier | int | UInt | Positive multiplier a. |
modulus | int | UInt | Modulus N. |
window_size | int | Lookup address width. Defaults to 2. |
inverse_multiplier | int | UInt | None | Multiplicative inverse of multiplier modulo modulus. Python integer inputs compute it automatically. Symbolic inputs must provide it explicitly. Defaults to None. |
control | Qubit | None | Optional control qubit. When provided the multiplication is applied conditionally (as Shor’s order finding conditions each modular multiplication on an exponent qubit). Defaults to None. |
Returns:
Vector[Qubit] | tuple[Qubit, Vector[Qubit]] — Vector[Qubit] | tuple[Qubit, Vector[Qubit]]: The register after modular
Vector[Qubit] | tuple[Qubit, Vector[Qubit]] — multiplication, or (control, register) when a control qubit is
Vector[Qubit] | tuple[Qubit, Vector[Qubit]] — supplied.
Raises:
ValueError— If concrete constants are invalid or symbolic constants omitinverse_multiplier.
Example:
>>> import qamomile.circuit as qmc
>>> from qamomile.circuit.stdlib import modmul_const
>>> @qmc.qkernel
... def mul(reg: qmc.Vector[qmc.Qubit]) -> qmc.Vector[qmc.Qubit]:
... return modmul_const(reg, multiplier=2, modulus=15)modular_add [source]¶
def modular_add(
addend: Vector[Qubit],
modulus: Vector[Qubit],
target: Vector[Qubit],
carry: Qubit,
overflow: Qubit,
flag: Qubit,
) -> tuple[Vector[Qubit], Vector[Qubit], Vector[Qubit], Qubit, Qubit, Qubit]Add one register into another modulo a preserved modulus register.
All registers are equally sized and little-endian. Inputs must encode
addend < modulus and target < modulus. The three workspace qubits
must start in |0> and are restored before returning.
Parameters:
| Name | Type | Description |
|---|---|---|
addend | Vector[Qubit] | Value to add, preserved on return. |
modulus | Vector[Qubit] | Modulus value, preserved on return. |
target | Vector[Qubit] | Value updated to (target + addend) % modulus. |
carry | Qubit | Clean ripple-carry workspace. |
overflow | Qubit | Clean high bit for underflow detection. |
flag | Qubit | Clean conditional-restoration flag. |
Returns:
tuple[Vector[Qubit], Vector[Qubit], Vector[Qubit], Qubit, Qubit, Qubit] — tuple[Vector[Qubit], Vector[Qubit], Vector[Qubit], Qubit, Qubit, Qubit]:
Preserved addend and modulus, modular sum, and restored workspaces.
modular_add_const [source]¶
def modular_add_const(
target: Vector[Qubit],
overflow: Qubit,
flag: Qubit,
addend: UInt,
modulus: UInt,
) -> tuple[Vector[Qubit], Qubit, Qubit]Add a classical constant to a quantum register modulo a constant.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Vector[Qubit] | Modular target register. |
overflow | Qubit | Clean high-bit workspace restored on return. |
flag | Qubit | Clean modular-reduction flag restored on return. |
addend | UInt | Classical value to add. |
modulus | UInt | Classical modulus. |
Returns:
tuple[Vector[Qubit], Qubit, Qubit] — tuple[Vector[Qubit], Qubit, Qubit]: Modular target and restored
workspace qubits.
ripple_carry_add [source]¶
def ripple_carry_add(
left: Vector[Qubit],
right: Vector[Qubit],
carry: Qubit,
overflow: Qubit,
) -> tuple[Vector[Qubit], Vector[Qubit], Qubit, Qubit]Add left into right with a reversible ripple-carry network.
The equally sized registers are little-endian. carry must start in
|0> and is restored to |0>. overflow receives the final carry,
so the output represents the full n + 1 bit sum without discarding
quantum information.
Parameters:
| Name | Type | Description |
|---|---|---|
left | Vector[Qubit] | Little-endian addend register. |
right | Vector[Qubit] | Little-endian accumulator register. |
carry | Qubit | Clean carry workspace qubit, restored on return. |
overflow | Qubit | Qubit receiving the most significant carry bit. |
Returns:
tuple[Vector[Qubit], Vector[Qubit], Qubit, Qubit] — tuple[Vector[Qubit], Vector[Qubit], Qubit, Qubit]: Preserved addend,
summed accumulator, restored carry, and updated overflow qubit.
qamomile.circuit.stdlib.arithmetic.bitwise¶
Implement bitwise helpers for constant modular multiplication.
qamomile.circuit.stdlib.arithmetic.carry_venting¶
Implement carry-venting constant addition primitives.
Overview¶
| Function | Description |
|---|---|
get_size | Return the size of a Vector handle as a Python integer. |
Functions¶
get_size [source]¶
def get_size(arr: Vector[_H]) -> intReturn the size of a Vector handle as a Python integer.
Resolves the leading axis of arr.shape through two forms a
Vector shape entry can take:
A plain Python
int(built-in bound shape; this is what you get fromqmc.qubit_array(N, ...)for literalN).A
UInthandle whose underlyingValuecarries a compile-time constant (set byuint(literal),_create_bound_input, or partial evaluation).
A UInt handle whose underlying Value is not a constant is
treated as an unresolved symbolic dimension and raises
ValueError even when the handle has the dataclass-default
init_value=0. Falling back to init_value for that case
would silently turn a runtime-symbolic Vector[Float] parameter
into a “size 0” array, hiding programming errors. Callers that
need to handle symbolic shapes (e.g., to emit a deferred callable
when the size is unknown) must catch the ValueError themselves.
Parameters:
| Name | Type | Description |
|---|---|---|
arr | Vector[Handle] | Vector handle whose first axis size is requested. |
Returns:
int — The first-axis size as a plain Python int.
Raises:
TypeError— If arr is not a 1-DVectorhandle (Vectoror itsVectorViewsubclass) — e.g., a scalarQubitwas passed where aVectoris required, a higher-rankMatrix/Tensorwas passed (this helper only resolves a 1-D first-axis size), or an unrelatedshape-bearing object such as a numpy array. This is a clearer signal than the bareAttributeErrorthatarr.shapewould otherwise raise, and it guards the stdlib / composite callers that resolve a register size through this helper.ValueError— If the shape cannot be resolved to a concrete integer — e.g., the Vector is a runtime-parametric handle without compile-time bindings, or carries aUIntdimension whose underlyingValuehas not been promoted to a constant.
qamomile.circuit.stdlib.arithmetic.constant¶
Implement Fourier-based constant addition primitives.
Overview¶
| Function | Description |
|---|---|
add_const | Add a classical constant to an extended quantum register. |
controlled_add_const | Condition a classical constant addition on one qubit. |
Functions¶
add_const [source]¶
def add_const(
target: Vector[Qubit],
overflow: Qubit,
value: UInt,
) -> tuple[Vector[Qubit], Qubit]Add a classical constant to an extended quantum register.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Vector[Qubit] | Little-endian low bits to update. |
overflow | Qubit | Most-significant bit of the extended value. |
value | UInt | Classical non-negative value to add. |
Returns:
tuple[Vector[Qubit], Qubit] — tuple[Vector[Qubit], Qubit]: Updated low bits and overflow bit.
controlled_add_const [source]¶
def controlled_add_const(
control: Qubit,
target: Vector[Qubit],
overflow: Qubit,
value: UInt,
) -> tuple[Qubit, Vector[Qubit], Qubit]Condition a classical constant addition on one qubit.
Parameters:
| Name | Type | Description |
|---|---|---|
control | Qubit | Quantum control preserved by the operation. |
target | Vector[Qubit] | Little-endian low bits to update. |
overflow | Qubit | Most-significant bit of the extended value. |
value | UInt | Classical non-negative value to add. |
Returns:
tuple[Qubit, Vector[Qubit], Qubit] — tuple[Qubit, Vector[Qubit], Qubit]: Updated control, low bits, and
overflow bit.
qamomile.circuit.stdlib.arithmetic.increment¶
Implement modular increment, decrement, and fixed-window shifts.
Overview¶
| Class | Description |
|---|---|
QKernel | Decorator class for Qamomile quantum kernels. |
Classes¶
QKernel [source]¶
class QKernel(QKernelBuildMixin, QKernelVisualizationMixin, Generic[P, R])Decorator class for Qamomile quantum kernels.
Constructor¶
def __init__(self, func: Callable[P, R]) -> NoneAttributes¶
block: Block Compile the function to a hierarchical Block if not already compiled.effects: KernelEffect Return cached semantic effects of this qkernel.funcinput_types: dict[str, Any] Return resolved and frozen frontend input annotations.nameoutput_types: list[Any] Return the resolved frontend annotation for every output slot.raw_funcreturn_type: Any Return the resolved and frozen complete return annotation.signature
qamomile.circuit.stdlib.arithmetic.modular¶
Implement modular addition primitives.
Overview¶
| Function | Description |
|---|---|
controlled_add_const | Condition a classical constant addition on one qubit. |
controlled_modular_add | Condition a modular addition on one qubit. |
controlled_modular_add_const | Condition a constant modular addition on one qubit. |
controlled_modular_add_const_modulus | Condition a quantum-register addition modulo a classical constant. |
modular_add | Add one register into another modulo a preserved modulus register. |
modular_add_const | Add a classical constant to a quantum register modulo a constant. |
ripple_carry_add | Add left into right with a reversible ripple-carry network. |
Functions¶
controlled_add_const [source]¶
def controlled_add_const(
control: Qubit,
target: Vector[Qubit],
overflow: Qubit,
value: UInt,
) -> tuple[Qubit, Vector[Qubit], Qubit]Condition a classical constant addition on one qubit.
Parameters:
| Name | Type | Description |
|---|---|---|
control | Qubit | Quantum control preserved by the operation. |
target | Vector[Qubit] | Little-endian low bits to update. |
overflow | Qubit | Most-significant bit of the extended value. |
value | UInt | Classical non-negative value to add. |
Returns:
tuple[Qubit, Vector[Qubit], Qubit] — tuple[Qubit, Vector[Qubit], Qubit]: Updated control, low bits, and
overflow bit.
controlled_modular_add [source]¶
def controlled_modular_add(
control: Qubit,
addend: Vector[Qubit],
modulus: Vector[Qubit],
target: Vector[Qubit],
carry: Qubit,
overflow: Qubit,
flag: Qubit,
) -> tuple[Qubit, Vector[Qubit], Vector[Qubit], Vector[Qubit], Qubit, Qubit, Qubit]Condition a modular addition on one qubit.
Parameters:
| Name | Type | Description |
|---|---|---|
control | Qubit | Control qubit preserved by the operation. |
addend | Vector[Qubit] | Value to add when control is one. |
modulus | Vector[Qubit] | Modulus value, preserved on return. |
target | Vector[Qubit] | Modular accumulator register. |
carry | Qubit | Clean ripple-carry workspace. |
overflow | Qubit | Clean high bit for underflow detection. |
flag | Qubit | Clean conditional-restoration flag. |
Returns:
Qubit — tuple[Qubit, Vector[Qubit], Vector[Qubit], Vector[Qubit], Qubit, Qubit,
Vector[Qubit] — Qubit]: Preserved control and constants, conditionally updated target,
and restored workspaces.
controlled_modular_add_const [source]¶
def controlled_modular_add_const(
control: Qubit,
target: Vector[Qubit],
overflow: Qubit,
flag: Qubit,
addend: UInt,
modulus: UInt,
) -> tuple[Qubit, Vector[Qubit], Qubit, Qubit]Condition a constant modular addition on one qubit.
Parameters:
| Name | Type | Description |
|---|---|---|
control | Qubit | Quantum control preserved by the operation. |
target | Vector[Qubit] | Modular target register. |
overflow | Qubit | Clean high-bit workspace restored on return. |
flag | Qubit | Clean modular-reduction flag restored on return. |
addend | UInt | Classical value to add when enabled. |
modulus | UInt | Classical modulus. |
Returns:
tuple[Qubit, Vector[Qubit], Qubit, Qubit] — tuple[Qubit, Vector[Qubit], Qubit, Qubit]: Updated control, modular
target, and restored workspace qubits.
controlled_modular_add_const_modulus [source]¶
def controlled_modular_add_const_modulus(
control: Qubit,
addend: Vector[Qubit],
target: Vector[Qubit],
carry: Qubit,
overflow: Qubit,
flag: Qubit,
modulus: UInt,
) -> tuple[Qubit, Vector[Qubit], Vector[Qubit], Qubit, Qubit, Qubit]Condition a quantum-register addition modulo a classical constant.
Parameters:
| Name | Type | Description |
|---|---|---|
control | Qubit | Control for the modular addition. |
addend | Vector[Qubit] | Quantum addend preserved on return. |
target | Vector[Qubit] | Modular target register. |
carry | Qubit | Clean carry workspace restored on return. |
overflow | Qubit | Clean high-bit workspace restored on return. |
flag | Qubit | Clean reduction flag restored on return. |
modulus | UInt | Classical modulus. |
Returns:
tuple[Qubit, Vector[Qubit], Vector[Qubit], Qubit, Qubit, Qubit] — tuple[Qubit, Vector[Qubit], Vector[Qubit], Qubit, Qubit, Qubit]:
Preserved control and addend, modular target, and workspaces.
modular_add [source]¶
def modular_add(
addend: Vector[Qubit],
modulus: Vector[Qubit],
target: Vector[Qubit],
carry: Qubit,
overflow: Qubit,
flag: Qubit,
) -> tuple[Vector[Qubit], Vector[Qubit], Vector[Qubit], Qubit, Qubit, Qubit]Add one register into another modulo a preserved modulus register.
All registers are equally sized and little-endian. Inputs must encode
addend < modulus and target < modulus. The three workspace qubits
must start in |0> and are restored before returning.
Parameters:
| Name | Type | Description |
|---|---|---|
addend | Vector[Qubit] | Value to add, preserved on return. |
modulus | Vector[Qubit] | Modulus value, preserved on return. |
target | Vector[Qubit] | Value updated to (target + addend) % modulus. |
carry | Qubit | Clean ripple-carry workspace. |
overflow | Qubit | Clean high bit for underflow detection. |
flag | Qubit | Clean conditional-restoration flag. |
Returns:
tuple[Vector[Qubit], Vector[Qubit], Vector[Qubit], Qubit, Qubit, Qubit] — tuple[Vector[Qubit], Vector[Qubit], Vector[Qubit], Qubit, Qubit, Qubit]:
Preserved addend and modulus, modular sum, and restored workspaces.
modular_add_const [source]¶
def modular_add_const(
target: Vector[Qubit],
overflow: Qubit,
flag: Qubit,
addend: UInt,
modulus: UInt,
) -> tuple[Vector[Qubit], Qubit, Qubit]Add a classical constant to a quantum register modulo a constant.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Vector[Qubit] | Modular target register. |
overflow | Qubit | Clean high-bit workspace restored on return. |
flag | Qubit | Clean modular-reduction flag restored on return. |
addend | UInt | Classical value to add. |
modulus | UInt | Classical modulus. |
Returns:
tuple[Vector[Qubit], Qubit, Qubit] — tuple[Vector[Qubit], Qubit, Qubit]: Modular target and restored
workspace qubits.
ripple_carry_add [source]¶
def ripple_carry_add(
left: Vector[Qubit],
right: Vector[Qubit],
carry: Qubit,
overflow: Qubit,
) -> tuple[Vector[Qubit], Vector[Qubit], Qubit, Qubit]Add left into right with a reversible ripple-carry network.
The equally sized registers are little-endian. carry must start in
|0> and is restored to |0>. overflow receives the final carry,
so the output represents the full n + 1 bit sum without discarding
quantum information.
Parameters:
| Name | Type | Description |
|---|---|---|
left | Vector[Qubit] | Little-endian addend register. |
right | Vector[Qubit] | Little-endian accumulator register. |
carry | Qubit | Clean carry workspace qubit, restored on return. |
overflow | Qubit | Qubit receiving the most significant carry bit. |
Returns:
tuple[Vector[Qubit], Vector[Qubit], Qubit, Qubit] — tuple[Vector[Qubit], Vector[Qubit], Qubit, Qubit]: Preserved addend,
summed accumulator, restored carry, and updated overflow qubit.
qamomile.circuit.stdlib.arithmetic.modular_multiplication¶
Implement constant modular multiplication primitives.
Overview¶
| Function | Description |
|---|---|
get_size | Return the size of a Vector handle as a Python integer. |
lookup_xor | XOR a modular multiplication lookup into a clean target register. |
modmul_const | Apply constant modular multiplication |x> -> |a*x mod N>. |
Functions¶
get_size [source]¶
def get_size(arr: Vector[_H]) -> intReturn the size of a Vector handle as a Python integer.
Resolves the leading axis of arr.shape through two forms a
Vector shape entry can take:
A plain Python
int(built-in bound shape; this is what you get fromqmc.qubit_array(N, ...)for literalN).A
UInthandle whose underlyingValuecarries a compile-time constant (set byuint(literal),_create_bound_input, or partial evaluation).
A UInt handle whose underlying Value is not a constant is
treated as an unresolved symbolic dimension and raises
ValueError even when the handle has the dataclass-default
init_value=0. Falling back to init_value for that case
would silently turn a runtime-symbolic Vector[Float] parameter
into a “size 0” array, hiding programming errors. Callers that
need to handle symbolic shapes (e.g., to emit a deferred callable
when the size is unknown) must catch the ValueError themselves.
Parameters:
| Name | Type | Description |
|---|---|---|
arr | Vector[Handle] | Vector handle whose first axis size is requested. |
Returns:
int — The first-axis size as a plain Python int.
Raises:
TypeError— If arr is not a 1-DVectorhandle (Vectoror itsVectorViewsubclass) — e.g., a scalarQubitwas passed where aVectoris required, a higher-rankMatrix/Tensorwas passed (this helper only resolves a 1-D first-axis size), or an unrelatedshape-bearing object such as a numpy array. This is a clearer signal than the bareAttributeErrorthatarr.shapewould otherwise raise, and it guards the stdlib / composite callers that resolve a register size through this helper.ValueError— If the shape cannot be resolved to a concrete integer — e.g., the Vector is a runtime-parametric handle without compile-time bindings, or carries aUIntdimension whose underlyingValuehas not been promoted to a constant.
lookup_xor [source]¶
def lookup_xor(
address: Vector[Qubit],
target: Vector[Qubit],
scale: UInt,
modulus: UInt,
) -> tuple[Vector[Qubit], Vector[Qubit]]XOR a modular multiplication lookup into a clean target register.
The table maps j to (scale * j) % modulus. Its body is expressed
entirely in Qamomile operations, so resource estimation counts the actual
candidate-enumeration lookup network rather than an opaque table-cost
formula.
Parameters:
| Name | Type | Description |
|---|---|---|
address | Vector[Qubit] | Little-endian lookup address, preserved. |
target | Vector[Qubit] | Register XORed with the selected table value. |
scale | UInt | Classical scale factor applied to each address. |
modulus | UInt | Classical modulus applied to each table value. |
Returns:
tuple[Vector[Qubit], Vector[Qubit]] — tuple[Vector[Qubit], Vector[Qubit]]: Preserved address and updated
lookup target.
modmul_const [source]¶
def modmul_const(
reg: Vector[Qubit],
*,
multiplier: int | UInt,
modulus: int | UInt,
window_size: int = 2,
inverse_multiplier: int | UInt | None = None,
control: Qubit | None = None,
) -> Vector[Qubit] | tuple[Qubit, Vector[Qubit]]Apply constant modular multiplication |x> -> |a*x mod N>.
The standard implementation uses lookup windows and reversible modular
additions. Resource estimation walks this same executable body; it never
substitutes an external arithmetic cost formula. Basis states x >= N
are left unchanged so the operation is a unitary permutation over the full
register space. The FTQC body contains measurement and reset operations;
condition it through the control argument rather than wrapping the
complete operation with :func:qamomile.circuit.control.
Parameters:
| Name | Type | Description |
|---|---|---|
reg | Vector[Qubit] | Little-endian register to multiply in place. Its width must be known when the qkernel is traced. |
multiplier | int | UInt | Positive multiplier a. |
modulus | int | UInt | Modulus N. |
window_size | int | Lookup address width. Defaults to 2. |
inverse_multiplier | int | UInt | None | Multiplicative inverse of multiplier modulo modulus. Python integer inputs compute it automatically. Symbolic inputs must provide it explicitly. Defaults to None. |
control | Qubit | None | Optional control qubit. When provided the multiplication is applied conditionally (as Shor’s order finding conditions each modular multiplication on an exponent qubit). Defaults to None. |
Returns:
Vector[Qubit] | tuple[Qubit, Vector[Qubit]] — Vector[Qubit] | tuple[Qubit, Vector[Qubit]]: The register after modular
Vector[Qubit] | tuple[Qubit, Vector[Qubit]] — multiplication, or (control, register) when a control qubit is
Vector[Qubit] | tuple[Qubit, Vector[Qubit]] — supplied.
Raises:
ValueError— If concrete constants are invalid or symbolic constants omitinverse_multiplier.
Example:
>>> import qamomile.circuit as qmc
>>> from qamomile.circuit.stdlib import modmul_const
>>> @qmc.qkernel
... def mul(reg: qmc.Vector[qmc.Qubit]) -> qmc.Vector[qmc.Qubit]:
... return modmul_const(reg, multiplier=2, modulus=15)qamomile.circuit.stdlib.arithmetic.ripple_carry¶
Implement reversible ripple-carry addition primitives.
Overview¶
| Function | Description |
|---|---|
configure_composite | Configure a QKernel to remain visible as a named composite call. |
ripple_carry_add | Add left into right with a reversible ripple-carry network. |
| Class | Description |
|---|---|
CallPolicy | Describe the default lowering policy for a callable call. |
Functions¶
configure_composite [source]¶
def configure_composite(
kernel: QKernel[..., Any],
*,
name: str | None = None,
namespace: str | None = None,
gate_type: CompositeGateType = CompositeGateType.CUSTOM,
policy: CallPolicy = CallPolicy.PRESERVE_BOX,
implementations: Sequence[CallableImplementation] | None = None,
semantic_arguments: Mapping[str, Any] | None = None,
) -> QKernel[..., Any]Configure a QKernel to remain visible as a named composite call.
This mutates and returns the same QKernel object. No wrapper class or alternate call protocol is introduced.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernel[..., Any] | Kernel to configure. |
name | str | None | Public callable name. Defaults to the kernel name. |
namespace | str | None | Explicit stable callable namespace. None derives one from the decorated function’s module, qualified name, and source location. Defaults to None. |
gate_type | CompositeGateType | Internal stdlib classification. Defaults to CUSTOM. |
policy | CallPolicy | Lowering policy. Defaults to PRESERVE_BOX. |
implementations | Sequence[CallableImplementation] | None | Optional implementation candidates. |
semantic_arguments | Mapping[str, Any] | None | Serializer-friendly arguments that are part of the operation’s meaning rather than its decomposition. Defaults to no semantic arguments. |
Returns:
QKernel[..., Any] — QKernel[..., Any]: The same configured kernel instance.
ripple_carry_add [source]¶
def ripple_carry_add(
left: Vector[Qubit],
right: Vector[Qubit],
carry: Qubit,
overflow: Qubit,
) -> tuple[Vector[Qubit], Vector[Qubit], Qubit, Qubit]Add left into right with a reversible ripple-carry network.
The equally sized registers are little-endian. carry must start in
|0> and is restored to |0>. overflow receives the final carry,
so the output represents the full n + 1 bit sum without discarding
quantum information.
Parameters:
| Name | Type | Description |
|---|---|---|
left | Vector[Qubit] | Little-endian addend register. |
right | Vector[Qubit] | Little-endian accumulator register. |
carry | Qubit | Clean carry workspace qubit, restored on return. |
overflow | Qubit | Qubit receiving the most significant carry bit. |
Returns:
tuple[Vector[Qubit], Vector[Qubit], Qubit, Qubit] — tuple[Vector[Qubit], Vector[Qubit], Qubit, Qubit]: Preserved addend,
summed accumulator, restored carry, and updated overflow qubit.
Classes¶
CallPolicy [source]¶
class CallPolicy(enum.Enum)Describe the default lowering policy for a callable call.
Attributes¶
INLINENATIVE_FIRSTPRESERVE_BOX
qamomile.circuit.stdlib.block_encoding¶
Expose exact block-encoding descriptors and construction factories.
The subpackage groups algorithm-independent operator encodings. Consumers
normally use the stable top-level qamomile.circuit exports, while direct
imports may use this namespace when producer-specific types are needed.
Overview¶
| Function | Description |
|---|---|
identity_block_encoding | Create an exact identity encoding with one pass-through signal. |
ising_z_block_encoding | Create an exact block encoding of a diagonal Ising-Z operator. |
lcu_block_encoding | Compose an ordered LCU of exact child block encodings. |
pauli_lcu_block_encoding | Create a static exact block encoding of a complex Pauli LCU. |
periodic_shift_lcu_block_encoding | Build an LCU block encoding from a periodic-shift decomposition. |
| Class | Description |
|---|---|
IsingZBlockEncoding | Describe one static exact block encoding of an Ising-Z operator. |
LCUBlockEncoding | Describe one static exact LCU block encoding. |
LCUBlockEncodingTerm | Pair a logical coefficient with one exact child block encoding. |
PauliLCUBlockEncoding | Identify an LCU block encoding produced from a Pauli decomposition. |
PeriodicShiftLCUBlockEncoding | Describe one static exact periodic-shift LCU block encoding. |
Functions¶
identity_block_encoding [source]¶
def identity_block_encoding(num_system_qubits: int) -> LCUBlockEncodingCreate an exact identity encoding with one pass-through signal.
The unitary acts as identity on both registers and satisfies
V0^dagger U V0 = I with normalization 1.0. One signal qubit is
retained so the descriptor has the same positive-width ABI required by
reusable circuits, nested SELECT, and all-zero projector consumers.
Parameters:
| Name | Type | Description |
|---|---|---|
num_system_qubits | int | Concrete positive system-register width. |
Returns:
LCUBlockEncoding — Exact identity descriptor with one signal qubit.
Raises:
TypeError— Ifnum_system_qubitsis not an integer.ValueError— Ifnum_system_qubitsis non-positive.
ising_z_block_encoding [source]¶
def ising_z_block_encoding(
coefficients: Mapping[tuple[int, ...], complex],
num_system_qubits: int,
) -> IsingZBlockEncodingCreate an exact block encoding of a diagonal Ising-Z operator.
Each mapping key is a product of Z operators at the listed system-qubit
indices. Repeated indices cancel pairwise because Z**2 = I; the empty
tuple denotes identity. Algebraically equivalent words are aggregated
before constructing
Aggregation is deterministic for the same converted coefficient multiset
on one host/runtime. Inputs that make the host math.fsum overflow an
intermediate partial may be rejected even when their exact final sum is
representable.
A multi-term encoding uses PREPARE amplitudes
sqrt(abs(c_j) / alpha) and SELECT cases
exp(1j * arg(c_j)) * Z_{S_j}. The returned encoding can be used as a
child of another block encoding without converting the operator to a
PauliLCU.
Parameters:
| Name | Type | Description |
|---|---|---|
coefficients | Mapping[tuple[int, ...], complex] | Ising-Z coefficients keyed by products of zero-based system-qubit indices. Coefficients must be finite Python or NumPy real/complex numeric scalars. |
num_system_qubits | int | Positive number of ordered system qubits. |
Returns:
IsingZBlockEncoding — Frozen non-callable block-encoding descriptor.
Raises:
TypeError— Ifcoefficientsis not a mapping, a word is not a tuple, an index is not an integer, or a coefficient has an unsupported scalar type.ValueError— If a width is non-positive, an index is out of range, a coefficient or aggregate is non-finite, or finite coefficient aggregation overflows.RuntimeError— If internal state-preparation width derivation disagrees with the Ising-Z selector width.
Example:
>>> import qamomile.circuit as qmc
>>> encoding = qmc.ising_z_block_encoding(
... {(): 0.25, (0,): -1.0, (0, 1): 0.5j},
... num_system_qubits=2,
... )
>>> @qmc.qkernel
... def circuit() -> tuple[qmc.Vector[qmc.Qubit], qmc.Vector[qmc.Qubit]]:
... signal = qmc.qubit_array(encoding.num_signal_qubits, "signal")
... system = qmc.qubit_array(encoding.num_system_qubits, "system")
... return encoding.unitary(signal, system)lcu_block_encoding [source]¶
def lcu_block_encoding(terms: Sequence[LCUBlockEncodingTerm]) -> LCUBlockEncodingCompose an ordered LCU of exact child block encodings.
Given child encodings U_j satisfying
and logical coefficients c_j, this factory encodes
PREPARE amplitudes are sqrt(abs(c_j) * alpha_j / Lambda) and SELECT
case j applies exp(1j * arg(c_j)) * U_j. Heterogeneous child
signal registers share a pool whose width is the maximum child width.
Every uniform-signature case routes only its leading child-sized slice and
acts exactly as identity on unused padding for arbitrary pool states. The
private parent lowering is [outer selector | shared child pool];
consumers only allocate the reported flat signal register and project all
of it onto zero.
Child descriptors are concrete when this factory runs. Their coefficient
data, angles, and layouts do not become public arguments of the completed
parent unitary. The returned common descriptor may itself be supplied as a
child of another composition or bound later to a reusable qkernel argument
annotated with :class:LCUBlockEncoding.
Children must interpret the ordered system wires in the same logical basis; the common descriptor can validate their widths but cannot infer basis conventions. Generated callable semantic identity across separately constructed descriptors is not part of this API yet. Concrete children are captured when the factory runs, and the completed descriptor supports nesting and compile-time static binding without exposing those children as public qkernel arguments. Qiskit, QuriParts, and CUDA-Q inline these generated bodies. The HUGR target does not currently support recursive LCU composition because SELECT lowering and multiple inline callable-body variants sharing one source-derived reference are not yet supported.
Zero-coefficient terms are removed before normalization and SELECT
construction. A nonempty sequence containing only zero coefficients
creates an exact zero encoding with normalization 1.0 and one signal
qubit; its child system widths must agree so the zero operator’s domain is
defined. An empty sequence is rejected because its system width is
unknowable.
Parameters:
| Name | Type | Description |
|---|---|---|
terms | Sequence[LCUBlockEncodingTerm] | Nonempty ordered child terms. Every active child must use the same ordered system-register width. If all coefficients are zero, every child must use one common width. |
Returns:
LCUBlockEncoding — Exact recursively composable parent descriptor.
Raises:
TypeError— Iftermsis not an ordered sequence or contains a non-term value.ValueError— Iftermsis empty, relevant child system widths differ, or the composed normalization overflows or is non-finite.RuntimeError— If internal state-preparation width derivation disagrees with the recursive selector width.
Example:
>>> import qamomile.circuit as qmc
>>> identity = qmc.identity_block_encoding(1)
>>> encoding = qmc.lcu_block_encoding(
... [
... qmc.LCUBlockEncodingTerm(2.0, identity),
... qmc.LCUBlockEncodingTerm(-0.5j, identity),
... ]
... )
>>> encoding.normalization
2.5pauli_lcu_block_encoding [source]¶
def pauli_lcu_block_encoding(lcu: PauliLCU) -> PauliLCUBlockEncodingCreate a static exact block encoding of a complex Pauli LCU.
For a nonzero decomposition
the descriptor’s qkernel unitary implements U and satisfies
Multi-term encodings use real-amplitude PREPARE weights
sqrt(abs(c_j) / alpha) and SELECT cases
exp(1j * arg(c_j)) * P_j. The identity Pauli word is a normal case, so
its coefficient phase is retained. The zero operator uses one signal
qubit and an X gate, giving an exact zero all-zero block with
normalization 1.0; its PauliLCU.alpha remains 0.0.
The retained Pauli LCU is square, static, and encoded exactly. When
:meth:PauliLCU.from_matrix truncated coefficients, its source-to-retained
error remains available as lcu.truncation_error_bound and is not an
error in this unitary. The unitary accepts arbitrary signal states, returns
the same signal and system wires in the same order, supports
:func:~qamomile.circuit.inverse, and allocates no hidden source-level
logical workspace. Backend-only decomposition scratch is permitted only
when resource-accounted and exactly uncomputed for all inputs, including
under inverse and control.
Parameters:
| Name | Type | Description |
|---|---|---|
lcu | PauliLCU | Immutable retained Pauli decomposition. It must describe at least one system qubit. |
Returns:
PauliLCUBlockEncoding — Frozen non-callable descriptor. Allocate its
registers with num_signal_qubits and num_system_qubits,
then invoke unitary(signal, system).
Raises:
TypeError— Iflcuis not aPauliLCU.ValueError— Iflcurepresents a scalar zero-qubit system.
Example:
>>> import numpy as np
>>> import qamomile.circuit as qmc
>>> from qamomile.linalg import PauliLCU
>>> lcu = PauliLCU.from_matrix(np.array([[0, 1], [0, 0]], complex))
>>> encoding = qmc.pauli_lcu_block_encoding(lcu)
>>> @qmc.qkernel
... def circuit() -> tuple[qmc.Vector[qmc.Qubit], qmc.Vector[qmc.Qubit]]:
... signal = qmc.qubit_array(encoding.num_signal_qubits, "signal")
... system = qmc.qubit_array(encoding.num_system_qubits, "system")
... return encoding.unitary(signal, system)periodic_shift_lcu_block_encoding [source]¶
def periodic_shift_lcu_block_encoding(lcu: PeriodicShiftLCU) -> PeriodicShiftLCUBlockEncodingBuild an LCU block encoding from a periodic-shift decomposition.
lcu defines A = sum_k c_k T_k, where T_k is the modular
translation for one canonical offset tuple. The system is the flattened
concatenation of the decomposition’s LSB-first axis registers. A shift
uses the shorter signed displacement, then emits one ancilla-free
increment or decrement ladder for each set bit of its magnitude. This
bounds the number of Qamomile-level X and multi-controlled-X operations by
a quadratic function of an axis register’s width; backend elementary-gate
cost depends on how that backend decomposes multi-controlled X operations.
The returned descriptor’s unitary acts on arbitrary signal states.
Projecting its signal register onto all zero before and after the unitary
yields A / lambda, where lambda is available as
result.normalization.
The zero operator uses one signal qubit and an X gate, giving an exact
zero all-zero block with normalization 1.0 while lcu.alpha remains
0.0.
A single term retains one pass-through signal qubit for composition but
omits PREPARE and SELECT entirely.
When :meth:PeriodicShiftLCU.from_matrix or
:meth:PeriodicShiftLCU.from_coefficients pruned coefficients, the source
error remains available as lcu.truncation_error_bound and is not an
error in the retained unitary.
Parameters:
| Name | Type | Description |
|---|---|---|
lcu | PeriodicShiftLCU | Immutable retained periodic-shift decomposition. It must describe at least one system qubit. |
Returns:
PeriodicShiftLCUBlockEncoding — Frozen non-callable descriptor containing
the generated shift-LCU unitary and method-specific canonical
metadata.
Raises:
TypeError— Iflcuis not a :class:PeriodicShiftLCU.ValueError— Iflcurepresents a scalar zero-qubit system.
Example:
>>> import qamomile.circuit as qmc
>>> from qamomile.circuit.serialization import deserialize, serialize
>>> from qamomile.linalg import PeriodicShiftLCU
>>> from qamomile.qiskit import QiskitTranspiler
>>> @qmc.qkernel
... def apply_encoding(
... encoding: qmc.LCUBlockEncoding,
... ) -> tuple[qmc.Vector[qmc.Qubit], qmc.Vector[qmc.Qubit]]:
... signal = qmc.qubit_array(encoding.num_signal_qubits, "signal")
... system = qmc.qubit_array(encoding.num_system_qubits, "system")
... return encoding.unitary(signal, system)
>>> payload = serialize(apply_encoding)
>>> received = deserialize(payload)
>>> lcu = PeriodicShiftLCU.from_coefficients(
... {-1: 1.0, 0: -2.0, 1: 1.0},
... register_sizes=(3,),
... )
>>> neighbor_difference = qmc.periodic_shift_lcu_block_encoding(lcu)
>>> isinstance(neighbor_difference, qmc.LCUBlockEncoding)
True
>>> neighbor_difference.normalization
4.0
>>> executable = QiskitTranspiler().transpile(
... received,
... bindings={"encoding": neighbor_difference},
... )Classes¶
IsingZBlockEncoding [source]¶
class IsingZBlockEncoding(LCUBlockEncoding)Describe one static exact block encoding of an Ising-Z operator.
The inherited unitary field has the quantum ABI
unitary(signal, system) -> (signal, system) and no classical
arguments. For the isometry V0 that initializes the complete signal
register to zero, it satisfies
including the complex phases of the Ising-Z coefficients. The unitary allocates no hidden logical qubits and preserves the order of all input wires. Descriptor equality and hashing use object identity.
This producer-specific subtype adds no qkernel-visible fields. Reusable
qkernels should annotate inputs with :class:LCUBlockEncoding so Ising-Z,
Pauli, and recursively composed descriptors share one static binding slot.
Parameters:
| Name | Type | Description |
|---|---|---|
unitary | QKernel | QKernel implementing the static block-encoding unitary. |
normalization | float | Finite positive LCU coefficient one-norm. The exact zero operator uses 1.0. |
num_signal_qubits | int | Positive physical signal-register width, including pass-through padding. |
num_system_qubits | int | Positive ordered system-register width. |
Raises:
TypeError— If a field has an invalid runtime type orunitarydoes not have the required static block-encoding ABI.ValueError— If normalization is non-finite or non-positive, or a register width is non-positive.
Constructor¶
def __init__(
self,
unitary: _BlockEncodingUnitary,
normalization: float,
num_signal_qubits: int,
num_system_qubits: int,
) -> NoneLCUBlockEncoding [source]¶
class LCUBlockEncodingDescribe one static exact LCU block encoding.
unitary is the qkernel implementing the larger unitary U; it is
neither the encoded matrix A nor a dense matrix value. It has no
classical arguments and its quantum ABI is
unitary(signal, system) -> (signal, system). system is the ordered
logical data register on which A acts. signal is the complete
source-level ancilla bundle whose all-zero state selects the encoded block.
The unitary returns the same logical wires in the same order and acts
unitarily for arbitrary signal inputs; after one application, the signal
may have non-zero components rather than returning entirely to zero.
For the all-zero signal isometry V0, the producer must guarantee
including coefficient phase. normalization is finite and positive;
an encoding of the zero operator uses 1.0. Implementations allocate no
hidden source-level logical qubits. A backend may still use temporary
decomposition scratch that is resource-accounted, exactly uncomputed for
every public input, and preserved under inverse and control. Descriptor
comparison and hashing use object identity rather than field values.
This common descriptor deliberately excludes decomposition-specific metadata. Reusable qkernels should annotate an encoding argument with this class so descriptors produced by Pauli and future LCU factories can occupy the same compile-time binding slot.
Parameters:
| Name | Type | Description |
|---|---|---|
unitary | QKernel | QKernel implementing the block-encoding unitary U with the static (signal, system) ABI. |
normalization | float | Finite positive block normalization. |
num_signal_qubits | int | Concrete positive width of the complete signal register, including selectors, logical workspace, and padding required by the producer. |
num_system_qubits | int | Concrete positive width of the ordered system register. |
Raises:
TypeError— Ifunitaryis not aQKernelwith the exact static positional ABI above, normalization is not a real scalar, or either width is not an integer.ValueError— If normalization is non-finite or non-positive, or either width is non-positive.
Constructor¶
def __init__(
self,
unitary: _BlockEncodingUnitary,
normalization: float,
num_signal_qubits: int,
num_system_qubits: int,
) -> NoneAttributes¶
normalization: floatnum_signal_qubits: intnum_system_qubits: intunitary: _BlockEncodingUnitary
LCUBlockEncodingTerm [source]¶
class LCUBlockEncodingTermPair a logical coefficient with one exact child block encoding.
coefficient multiplies the child target matrix A_j, not its
normalized projected block A_j / alpha_j. The recursive composer
therefore assigns the term weight abs(coefficient) * encoding.normalization. Children are concrete construction-time
descriptors; the completed parent, rather than unresolved children, is
the object intended for qkernel static binding.
Parameters:
| Name | Type | Description |
|---|---|---|
coefficient | complex | Finite logical coefficient. Zero terms are removed before nonzero circuit construction. |
encoding | LCUBlockEncoding | Concrete exact child descriptor. Producer subtypes such as PauliLCUBlockEncoding are accepted through the nominal common base class. |
Raises:
TypeError— If the coefficient is not a non-boolean complex numeric scalar orencodingis not anLCUBlockEncoding.ValueError— If a numeric coefficient cannot be converted to a finite built-in complex value or either component is non-finite.
Constructor¶
def __init__(self, coefficient: complex, encoding: LCUBlockEncoding) -> NoneAttributes¶
coefficient: complexencoding: LCUBlockEncoding
PauliLCUBlockEncoding [source]¶
class PauliLCUBlockEncoding(LCUBlockEncoding)Identify an LCU block encoding produced from a Pauli decomposition.
The subtype adds no qkernel-visible fields. Reusable qkernels should
annotate encoding arguments with :class:LCUBlockEncoding; the Pauli
subtype remains available for producer-specific host-side code and
backward-compatible serialized templates.
Parameters:
| Name | Type | Description |
|---|---|---|
unitary | QKernel | QKernel implementing the exact block-encoding unitary with the static (signal, system) ABI. |
normalization | float | Finite positive block normalization. |
num_signal_qubits | int | Concrete positive width of the complete signal register. |
num_system_qubits | int | Concrete positive width of the ordered system register. |
Raises:
TypeError— If an inherited descriptor field has an invalid type or the unitary ABI is invalid.ValueError— If normalization or a register width is non-positive or non-finite.
Constructor¶
def __init__(
self,
unitary: _BlockEncodingUnitary,
normalization: float,
num_signal_qubits: int,
num_system_qubits: int,
) -> NonePeriodicShiftLCUBlockEncoding [source]¶
class PeriodicShiftLCUBlockEncoding(LCUBlockEncoding)Describe one static exact periodic-shift LCU block encoding.
unitary is the qkernel implementing the larger unitary U; it is
neither the encoded periodic-shift matrix A nor a dense matrix value. It has
no classical arguments and its quantum ABI is
unitary(signal, system) -> (signal, system). system is the ordered
flattened data register on which A acts. signal is the complete
source-level ancilla bundle whose all-zero state selects the encoded
block. The unitary returns the same logical wires in the same order and
acts unitarily for arbitrary signal inputs; signal need not return to zero
after one application.
For the all-zero signal isometry V0, the encoded periodic-shift matrix
satisfies
including coefficient phase. The construction is exact in ideal logical arithmetic; host floating-point roundoff in state-preparation angles and backend gate synthesis are outside this semantic equality. This producer allocates no hidden source-level logical qubits. Backend decomposition scratch is permitted only when resource-accounted and exactly uncomputed for every input, including under inverse and control. Descriptor comparison and hashing use object identity rather than field values.
The inherited fields form the qkernel-visible static LCU contract.
register_sizes, offsets, and coefficients are deeply immutable
producer metadata for host-side inspection only. A producer-specific
qkernel may annotate an argument with this class. Reusable qkernels should
instead annotate descriptor arguments with :class:LCUBlockEncoding,
allowing the same serialized template to accept this and other exact LCU
producers.
Parameters:
| Name | Type | Description |
|---|---|---|
unitary | qmc.QKernel | QKernel implementing the block-encoding unitary U with the static (signal, system) ABI. |
normalization | float | Finite positive LCU normalization sum(abs(coefficients)) after equivalent periodic offsets are combined. Direct construction accepts relative disagreement up to 1e-12 for host rounding and stores the canonical coefficient-derived sum. The empty zero-operator representation instead uses 1.0. |
num_signal_qubits | int | Concrete positive width of the complete signal register, including selector padding. |
num_system_qubits | int | Concrete positive width of the ordered flat system register. |
register_sizes | tuple[int, ...] | Qubit widths of the flattened system register’s axes. |
offsets | tuple[tuple[int, ...], ...] | Canonical modular offsets, in SELECT case order. The empty tuple represents the zero operator. |
coefficients | tuple[complex, ...] | Nonzero combined coefficients, in SELECT case order. The empty tuple represents the zero operator. |
Raises:
TypeError— If the common block-encoding fields or method-specific metadata have invalid runtime types.ValueError— If normalization or a width is invalid, method-specific metadata is inconsistent, or offsets are not canonical.
Constructor¶
def __init__(
self,
unitary: _BlockEncodingUnitary,
normalization: float,
num_signal_qubits: int,
num_system_qubits: int,
register_sizes: tuple[int, ...],
offsets: tuple[tuple[int, ...], ...],
coefficients: tuple[complex, ...],
) -> NoneAttributes¶
coefficients: tuple[complex, ...]offsets: tuple[tuple[int, ...], ...]register_sizes: tuple[int, ...]
qamomile.circuit.stdlib.block_encoding.ising_z¶
Build exact block encodings of diagonal Ising-Z operators.
Overview¶
| Function | Description |
|---|---|
configure_composite | Configure a QKernel to remain visible as a named composite call. |
global_phase | Apply a qkernel call followed by exp(i * phase). |
ising_z_block_encoding | Create an exact block encoding of a diagonal Ising-Z operator. |
qkernel | Decorator to define a Qamomile quantum kernel. |
z | Pauli-Z gate. |
| Class | Description |
|---|---|
CallPolicy | Describe the default lowering policy for a callable call. |
IsingZBlockEncoding | Describe one static exact block encoding of an Ising-Z operator. |
LCUBlockEncoding | Describe one static exact LCU block encoding. |
QKernel | Decorator class for Qamomile quantum kernels. |
Functions¶
configure_composite [source]¶
def configure_composite(
kernel: QKernel[..., Any],
*,
name: str | None = None,
namespace: str | None = None,
gate_type: CompositeGateType = CompositeGateType.CUSTOM,
policy: CallPolicy = CallPolicy.PRESERVE_BOX,
implementations: Sequence[CallableImplementation] | None = None,
semantic_arguments: Mapping[str, Any] | None = None,
) -> QKernel[..., Any]Configure a QKernel to remain visible as a named composite call.
This mutates and returns the same QKernel object. No wrapper class or alternate call protocol is introduced.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernel[..., Any] | Kernel to configure. |
name | str | None | Public callable name. Defaults to the kernel name. |
namespace | str | None | Explicit stable callable namespace. None derives one from the decorated function’s module, qualified name, and source location. Defaults to None. |
gate_type | CompositeGateType | Internal stdlib classification. Defaults to CUSTOM. |
policy | CallPolicy | Lowering policy. Defaults to PRESERVE_BOX. |
implementations | Sequence[CallableImplementation] | None | Optional implementation candidates. |
semantic_arguments | Mapping[str, Any] | None | Serializer-friendly arguments that are part of the operation’s meaning rather than its decomposition. Defaults to no semantic arguments. |
Returns:
QKernel[..., Any] — QKernel[..., Any]: The same configured kernel instance.
global_phase [source]¶
def global_phase(target: QKernel | Callable[..., Any], phase: PhaseValue) -> GlobalPhaseGateApply a qkernel call followed by exp(i * phase).
The phase is represented as a zero-qubit operation and is retained even when it is not observable in the surrounding program. A reversible qkernel containing the operation acquires an observable relative phase when it is coherently controlled. Measurement, reset, allocation, classical outputs, and classical-only qkernels remain valid for ordinary standalone use.
Parameters:
| Name | Type | Description |
|---|---|---|
target | QKernel | Callable[..., Any] | QKernel or gate-like callable whose call is followed by the global phase. |
phase | float | int | Float | Phase angle in radians, supplied as a Qamomile Float handle or Python numeric literal. |
Returns:
GlobalPhaseGate — Callable wrapper with the target’s call interface.
Raises:
TypeError— Iftargetcannot be interpreted as a gate-like callable.
Example:
>>> import qamomile.circuit as qmc
>>> @qmc.qkernel
... def step(q: qmc.Qubit) -> qmc.Qubit:
... return qmc.x(q)
>>> @qmc.qkernel
... def phased_step(q: qmc.Qubit) -> qmc.Qubit:
... return qmc.global_phase(step, 0.7)(q)ising_z_block_encoding [source]¶
def ising_z_block_encoding(
coefficients: Mapping[tuple[int, ...], complex],
num_system_qubits: int,
) -> IsingZBlockEncodingCreate an exact block encoding of a diagonal Ising-Z operator.
Each mapping key is a product of Z operators at the listed system-qubit
indices. Repeated indices cancel pairwise because Z**2 = I; the empty
tuple denotes identity. Algebraically equivalent words are aggregated
before constructing
Aggregation is deterministic for the same converted coefficient multiset
on one host/runtime. Inputs that make the host math.fsum overflow an
intermediate partial may be rejected even when their exact final sum is
representable.
A multi-term encoding uses PREPARE amplitudes
sqrt(abs(c_j) / alpha) and SELECT cases
exp(1j * arg(c_j)) * Z_{S_j}. The returned encoding can be used as a
child of another block encoding without converting the operator to a
PauliLCU.
Parameters:
| Name | Type | Description |
|---|---|---|
coefficients | Mapping[tuple[int, ...], complex] | Ising-Z coefficients keyed by products of zero-based system-qubit indices. Coefficients must be finite Python or NumPy real/complex numeric scalars. |
num_system_qubits | int | Positive number of ordered system qubits. |
Returns:
IsingZBlockEncoding — Frozen non-callable block-encoding descriptor.
Raises:
TypeError— Ifcoefficientsis not a mapping, a word is not a tuple, an index is not an integer, or a coefficient has an unsupported scalar type.ValueError— If a width is non-positive, an index is out of range, a coefficient or aggregate is non-finite, or finite coefficient aggregation overflows.RuntimeError— If internal state-preparation width derivation disagrees with the Ising-Z selector width.
Example:
>>> import qamomile.circuit as qmc
>>> encoding = qmc.ising_z_block_encoding(
... {(): 0.25, (0,): -1.0, (0, 1): 0.5j},
... num_system_qubits=2,
... )
>>> @qmc.qkernel
... def circuit() -> tuple[qmc.Vector[qmc.Qubit], qmc.Vector[qmc.Qubit]]:
... signal = qmc.qubit_array(encoding.num_signal_qubits, "signal")
... system = qmc.qubit_array(encoding.num_system_qubits, "system")
... return encoding.unitary(signal, system)qkernel [source]¶
def qkernel(func: Callable[P, R]) -> QKernel[P, R]Decorator to define a Qamomile quantum kernel.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable[P, R] | Function to decorate. |
Returns:
QKernel[P, R] — QKernel[P, R]: QKernel wrapping the function.
z [source]¶
def z(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]Pauli-Z gate.
Broadcasts over a Vector[Qubit] when applied to one.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Union[Qubit, Vector[Qubit]] | A single Qubit or a Vector[Qubit]. |
Returns:
Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.
Raises:
TypeError— Iftargetis neither aQubitnor aVector[Qubit].
Classes¶
CallPolicy [source]¶
class CallPolicy(enum.Enum)Describe the default lowering policy for a callable call.
Attributes¶
INLINENATIVE_FIRSTPRESERVE_BOX
IsingZBlockEncoding [source]¶
class IsingZBlockEncoding(LCUBlockEncoding)Describe one static exact block encoding of an Ising-Z operator.
The inherited unitary field has the quantum ABI
unitary(signal, system) -> (signal, system) and no classical
arguments. For the isometry V0 that initializes the complete signal
register to zero, it satisfies
including the complex phases of the Ising-Z coefficients. The unitary allocates no hidden logical qubits and preserves the order of all input wires. Descriptor equality and hashing use object identity.
This producer-specific subtype adds no qkernel-visible fields. Reusable
qkernels should annotate inputs with :class:LCUBlockEncoding so Ising-Z,
Pauli, and recursively composed descriptors share one static binding slot.
Parameters:
| Name | Type | Description |
|---|---|---|
unitary | QKernel | QKernel implementing the static block-encoding unitary. |
normalization | float | Finite positive LCU coefficient one-norm. The exact zero operator uses 1.0. |
num_signal_qubits | int | Positive physical signal-register width, including pass-through padding. |
num_system_qubits | int | Positive ordered system-register width. |
Raises:
TypeError— If a field has an invalid runtime type orunitarydoes not have the required static block-encoding ABI.ValueError— If normalization is non-finite or non-positive, or a register width is non-positive.
Constructor¶
def __init__(
self,
unitary: _BlockEncodingUnitary,
normalization: float,
num_signal_qubits: int,
num_system_qubits: int,
) -> NoneLCUBlockEncoding [source]¶
class LCUBlockEncodingDescribe one static exact LCU block encoding.
unitary is the qkernel implementing the larger unitary U; it is
neither the encoded matrix A nor a dense matrix value. It has no
classical arguments and its quantum ABI is
unitary(signal, system) -> (signal, system). system is the ordered
logical data register on which A acts. signal is the complete
source-level ancilla bundle whose all-zero state selects the encoded block.
The unitary returns the same logical wires in the same order and acts
unitarily for arbitrary signal inputs; after one application, the signal
may have non-zero components rather than returning entirely to zero.
For the all-zero signal isometry V0, the producer must guarantee
including coefficient phase. normalization is finite and positive;
an encoding of the zero operator uses 1.0. Implementations allocate no
hidden source-level logical qubits. A backend may still use temporary
decomposition scratch that is resource-accounted, exactly uncomputed for
every public input, and preserved under inverse and control. Descriptor
comparison and hashing use object identity rather than field values.
This common descriptor deliberately excludes decomposition-specific metadata. Reusable qkernels should annotate an encoding argument with this class so descriptors produced by Pauli and future LCU factories can occupy the same compile-time binding slot.
Parameters:
| Name | Type | Description |
|---|---|---|
unitary | QKernel | QKernel implementing the block-encoding unitary U with the static (signal, system) ABI. |
normalization | float | Finite positive block normalization. |
num_signal_qubits | int | Concrete positive width of the complete signal register, including selectors, logical workspace, and padding required by the producer. |
num_system_qubits | int | Concrete positive width of the ordered system register. |
Raises:
TypeError— Ifunitaryis not aQKernelwith the exact static positional ABI above, normalization is not a real scalar, or either width is not an integer.ValueError— If normalization is non-finite or non-positive, or either width is non-positive.
Constructor¶
def __init__(
self,
unitary: _BlockEncodingUnitary,
normalization: float,
num_signal_qubits: int,
num_system_qubits: int,
) -> NoneAttributes¶
normalization: floatnum_signal_qubits: intnum_system_qubits: intunitary: _BlockEncodingUnitary
QKernel [source]¶
class QKernel(QKernelBuildMixin, QKernelVisualizationMixin, Generic[P, R])Decorator class for Qamomile quantum kernels.
Constructor¶
def __init__(self, func: Callable[P, R]) -> NoneAttributes¶
block: Block Compile the function to a hierarchical Block if not already compiled.effects: KernelEffect Return cached semantic effects of this qkernel.funcinput_types: dict[str, Any] Return resolved and frozen frontend input annotations.nameoutput_types: list[Any] Return the resolved frontend annotation for every output slot.raw_funcreturn_type: Any Return the resolved and frozen complete return annotation.signature
qamomile.circuit.stdlib.block_encoding.lcu¶
Define the common static descriptor contract for exact LCU encodings.
Overview¶
| Function | Description |
|---|---|
get_size | Return the size of a Vector handle as a Python integer. |
global_phase | Apply a qkernel call followed by exp(i * phase). |
identity_block_encoding | Create an exact identity encoding with one pass-through signal. |
inverse | Create an inverse operation wrapper. |
lcu_block_encoding | Compose an ordered LCU of exact child block encodings. |
merge_quantum_operand_widths | Merge exact quantum widths into serializer-friendly callable attrs. |
qkernel | Decorator to define a Qamomile quantum kernel. |
qkernel_callable_attrs | Return compiler attrs for a qkernel invocation. |
quantum_operand_widths | Decode exact quantum-operand widths from callable resource metadata. |
register_static_binding | Register one closed compile-time object adapter. |
select | Create a quantum multiplexer (SELECT) over a list of unitaries. |
uint | Create a UInt handle from an integer literal or a named parameter. |
x | Pauli-X gate (NOT gate). |
| Class | Description |
|---|---|
CallPolicy | Describe the default lowering policy for a callable call. |
LCUBlockEncoding | Describe one static exact LCU block encoding. |
LCUBlockEncodingTerm | Pair a logical coefficient with one exact child block encoding. |
QKernel | Decorator class for Qamomile quantum kernels. |
QuantumOperandWidth | Describe one exact source-callable quantum operand width. |
StaticBindingFieldSpec | Describe one scalar field exposed by a static-binding proxy. |
StaticBindingMemberSpec | Describe one deferred qkernel-valued member of a static binding. |
StaticBindingSpec | Register the closed qkernel surface of one compile-time object type. |
Functions¶
get_size [source]¶
def get_size(arr: Vector[_H]) -> intReturn the size of a Vector handle as a Python integer.
Resolves the leading axis of arr.shape through two forms a
Vector shape entry can take:
A plain Python
int(built-in bound shape; this is what you get fromqmc.qubit_array(N, ...)for literalN).A
UInthandle whose underlyingValuecarries a compile-time constant (set byuint(literal),_create_bound_input, or partial evaluation).
A UInt handle whose underlying Value is not a constant is
treated as an unresolved symbolic dimension and raises
ValueError even when the handle has the dataclass-default
init_value=0. Falling back to init_value for that case
would silently turn a runtime-symbolic Vector[Float] parameter
into a “size 0” array, hiding programming errors. Callers that
need to handle symbolic shapes (e.g., to emit a deferred callable
when the size is unknown) must catch the ValueError themselves.
Parameters:
| Name | Type | Description |
|---|---|---|
arr | Vector[Handle] | Vector handle whose first axis size is requested. |
Returns:
int — The first-axis size as a plain Python int.
Raises:
TypeError— If arr is not a 1-DVectorhandle (Vectoror itsVectorViewsubclass) — e.g., a scalarQubitwas passed where aVectoris required, a higher-rankMatrix/Tensorwas passed (this helper only resolves a 1-D first-axis size), or an unrelatedshape-bearing object such as a numpy array. This is a clearer signal than the bareAttributeErrorthatarr.shapewould otherwise raise, and it guards the stdlib / composite callers that resolve a register size through this helper.ValueError— If the shape cannot be resolved to a concrete integer — e.g., the Vector is a runtime-parametric handle without compile-time bindings, or carries aUIntdimension whose underlyingValuehas not been promoted to a constant.
global_phase [source]¶
def global_phase(target: QKernel | Callable[..., Any], phase: PhaseValue) -> GlobalPhaseGateApply a qkernel call followed by exp(i * phase).
The phase is represented as a zero-qubit operation and is retained even when it is not observable in the surrounding program. A reversible qkernel containing the operation acquires an observable relative phase when it is coherently controlled. Measurement, reset, allocation, classical outputs, and classical-only qkernels remain valid for ordinary standalone use.
Parameters:
| Name | Type | Description |
|---|---|---|
target | QKernel | Callable[..., Any] | QKernel or gate-like callable whose call is followed by the global phase. |
phase | float | int | Float | Phase angle in radians, supplied as a Qamomile Float handle or Python numeric literal. |
Returns:
GlobalPhaseGate — Callable wrapper with the target’s call interface.
Raises:
TypeError— Iftargetcannot be interpreted as a gate-like callable.
Example:
>>> import qamomile.circuit as qmc
>>> @qmc.qkernel
... def step(q: qmc.Qubit) -> qmc.Qubit:
... return qmc.x(q)
>>> @qmc.qkernel
... def phased_step(q: qmc.Qubit) -> qmc.Qubit:
... return qmc.global_phase(step, 0.7)(q)identity_block_encoding [source]¶
def identity_block_encoding(num_system_qubits: int) -> LCUBlockEncodingCreate an exact identity encoding with one pass-through signal.
The unitary acts as identity on both registers and satisfies
V0^dagger U V0 = I with normalization 1.0. One signal qubit is
retained so the descriptor has the same positive-width ABI required by
reusable circuits, nested SELECT, and all-zero projector consumers.
Parameters:
| Name | Type | Description |
|---|---|---|
num_system_qubits | int | Concrete positive system-register width. |
Returns:
LCUBlockEncoding — Exact identity descriptor with one signal qubit.
Raises:
TypeError— Ifnum_system_qubitsis not an integer.ValueError— Ifnum_system_qubitsis non-positive.
inverse [source]¶
def inverse(target: Oracle | TransformedOracle | QKernelLike | Callable[..., Any]) -> AnyCreate an inverse operation wrapper.
Native Qamomile gate functions are first synthesized into tiny
QKernel objects, then inverted with the same block walker used for
user-defined kernels. Qkernel-like composite gate callables created by
qmc.composite_gate reuse their wrapped qkernel body. Known QFT/IQFT
functions map directly to their counterpart so backend-native composite
emission remains available. Opaque Oracles retain their original
definition and cost boundary while the call records an inverse transform;
the result can be passed directly to qmc.control. Inverting an already
controlled Oracle produces the same transformed invocation as controlling
its inverse.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Oracle | TransformedOracle | QKernelLike | Callable[..., Any] | Opaque Oracle, transformed Oracle, native gate function, qkernel-like object, or supported stdlib function to invert. |
Returns:
Any — A callable inverse wrapper, or the opposite QFT/IQFT function.
Raises:
TypeError— Iftargetcannot be interpreted as a gate-like callable, or if a body-free class-based composite instance is passed directly.NotImplementedError— If an inverted kernel uses unsupported operations such asif/while/for itemscontrol flow,QInit, or aForOperationwhose bounds are not compile-time constants when the inverse wrapper is traced. Loop-carried classical values are supported for UInt carries with a constant additive recurrence and for unchanged Float carries. Nonzero Float recurrences, non-additive recurrences, and coupled carries are rejected uniformly before backend emission.
Example:
>>> import qamomile.circuit as qmc
>>> @qmc.qkernel
... def layer(q: qmc.Qubit, angle: qmc.Float) -> qmc.Qubit:
... q = qmc.h(q)
... q = qmc.rz(q, angle)
... return q
>>> @qmc.qkernel
... def circuit(angle: qmc.Float) -> qmc.Qubit:
... q = qmc.qubit("q")
... q = layer(q, angle)
... q = qmc.inverse(layer)(q, angle)
... return qlcu_block_encoding [source]¶
def lcu_block_encoding(terms: Sequence[LCUBlockEncodingTerm]) -> LCUBlockEncodingCompose an ordered LCU of exact child block encodings.
Given child encodings U_j satisfying
and logical coefficients c_j, this factory encodes
PREPARE amplitudes are sqrt(abs(c_j) * alpha_j / Lambda) and SELECT
case j applies exp(1j * arg(c_j)) * U_j. Heterogeneous child
signal registers share a pool whose width is the maximum child width.
Every uniform-signature case routes only its leading child-sized slice and
acts exactly as identity on unused padding for arbitrary pool states. The
private parent lowering is [outer selector | shared child pool];
consumers only allocate the reported flat signal register and project all
of it onto zero.
Child descriptors are concrete when this factory runs. Their coefficient
data, angles, and layouts do not become public arguments of the completed
parent unitary. The returned common descriptor may itself be supplied as a
child of another composition or bound later to a reusable qkernel argument
annotated with :class:LCUBlockEncoding.
Children must interpret the ordered system wires in the same logical basis; the common descriptor can validate their widths but cannot infer basis conventions. Generated callable semantic identity across separately constructed descriptors is not part of this API yet. Concrete children are captured when the factory runs, and the completed descriptor supports nesting and compile-time static binding without exposing those children as public qkernel arguments. Qiskit, QuriParts, and CUDA-Q inline these generated bodies. The HUGR target does not currently support recursive LCU composition because SELECT lowering and multiple inline callable-body variants sharing one source-derived reference are not yet supported.
Zero-coefficient terms are removed before normalization and SELECT
construction. A nonempty sequence containing only zero coefficients
creates an exact zero encoding with normalization 1.0 and one signal
qubit; its child system widths must agree so the zero operator’s domain is
defined. An empty sequence is rejected because its system width is
unknowable.
Parameters:
| Name | Type | Description |
|---|---|---|
terms | Sequence[LCUBlockEncodingTerm] | Nonempty ordered child terms. Every active child must use the same ordered system-register width. If all coefficients are zero, every child must use one common width. |
Returns:
LCUBlockEncoding — Exact recursively composable parent descriptor.
Raises:
TypeError— Iftermsis not an ordered sequence or contains a non-term value.ValueError— Iftermsis empty, relevant child system widths differ, or the composed normalization overflows or is non-finite.RuntimeError— If internal state-preparation width derivation disagrees with the recursive selector width.
Example:
>>> import qamomile.circuit as qmc
>>> identity = qmc.identity_block_encoding(1)
>>> encoding = qmc.lcu_block_encoding(
... [
... qmc.LCUBlockEncodingTerm(2.0, identity),
... qmc.LCUBlockEncodingTerm(-0.5j, identity),
... ]
... )
>>> encoding.normalization
2.5merge_quantum_operand_widths [source]¶
def merge_quantum_operand_widths(
attrs: Mapping[str, Any],
widths: Sequence[QuantumOperandWidth],
*,
source: str,
operand_count: int | None = None,
conflict_labels: Mapping[int, str] | None = None,
) -> dict[str, Any]Merge exact quantum widths into serializer-friendly callable attrs.
Existing resource-contract keys are preserved. Width entries are merged by quantum-operand index, compatible partial declarations are completed, and the encoded list is canonicalized by index.
Parameters:
| Name | Type | Description |
|---|---|---|
attrs | Mapping[str, Any] | Existing callable attributes. |
widths | Sequence[QuantumOperandWidth] | Width declarations to merge. |
source | str | Callable name used in malformed-contract diagnostics. |
operand_count | int | None | Optional quantum operand count used to reject out-of-range entries. Defaults to None. |
conflict_labels | Mapping[int, str] | None | Optional caller-facing field labels used for width-conflict diagnostics. Defaults to operand-index diagnostics. |
Returns:
dict[str, Any] — dict[str, Any]: Copied attributes with the merged resource contract.
Raises:
ValueError— If the existing or requested contract is malformed, repeats or conflicts at an operand index, or references an index outsideoperand_count.
qkernel [source]¶
def qkernel(func: Callable[P, R]) -> QKernel[P, R]Decorator to define a Qamomile quantum kernel.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable[P, R] | Function to decorate. |
Returns:
QKernel[P, R] — QKernel[P, R]: QKernel wrapping the function.
qkernel_callable_attrs [source]¶
def qkernel_callable_attrs(kernel: Any) -> dict[str, Any]Return compiler attrs for a qkernel invocation.
Composite metadata lives directly on QKernel. This helper is the
single translation point from that frontend state into serializer-safe IR
attributes, so direct, controlled, and inverse calls share one identity.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object carrying callable metadata. |
Returns:
dict[str, Any] — dict[str, Any]: Serializer-friendly callable attributes.
quantum_operand_widths [source]¶
def quantum_operand_widths(attrs: Mapping[str, Any], *, source: str) -> tuple[QuantumOperandWidth, ...]Decode exact quantum-operand widths from callable resource metadata.
Parameters:
| Name | Type | Description |
|---|---|---|
attrs | Mapping[str, Any] | Callable definition or operation attrs. |
source | str | Callable name used in malformed-contract diagnostics. |
Returns:
tuple[QuantumOperandWidth, ...] — tuple[QuantumOperandWidth, ...]: Validated exact-width entries, or an
empty tuple when the callable declares no such contract.
Raises:
ValueError— If present resource metadata is malformed or repeats an operand index.
register_static_binding [source]¶
def register_static_binding(spec: StaticBindingSpec) -> NoneRegister one closed compile-time object adapter.
Parameters:
| Name | Type | Description |
|---|---|---|
spec | StaticBindingSpec | Adapter contract to register. |
Raises:
TypeError— If the annotation or type key has the wrong type, or if a field getter, field handle, or deferred member ABI is unsupported.ValueError— If the annotation or stable type key is already registered, or if the contract is empty or malformed.
select [source]¶
def select(
cases: Sequence['QKernel | Callable[..., Any]'],
num_index_qubits: int | UInt | None = None,
) -> SelectGateCreate a quantum multiplexer (SELECT) over a list of unitaries.
The returned gate applies cases[i] to a shared target register
when the index register reads the integer i with index qubit zero as
the least-significant bit. len(cases) need not be a power of
two; index values >= len(cases) apply no operation.
A scalar Qubit case called with a Vector[Qubit] or
VectorView[Qubit] target is applied independently to every element.
This is the same tensor-product unitary as an explicit per-element loop,
including one copy of the scalar case’s global phase per element. A phase
intended for the complete register belongs on a case whose parameter is
itself Vector[Qubit].
Circuit-family lowering retains the abstract SELECT identity while its
portable fallback invokes each case under the corresponding mixed
0/1 (anti-/normal) index pattern.
Parameters:
| Name | Type | Description |
|---|---|---|
cases | Sequence[QKernel | Callable[..., Any]] | The case unitaries in ascending index order. Each may be a @qmc.qkernel function, a qkernel-backed composite gate, or a built-in gate callable. All cases must share the same parameter signature and act on the same target register. |
num_index_qubits | int | UInt | None | Number of leading index qubits. None infers the minimal width from the case count. A wider concrete value leaves its unassigned index states as identity. UInt defers the width check to transpilation. Defaults to None. |
Returns:
SelectGate — A callable applied as sel(index, *targets, **params).
Raises:
ValueError— If fewer than two cases are supplied, a concrete width is too small, or the cases do not share an identical parameter signature. Case-body footprint and unitarity are validated when the returned gate is called.TypeError— If the width has an unsupported type or a case cannot be wrapped into a qkernel.
Example:
>>> import qamomile.circuit as qm
>>> @qm.qkernel
... def pick() -> qm.Vector[qm.Bit]:
... idx = qm.qubit_array(2, name="idx")
... idx = qm.h(idx)
... t = qm.qubit(name="t")
... idx, t = qm.select([qm.x, qm.y, qm.z, qm.h])(idx, t)
... return qm.measure(idx)uint [source]¶
def uint(arg: int | str) -> UIntCreate a UInt handle from an integer literal or a named parameter.
Parameters:
| Name | Type | Description |
|---|---|---|
arg | int | str | An integer literal to bake in as a compile-time constant, or a str naming a symbolic UInt parameter. A bool is rejected: True / False are not valid integer values here even though bool subclasses int. (Sign is not validated here -- a negative literal is accepted and baked in as-is.) |
Returns:
UInt — A constant-valued handle for an int argument, or a named
symbolic handle for a str argument.
Raises:
TypeError— Ifargis neither a plainintnor astr(in particular, if it is abool).
x [source]¶
def x(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]Pauli-X gate (NOT gate).
Broadcasts over a Vector[Qubit] when applied to one.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Union[Qubit, Vector[Qubit]] | A single Qubit or a Vector[Qubit]. |
Returns:
Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.
Raises:
TypeError— Iftargetis neither aQubitnor aVector[Qubit].
Classes¶
CallPolicy [source]¶
class CallPolicy(enum.Enum)Describe the default lowering policy for a callable call.
Attributes¶
INLINENATIVE_FIRSTPRESERVE_BOX
LCUBlockEncoding [source]¶
class LCUBlockEncodingDescribe one static exact LCU block encoding.
unitary is the qkernel implementing the larger unitary U; it is
neither the encoded matrix A nor a dense matrix value. It has no
classical arguments and its quantum ABI is
unitary(signal, system) -> (signal, system). system is the ordered
logical data register on which A acts. signal is the complete
source-level ancilla bundle whose all-zero state selects the encoded block.
The unitary returns the same logical wires in the same order and acts
unitarily for arbitrary signal inputs; after one application, the signal
may have non-zero components rather than returning entirely to zero.
For the all-zero signal isometry V0, the producer must guarantee
including coefficient phase. normalization is finite and positive;
an encoding of the zero operator uses 1.0. Implementations allocate no
hidden source-level logical qubits. A backend may still use temporary
decomposition scratch that is resource-accounted, exactly uncomputed for
every public input, and preserved under inverse and control. Descriptor
comparison and hashing use object identity rather than field values.
This common descriptor deliberately excludes decomposition-specific metadata. Reusable qkernels should annotate an encoding argument with this class so descriptors produced by Pauli and future LCU factories can occupy the same compile-time binding slot.
Parameters:
| Name | Type | Description |
|---|---|---|
unitary | QKernel | QKernel implementing the block-encoding unitary U with the static (signal, system) ABI. |
normalization | float | Finite positive block normalization. |
num_signal_qubits | int | Concrete positive width of the complete signal register, including selectors, logical workspace, and padding required by the producer. |
num_system_qubits | int | Concrete positive width of the ordered system register. |
Raises:
TypeError— Ifunitaryis not aQKernelwith the exact static positional ABI above, normalization is not a real scalar, or either width is not an integer.ValueError— If normalization is non-finite or non-positive, or either width is non-positive.
Constructor¶
def __init__(
self,
unitary: _BlockEncodingUnitary,
normalization: float,
num_signal_qubits: int,
num_system_qubits: int,
) -> NoneAttributes¶
normalization: floatnum_signal_qubits: intnum_system_qubits: intunitary: _BlockEncodingUnitary
LCUBlockEncodingTerm [source]¶
class LCUBlockEncodingTermPair a logical coefficient with one exact child block encoding.
coefficient multiplies the child target matrix A_j, not its
normalized projected block A_j / alpha_j. The recursive composer
therefore assigns the term weight abs(coefficient) * encoding.normalization. Children are concrete construction-time
descriptors; the completed parent, rather than unresolved children, is
the object intended for qkernel static binding.
Parameters:
| Name | Type | Description |
|---|---|---|
coefficient | complex | Finite logical coefficient. Zero terms are removed before nonzero circuit construction. |
encoding | LCUBlockEncoding | Concrete exact child descriptor. Producer subtypes such as PauliLCUBlockEncoding are accepted through the nominal common base class. |
Raises:
TypeError— If the coefficient is not a non-boolean complex numeric scalar orencodingis not anLCUBlockEncoding.ValueError— If a numeric coefficient cannot be converted to a finite built-in complex value or either component is non-finite.
Constructor¶
def __init__(self, coefficient: complex, encoding: LCUBlockEncoding) -> NoneAttributes¶
coefficient: complexencoding: LCUBlockEncoding
QKernel [source]¶
class QKernel(QKernelBuildMixin, QKernelVisualizationMixin, Generic[P, R])Decorator class for Qamomile quantum kernels.
Constructor¶
def __init__(self, func: Callable[P, R]) -> NoneAttributes¶
block: Block Compile the function to a hierarchical Block if not already compiled.effects: KernelEffect Return cached semantic effects of this qkernel.funcinput_types: dict[str, Any] Return resolved and frozen frontend input annotations.nameoutput_types: list[Any] Return the resolved frontend annotation for every output slot.raw_funcreturn_type: Any Return the resolved and frozen complete return annotation.signature
QuantumOperandWidth [source]¶
class QuantumOperandWidthDescribe one exact source-callable quantum operand width.
Parameters:
| Name | Type | Description |
|---|---|---|
index | int | Position among quantum operands only. |
name | str | User-facing register name. |
width | int | Required scalar qubit width. |
Constructor¶
def __init__(self, index: int, name: str, width: int) -> NoneAttributes¶
index: intname: strwidth: int
StaticBindingFieldSpec [source]¶
class StaticBindingFieldSpecDescribe one scalar field exposed by a static-binding proxy.
Parameters:
| Name | Type | Description |
|---|---|---|
handle_type | type[Handle] | Frontend scalar handle returned while tracing an unbound qkernel. |
getter | Callable[[Any], int | float] | Extractor used when a concrete object is bound. |
Constructor¶
def __init__(self, handle_type: type[Handle], getter: Callable[[Any], int | float]) -> NoneAttributes¶
getter: Callable[[Any], int | float]handle_type: type[Handle]
StaticBindingMemberSpec [source]¶
class StaticBindingMemberSpecDescribe one deferred qkernel-valued member of a static binding.
Parameters:
| Name | Type | Description |
|---|---|---|
input_types | Mapping[str, Any] | Ordered frontend input annotations. |
output_types | tuple[Any, ...] | Ordered frontend result annotations. |
return_annotation | Any | Complete Python return annotation. |
getter | Callable[[Any], Any] | Extractor returning the concrete qkernel-like member. |
qubit_width_fields | Mapping[str, str] | Input-name to scalar field-name mapping used to specialize quantum vector widths. |
Constructor¶
def __init__(
self,
input_types: Mapping[str, Any],
output_types: tuple[Any, ...],
return_annotation: Any,
getter: Callable[[Any], Any],
qubit_width_fields: Mapping[str, str] = dict(),
) -> NoneAttributes¶
getter: Callable[[Any], Any]input_types: Mapping[str, Any]output_types: tuple[Any, ...]qubit_width_fields: Mapping[str, str]return_annotation: Any
StaticBindingSpec [source]¶
class StaticBindingSpecRegister the closed qkernel surface of one compile-time object type.
Parameters:
| Name | Type | Description |
|---|---|---|
annotation | type[Any] | Public qkernel parameter annotation. |
type_key | str | Stable serialization key. |
fields | Mapping[str, StaticBindingFieldSpec] | Scalar projections available while tracing. |
members | Mapping[str, StaticBindingMemberSpec] | Deferred callable members available while tracing. |
Constructor¶
def __init__(
self,
annotation: type[Any],
type_key: str,
fields: Mapping[str, StaticBindingFieldSpec],
members: Mapping[str, StaticBindingMemberSpec],
) -> NoneAttributes¶
annotation: type[Any]fields: Mapping[str, StaticBindingFieldSpec]members: Mapping[str, StaticBindingMemberSpec]type_key: str
qamomile.circuit.stdlib.block_encoding.pauli¶
Build block encodings from complex Pauli linear combinations.
Overview¶
| Function | Description |
|---|---|
configure_composite | Configure a QKernel to remain visible as a named composite call. |
global_phase | Apply a qkernel call followed by exp(i * phase). |
pauli_lcu_block_encoding | Create a static exact block encoding of a complex Pauli LCU. |
qkernel | Decorator to define a Qamomile quantum kernel. |
x | Pauli-X gate (NOT gate). |
y | Pauli-Y gate. |
z | Pauli-Z gate. |
| Class | Description |
|---|---|
CallPolicy | Describe the default lowering policy for a callable call. |
LCUBlockEncoding | Describe one static exact LCU block encoding. |
PauliLCUBlockEncoding | Identify an LCU block encoding produced from a Pauli decomposition. |
QKernel | Decorator class for Qamomile quantum kernels. |
Functions¶
configure_composite [source]¶
def configure_composite(
kernel: QKernel[..., Any],
*,
name: str | None = None,
namespace: str | None = None,
gate_type: CompositeGateType = CompositeGateType.CUSTOM,
policy: CallPolicy = CallPolicy.PRESERVE_BOX,
implementations: Sequence[CallableImplementation] | None = None,
semantic_arguments: Mapping[str, Any] | None = None,
) -> QKernel[..., Any]Configure a QKernel to remain visible as a named composite call.
This mutates and returns the same QKernel object. No wrapper class or alternate call protocol is introduced.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernel[..., Any] | Kernel to configure. |
name | str | None | Public callable name. Defaults to the kernel name. |
namespace | str | None | Explicit stable callable namespace. None derives one from the decorated function’s module, qualified name, and source location. Defaults to None. |
gate_type | CompositeGateType | Internal stdlib classification. Defaults to CUSTOM. |
policy | CallPolicy | Lowering policy. Defaults to PRESERVE_BOX. |
implementations | Sequence[CallableImplementation] | None | Optional implementation candidates. |
semantic_arguments | Mapping[str, Any] | None | Serializer-friendly arguments that are part of the operation’s meaning rather than its decomposition. Defaults to no semantic arguments. |
Returns:
QKernel[..., Any] — QKernel[..., Any]: The same configured kernel instance.
global_phase [source]¶
def global_phase(target: QKernel | Callable[..., Any], phase: PhaseValue) -> GlobalPhaseGateApply a qkernel call followed by exp(i * phase).
The phase is represented as a zero-qubit operation and is retained even when it is not observable in the surrounding program. A reversible qkernel containing the operation acquires an observable relative phase when it is coherently controlled. Measurement, reset, allocation, classical outputs, and classical-only qkernels remain valid for ordinary standalone use.
Parameters:
| Name | Type | Description |
|---|---|---|
target | QKernel | Callable[..., Any] | QKernel or gate-like callable whose call is followed by the global phase. |
phase | float | int | Float | Phase angle in radians, supplied as a Qamomile Float handle or Python numeric literal. |
Returns:
GlobalPhaseGate — Callable wrapper with the target’s call interface.
Raises:
TypeError— Iftargetcannot be interpreted as a gate-like callable.
Example:
>>> import qamomile.circuit as qmc
>>> @qmc.qkernel
... def step(q: qmc.Qubit) -> qmc.Qubit:
... return qmc.x(q)
>>> @qmc.qkernel
... def phased_step(q: qmc.Qubit) -> qmc.Qubit:
... return qmc.global_phase(step, 0.7)(q)pauli_lcu_block_encoding [source]¶
def pauli_lcu_block_encoding(lcu: PauliLCU) -> PauliLCUBlockEncodingCreate a static exact block encoding of a complex Pauli LCU.
For a nonzero decomposition
the descriptor’s qkernel unitary implements U and satisfies
Multi-term encodings use real-amplitude PREPARE weights
sqrt(abs(c_j) / alpha) and SELECT cases
exp(1j * arg(c_j)) * P_j. The identity Pauli word is a normal case, so
its coefficient phase is retained. The zero operator uses one signal
qubit and an X gate, giving an exact zero all-zero block with
normalization 1.0; its PauliLCU.alpha remains 0.0.
The retained Pauli LCU is square, static, and encoded exactly. When
:meth:PauliLCU.from_matrix truncated coefficients, its source-to-retained
error remains available as lcu.truncation_error_bound and is not an
error in this unitary. The unitary accepts arbitrary signal states, returns
the same signal and system wires in the same order, supports
:func:~qamomile.circuit.inverse, and allocates no hidden source-level
logical workspace. Backend-only decomposition scratch is permitted only
when resource-accounted and exactly uncomputed for all inputs, including
under inverse and control.
Parameters:
| Name | Type | Description |
|---|---|---|
lcu | PauliLCU | Immutable retained Pauli decomposition. It must describe at least one system qubit. |
Returns:
PauliLCUBlockEncoding — Frozen non-callable descriptor. Allocate its
registers with num_signal_qubits and num_system_qubits,
then invoke unitary(signal, system).
Raises:
TypeError— Iflcuis not aPauliLCU.ValueError— Iflcurepresents a scalar zero-qubit system.
Example:
>>> import numpy as np
>>> import qamomile.circuit as qmc
>>> from qamomile.linalg import PauliLCU
>>> lcu = PauliLCU.from_matrix(np.array([[0, 1], [0, 0]], complex))
>>> encoding = qmc.pauli_lcu_block_encoding(lcu)
>>> @qmc.qkernel
... def circuit() -> tuple[qmc.Vector[qmc.Qubit], qmc.Vector[qmc.Qubit]]:
... signal = qmc.qubit_array(encoding.num_signal_qubits, "signal")
... system = qmc.qubit_array(encoding.num_system_qubits, "system")
... return encoding.unitary(signal, system)qkernel [source]¶
def qkernel(func: Callable[P, R]) -> QKernel[P, R]Decorator to define a Qamomile quantum kernel.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable[P, R] | Function to decorate. |
Returns:
QKernel[P, R] — QKernel[P, R]: QKernel wrapping the function.
x [source]¶
def x(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]Pauli-X gate (NOT gate).
Broadcasts over a Vector[Qubit] when applied to one.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Union[Qubit, Vector[Qubit]] | A single Qubit or a Vector[Qubit]. |
Returns:
Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.
Raises:
TypeError— Iftargetis neither aQubitnor aVector[Qubit].
y [source]¶
def y(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]Pauli-Y gate.
Broadcasts over a Vector[Qubit] when applied to one.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Union[Qubit, Vector[Qubit]] | A single Qubit or a Vector[Qubit]. |
Returns:
Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.
Raises:
TypeError— Iftargetis neither aQubitnor aVector[Qubit].
z [source]¶
def z(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]Pauli-Z gate.
Broadcasts over a Vector[Qubit] when applied to one.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Union[Qubit, Vector[Qubit]] | A single Qubit or a Vector[Qubit]. |
Returns:
Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.
Raises:
TypeError— Iftargetis neither aQubitnor aVector[Qubit].
Classes¶
CallPolicy [source]¶
class CallPolicy(enum.Enum)Describe the default lowering policy for a callable call.
Attributes¶
INLINENATIVE_FIRSTPRESERVE_BOX
LCUBlockEncoding [source]¶
class LCUBlockEncodingDescribe one static exact LCU block encoding.
unitary is the qkernel implementing the larger unitary U; it is
neither the encoded matrix A nor a dense matrix value. It has no
classical arguments and its quantum ABI is
unitary(signal, system) -> (signal, system). system is the ordered
logical data register on which A acts. signal is the complete
source-level ancilla bundle whose all-zero state selects the encoded block.
The unitary returns the same logical wires in the same order and acts
unitarily for arbitrary signal inputs; after one application, the signal
may have non-zero components rather than returning entirely to zero.
For the all-zero signal isometry V0, the producer must guarantee
including coefficient phase. normalization is finite and positive;
an encoding of the zero operator uses 1.0. Implementations allocate no
hidden source-level logical qubits. A backend may still use temporary
decomposition scratch that is resource-accounted, exactly uncomputed for
every public input, and preserved under inverse and control. Descriptor
comparison and hashing use object identity rather than field values.
This common descriptor deliberately excludes decomposition-specific metadata. Reusable qkernels should annotate an encoding argument with this class so descriptors produced by Pauli and future LCU factories can occupy the same compile-time binding slot.
Parameters:
| Name | Type | Description |
|---|---|---|
unitary | QKernel | QKernel implementing the block-encoding unitary U with the static (signal, system) ABI. |
normalization | float | Finite positive block normalization. |
num_signal_qubits | int | Concrete positive width of the complete signal register, including selectors, logical workspace, and padding required by the producer. |
num_system_qubits | int | Concrete positive width of the ordered system register. |
Raises:
TypeError— Ifunitaryis not aQKernelwith the exact static positional ABI above, normalization is not a real scalar, or either width is not an integer.ValueError— If normalization is non-finite or non-positive, or either width is non-positive.
Constructor¶
def __init__(
self,
unitary: _BlockEncodingUnitary,
normalization: float,
num_signal_qubits: int,
num_system_qubits: int,
) -> NoneAttributes¶
normalization: floatnum_signal_qubits: intnum_system_qubits: intunitary: _BlockEncodingUnitary
PauliLCUBlockEncoding [source]¶
class PauliLCUBlockEncoding(LCUBlockEncoding)Identify an LCU block encoding produced from a Pauli decomposition.
The subtype adds no qkernel-visible fields. Reusable qkernels should
annotate encoding arguments with :class:LCUBlockEncoding; the Pauli
subtype remains available for producer-specific host-side code and
backward-compatible serialized templates.
Parameters:
| Name | Type | Description |
|---|---|---|
unitary | QKernel | QKernel implementing the exact block-encoding unitary with the static (signal, system) ABI. |
normalization | float | Finite positive block normalization. |
num_signal_qubits | int | Concrete positive width of the complete signal register. |
num_system_qubits | int | Concrete positive width of the ordered system register. |
Raises:
TypeError— If an inherited descriptor field has an invalid type or the unitary ABI is invalid.ValueError— If normalization or a register width is non-positive or non-finite.
Constructor¶
def __init__(
self,
unitary: _BlockEncodingUnitary,
normalization: float,
num_signal_qubits: int,
num_system_qubits: int,
) -> NoneQKernel [source]¶
class QKernel(QKernelBuildMixin, QKernelVisualizationMixin, Generic[P, R])Decorator class for Qamomile quantum kernels.
Constructor¶
def __init__(self, func: Callable[P, R]) -> NoneAttributes¶
block: Block Compile the function to a hierarchical Block if not already compiled.effects: KernelEffect Return cached semantic effects of this qkernel.funcinput_types: dict[str, Any] Return resolved and frozen frontend input annotations.nameoutput_types: list[Any] Return the resolved frontend annotation for every output slot.raw_funcreturn_type: Any Return the resolved and frozen complete return annotation.signature
qamomile.circuit.stdlib.block_encoding.periodic_shift¶
Build LCU block encodings from constant-coefficient periodic shifts.
For axis registers with widths register_sizes, this module represents
where T_k adds the integer offset tuple k modulo the corresponding
power-of-two axis sizes. The construction prepares real amplitudes
sqrt(abs(c_k) / lambda), applies
exp(1j * arg(c_k)) * T_k through qmc.select, and unprepares the signal
register. Consequently the all-zero signal block is A / lambda for
lambda = sum(abs(c_k)).
Only periodic boundaries, constant coefficients, and power-of-two axis sizes are in scope. Non-periodic boundary corrections and position-dependent coefficients require different block-encoding constructions. Each constant shift is decomposed into ancilla-free increment or decrement ladders for the set bits of its displacement. A dense circulant kernel may still require exponentially many LCU terms, so this factory is intended for shift-sparse decompositions.
Overview¶
| Function | Description |
|---|---|
periodic_shift_lcu_block_encoding | Build an LCU block encoding from a periodic-shift decomposition. |
| Class | Description |
|---|---|
LCUBlockEncoding | Describe one static exact LCU block encoding. |
PeriodicShiftLCUBlockEncoding | Describe one static exact periodic-shift LCU block encoding. |
Functions¶
periodic_shift_lcu_block_encoding [source]¶
def periodic_shift_lcu_block_encoding(lcu: PeriodicShiftLCU) -> PeriodicShiftLCUBlockEncodingBuild an LCU block encoding from a periodic-shift decomposition.
lcu defines A = sum_k c_k T_k, where T_k is the modular
translation for one canonical offset tuple. The system is the flattened
concatenation of the decomposition’s LSB-first axis registers. A shift
uses the shorter signed displacement, then emits one ancilla-free
increment or decrement ladder for each set bit of its magnitude. This
bounds the number of Qamomile-level X and multi-controlled-X operations by
a quadratic function of an axis register’s width; backend elementary-gate
cost depends on how that backend decomposes multi-controlled X operations.
The returned descriptor’s unitary acts on arbitrary signal states.
Projecting its signal register onto all zero before and after the unitary
yields A / lambda, where lambda is available as
result.normalization.
The zero operator uses one signal qubit and an X gate, giving an exact
zero all-zero block with normalization 1.0 while lcu.alpha remains
0.0.
A single term retains one pass-through signal qubit for composition but
omits PREPARE and SELECT entirely.
When :meth:PeriodicShiftLCU.from_matrix or
:meth:PeriodicShiftLCU.from_coefficients pruned coefficients, the source
error remains available as lcu.truncation_error_bound and is not an
error in the retained unitary.
Parameters:
| Name | Type | Description |
|---|---|---|
lcu | PeriodicShiftLCU | Immutable retained periodic-shift decomposition. It must describe at least one system qubit. |
Returns:
PeriodicShiftLCUBlockEncoding — Frozen non-callable descriptor containing
the generated shift-LCU unitary and method-specific canonical
metadata.
Raises:
TypeError— Iflcuis not a :class:PeriodicShiftLCU.ValueError— Iflcurepresents a scalar zero-qubit system.
Example:
>>> import qamomile.circuit as qmc
>>> from qamomile.circuit.serialization import deserialize, serialize
>>> from qamomile.linalg import PeriodicShiftLCU
>>> from qamomile.qiskit import QiskitTranspiler
>>> @qmc.qkernel
... def apply_encoding(
... encoding: qmc.LCUBlockEncoding,
... ) -> tuple[qmc.Vector[qmc.Qubit], qmc.Vector[qmc.Qubit]]:
... signal = qmc.qubit_array(encoding.num_signal_qubits, "signal")
... system = qmc.qubit_array(encoding.num_system_qubits, "system")
... return encoding.unitary(signal, system)
>>> payload = serialize(apply_encoding)
>>> received = deserialize(payload)
>>> lcu = PeriodicShiftLCU.from_coefficients(
... {-1: 1.0, 0: -2.0, 1: 1.0},
... register_sizes=(3,),
... )
>>> neighbor_difference = qmc.periodic_shift_lcu_block_encoding(lcu)
>>> isinstance(neighbor_difference, qmc.LCUBlockEncoding)
True
>>> neighbor_difference.normalization
4.0
>>> executable = QiskitTranspiler().transpile(
... received,
... bindings={"encoding": neighbor_difference},
... )Classes¶
LCUBlockEncoding [source]¶
class LCUBlockEncodingDescribe one static exact LCU block encoding.
unitary is the qkernel implementing the larger unitary U; it is
neither the encoded matrix A nor a dense matrix value. It has no
classical arguments and its quantum ABI is
unitary(signal, system) -> (signal, system). system is the ordered
logical data register on which A acts. signal is the complete
source-level ancilla bundle whose all-zero state selects the encoded block.
The unitary returns the same logical wires in the same order and acts
unitarily for arbitrary signal inputs; after one application, the signal
may have non-zero components rather than returning entirely to zero.
For the all-zero signal isometry V0, the producer must guarantee
including coefficient phase. normalization is finite and positive;
an encoding of the zero operator uses 1.0. Implementations allocate no
hidden source-level logical qubits. A backend may still use temporary
decomposition scratch that is resource-accounted, exactly uncomputed for
every public input, and preserved under inverse and control. Descriptor
comparison and hashing use object identity rather than field values.
This common descriptor deliberately excludes decomposition-specific metadata. Reusable qkernels should annotate an encoding argument with this class so descriptors produced by Pauli and future LCU factories can occupy the same compile-time binding slot.
Parameters:
| Name | Type | Description |
|---|---|---|
unitary | QKernel | QKernel implementing the block-encoding unitary U with the static (signal, system) ABI. |
normalization | float | Finite positive block normalization. |
num_signal_qubits | int | Concrete positive width of the complete signal register, including selectors, logical workspace, and padding required by the producer. |
num_system_qubits | int | Concrete positive width of the ordered system register. |
Raises:
TypeError— Ifunitaryis not aQKernelwith the exact static positional ABI above, normalization is not a real scalar, or either width is not an integer.ValueError— If normalization is non-finite or non-positive, or either width is non-positive.
Constructor¶
def __init__(
self,
unitary: _BlockEncodingUnitary,
normalization: float,
num_signal_qubits: int,
num_system_qubits: int,
) -> NoneAttributes¶
normalization: floatnum_signal_qubits: intnum_system_qubits: intunitary: _BlockEncodingUnitary
PeriodicShiftLCUBlockEncoding [source]¶
class PeriodicShiftLCUBlockEncoding(LCUBlockEncoding)Describe one static exact periodic-shift LCU block encoding.
unitary is the qkernel implementing the larger unitary U; it is
neither the encoded periodic-shift matrix A nor a dense matrix value. It has
no classical arguments and its quantum ABI is
unitary(signal, system) -> (signal, system). system is the ordered
flattened data register on which A acts. signal is the complete
source-level ancilla bundle whose all-zero state selects the encoded
block. The unitary returns the same logical wires in the same order and
acts unitarily for arbitrary signal inputs; signal need not return to zero
after one application.
For the all-zero signal isometry V0, the encoded periodic-shift matrix
satisfies
including coefficient phase. The construction is exact in ideal logical arithmetic; host floating-point roundoff in state-preparation angles and backend gate synthesis are outside this semantic equality. This producer allocates no hidden source-level logical qubits. Backend decomposition scratch is permitted only when resource-accounted and exactly uncomputed for every input, including under inverse and control. Descriptor comparison and hashing use object identity rather than field values.
The inherited fields form the qkernel-visible static LCU contract.
register_sizes, offsets, and coefficients are deeply immutable
producer metadata for host-side inspection only. A producer-specific
qkernel may annotate an argument with this class. Reusable qkernels should
instead annotate descriptor arguments with :class:LCUBlockEncoding,
allowing the same serialized template to accept this and other exact LCU
producers.
Parameters:
| Name | Type | Description |
|---|---|---|
unitary | qmc.QKernel | QKernel implementing the block-encoding unitary U with the static (signal, system) ABI. |
normalization | float | Finite positive LCU normalization sum(abs(coefficients)) after equivalent periodic offsets are combined. Direct construction accepts relative disagreement up to 1e-12 for host rounding and stores the canonical coefficient-derived sum. The empty zero-operator representation instead uses 1.0. |
num_signal_qubits | int | Concrete positive width of the complete signal register, including selector padding. |
num_system_qubits | int | Concrete positive width of the ordered flat system register. |
register_sizes | tuple[int, ...] | Qubit widths of the flattened system register’s axes. |
offsets | tuple[tuple[int, ...], ...] | Canonical modular offsets, in SELECT case order. The empty tuple represents the zero operator. |
coefficients | tuple[complex, ...] | Nonzero combined coefficients, in SELECT case order. The empty tuple represents the zero operator. |
Raises:
TypeError— If the common block-encoding fields or method-specific metadata have invalid runtime types.ValueError— If normalization or a width is invalid, method-specific metadata is inconsistent, or offsets are not canonical.
Constructor¶
def __init__(
self,
unitary: _BlockEncodingUnitary,
normalization: float,
num_signal_qubits: int,
num_system_qubits: int,
register_sizes: tuple[int, ...],
offsets: tuple[tuple[int, ...], ...],
coefficients: tuple[complex, ...],
) -> NoneAttributes¶
coefficients: tuple[complex, ...]offsets: tuple[tuple[int, ...], ...]register_sizes: tuple[int, ...]
qamomile.circuit.stdlib.computational_basis_state¶
Overview¶
| Function | Description |
|---|---|
computational_basis_state | Prepare the computational basis state labeled by bits. |
Functions¶
computational_basis_state [source]¶
def computational_basis_state(q: qmc.Vector[qmc.Qubit], bits: qmc.Vector[qmc.UInt]) -> qmc.Vector[qmc.Qubit]Prepare the computational basis state labeled by bits.
Applies an exact X ** bits[i] to each qubit. The implementation uses
Rx(pi * bits[i]) plus its compensating exp(+i*pi*bits[i]/2)
global phase, so controlling this kernel preserves the intended unitary
rather than turning the RX phase into an observable relative phase.
Assumes q starts in and
q.shape[0] == bits.shape[0].
Parameters:
| Name | Type | Description |
|---|---|---|
q | qmc.Vector[qmc.Qubit] | Qubit register, expected to start in |0>^n. |
bits | qmc.Vector[qmc.UInt] | Classical bit register specifying the target state. |
Returns:
qmc.Vector[qmc.Qubit] — qmc.Vector[qmc.Qubit]: Qubit register prepared in the exact |bits>
qmc.Vector[qmc.Qubit] — state convention.
qamomile.circuit.stdlib.grover¶
Grover search building blocks with query-complexity resource estimation.
This module provides :func:grover_search, the amplitude-amplification loop
from the book’s Section 4.1 (“Search algorithms a la Grover”), and helpers to
compute the optimal iteration count. Grover search over N = 2**n items with
m marked solutions needs O(sqrt(N/m)) iterations, each applying one
oracle query and one diffusion (reflection about the uniform superposition).
The oracle is supplied by the caller as a costed opaque box (e.g.
qmc.opaque(..., cost=...)), so the total gate cost is
iterations x (oracle_cost + diffusion_cost) while the query complexity is
the universal O(sqrt(N/m)). Leaving the iteration count symbolic makes
estimate_resources report that scaling directly; :func:grover_iteration_count
returns the concrete or symbolic floor((pi/4) sqrt(N/m)). Plug it in with the
inputs argument to get the optimal query complexity
straight from one estimate call::
est = kernel.estimate_resources(
inputs={"iterations": grover_iteration_count(n, m)}
)
est.calls.queries_by_name[oracle_name] # floor((pi/4) sqrt(2^n / m))Overview¶
| Function | Description |
|---|---|
for_loop | Create a traced for loop in the Qamomile frontend. |
grover_iteration_count | Return the optimal Grover iteration count floor((pi/4) sqrt(N/m)). |
grover_search | Run the Grover amplitude-amplification loop on reg. |
| Class | Description |
|---|---|
Oracle | Represent an opaque oracle callable. |
QKernelLike | Describe the frontend surface required by compiler entrypoints. |
Functions¶
for_loop [source]¶
def for_loop(
start,
stop,
step = 1,
var_name: str = '_loop_idx',
*,
captures: tuple[tuple[str, Any], ...] = (),
) -> Generator[UInt, None, None]Create a traced for loop in the Qamomile frontend.
Parameters:
| Name | Type | Description |
|---|---|---|
start | typing.Any | Inclusive loop start as an integer or UInt. |
stop | typing.Any | Exclusive loop stop as an integer or UInt. |
step | typing.Any | Nonzero loop step as an integer or UInt. Defaults to 1. |
var_name | str | Display name of the loop variable. Defaults to "_loop_idx". |
captures | tuple[tuple[str, typing.Any], ...] | Statically analyzed read-only body inputs. Defaults to an empty tuple. |
Yields:
UInt — The loop iteration variable (can be used as array index)
Raises:
TypeError— If a bound cannot be represented as a scalar IR value.ValueError— If the constructed loop has inconsistent region-result metadata.
Example:
@QKernel
def my_kernel(qubits: Array[Qubit, Literal[3]]) -> Array[Qubit, Literal[3]]:
for i in qm.range(3):
qubits[i] = h(qubits[i])
return qubits
@QKernel
def my_kernel2(qubits: Array[Qubit, Literal[5]]) -> Array[Qubit, Literal[5]]:
for i in qm.range(1, 4): # i = 1, 2, 3
qubits[i] = h(qubits[i])
return qubitsClassical scalar updates (total = total + i) become explicit
RegionArg records on the ForOperation: the loop enters with
the initializer, each iteration reads the previous iteration’s
value, and post-loop code reads the loop result.
grover_iteration_count [source]¶
def grover_iteration_count(
num_qubits: int | np.integer[Any] | sp.Expr,
num_marked: int | np.integer[Any] | sp.Expr = 1,
) -> int | sp.ExprReturn the optimal Grover iteration count floor((pi/4) sqrt(N/m)).
Parameters:
| Name | Type | Description |
|---|---|---|
num_qubits | int | np.integer[Any] | sp.Expr | Number of search qubits n (search space N = 2**n). May be a Python or NumPy integer, or a symbolic expression. |
num_marked | int | np.integer[Any] | sp.Expr | Number of marked solutions m. Defaults to 1. |
Returns:
int | sp.Expr — int | sp.Expr: Concrete iteration count when both arguments are concrete
Python or NumPy integers, otherwise the symbolic expression
floor((pi/4) sqrt(2**n / m)). SymPy integers remain SymPy
expressions.
Raises:
TypeError— Ifnum_qubitsornum_markedis a boolean.ValueError— If concretenum_qubitsornum_markedis not positive.
Example:
>>> grover_iteration_count(4, 1)
3grover_search [source]¶
def grover_search(
reg: Vector[Qubit],
oracle: Oracle | QKernelLike,
iterations: int | qmc.UInt,
) -> Vector[Qubit]Run the Grover amplitude-amplification loop on reg.
Prepares the uniform superposition, then applies iterations rounds of
oracle followed by the diffusion operator. Leaving iterations
symbolic makes resource estimation report the universal O(sqrt(N/m))
query complexity: the oracle’s opaque cost contributes the per-query gate
cost and the diffusion contributes O(n) gates, both summed over the
symbolic iteration count.
Parameters:
| Name | Type | Description |
|---|---|---|
reg | Vector[Qubit] | Search register in the all-zero state on entry. |
oracle | Oracle | QKernelLike | Phase oracle marking the solution(s). Supply a costed opaque box (e.g. qmc.opaque(..., cost=...)) so the estimator can cost each query. |
iterations | int | qmc.UInt | Number of Grover iterations. Use :func:grover_iteration_count to obtain the optimal value; leave it as an unbound UInt parameter for symbolic estimation. |
Returns:
Vector[Qubit] — Vector[Qubit]: Register after amplitude amplification.
Example:
>>> import qamomile.circuit as qmc
>>> from qamomile.circuit.stdlib import grover_search, grover_iteration_count
>>> mark = qmc.opaque("mark", num_qubits=3)
>>> @qmc.qkernel
... def search(reg: qmc.Vector[qmc.Qubit]) -> qmc.Vector[qmc.Qubit]:
... return grover_search(reg, mark, grover_iteration_count(3))Classes¶
Oracle [source]¶
class OracleRepresent an opaque oracle callable.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | Human-readable oracle name. |
num_qubits | int | None | Number of target qubits consumed and returned by the oracle. None means the arity is provided by signature and may be vector-shaped. Python and NumPy integer scalars are accepted; booleans and negative values are rejected. |
num_control_qubits | int | Number of explicit control qubits required by scalar calls. Defaults to 0. |
signature | CallableSignature | None | Optional frontend signature for target operands only. It must not repeat the leading controls declared by num_control_qubits; those controls are prefixed by the Oracle automatically. When omitted, a fixed-width scalar/vector-compatible oracle is created from num_qubits. |
cost | ResourceEstimate | Callable[[OpaqueCostContext], ResourceEstimate] | None | Optional explicit cost for this bodyless callable. Both forms describe one ordinary application of the Oracle as declared, including num_control_qubits. Controls added later with qmc.control are projected by resource estimation. This is a complete definition-level contract: the author must include any phase-relevant work that later coherent controls need. The estimator does not infer omitted global-phase overhead. An intrinsic nonidentity phase is represented as a logical primitive in the aggregate gate and arity counts. A one-qubit phase entry is an upper-bound representative for the target-free phase, not an angle-aware reconstruction; use a body-backed global phase when angle-specific classification is required. Defaults to None. |
Raises:
TypeError— If a suppliednum_qubitsornum_control_qubitsis boolean or not an integral scalar.ValueError— If either width is negative, or neithernum_qubitsnorsignaturesupplies enough target-arity information.
Constructor¶
def __init__(
self,
name: str,
num_qubits: int | None = None,
*,
num_control_qubits: int = 0,
signature: CallableSignature | None = None,
cost: ResourceEstimate | Callable[[OpaqueCostContext], ResourceEstimate] | None = None,
) -> NoneInitialize an opaque oracle callable.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | Human-readable oracle name. |
num_qubits | int | None | Fixed scalar/vector width. Defaults to None when signature describes the callable. Python and NumPy integer scalars are accepted; booleans and negative values are rejected. |
num_control_qubits | int | Number of explicit scalar controls. Defaults to 0. |
signature | CallableSignature | None | Optional frontend signature for target operands only. Do not include controls declared by num_control_qubits; the Oracle prefixes those controls to its internal callable signature. Defaults to None. |
cost | ResourceEstimate | Callable[[OpaqueCostContext], ResourceEstimate] | None | Optional fixed or context-dependent opaque cost. The returned estimate describes one ordinary application of this Oracle definition, including its declared controls but excluding controls added by an outer transform. The result must be a complete definition-level contract, including phase-relevant work that an outer coherent control must transform. Represent an intrinsic nonidentity phase as a logical primitive in the aggregate gate and arity counts. A one-qubit phase entry is an upper-bound representative; use a body-backed global phase for angle-specific classification. Defaults to None. |
Raises:
TypeError— If a suppliednum_qubitsornum_control_qubitsis not a non-boolean integral scalar.ValueError— If neithernum_qubitsnorsignaturesupplies enough target-arity information, or if either width is negative.
Attributes¶
cost: ResourceEstimate | Callable[[OpaqueCostContext], ResourceEstimate] | Nonename: strnum_control_qubits: intnum_qubits: int | Nonesignature: CallableSignature | None
QKernelLike [source]¶
class QKernelLike(Protocol)Describe the frontend surface required by compiler entrypoints.
This protocol is intentionally structural. It lets decorator-created
composites reuse the qkernel inspection and build interface without making
them inherit from QKernel or exposing the compiler-facing callable
descriptor model as a frontend concept.
Attributes¶
block: Block Return the cached hierarchical body block.effects: KernelEffect Return cached semantic effects of the qkernel body.input_types: dict[str, Any] Return frontend input annotations by parameter name.name: str Return the user-facing callable name.output_types: list[Any] Return frontend output annotations.signature: inspect.Signature Return the Python call signature.
Methods¶
build¶
def build(self, parameters: list[str] | None = None, **kwargs: Any = {}) -> BlockBuild a traced body block.
Parameters:
| Name | Type | Description |
|---|---|---|
parameters | list[str] | None | Runtime parameter names to preserve. Defaults to None. |
**kwargs | Any | Compile-time bindings for non-parameter arguments. |
Returns:
Block — Traced hierarchical body block.
qamomile.circuit.stdlib.mottonen_amplitude_encoding¶
Amplitude encoding with generic and Möttönen-specific APIs.
Prepares the n-qubit state
from for a normalised amplitude vector
a. The construction follows Möttönen et al., “Transformation of
quantum states using uniformly controlled rotations”
(arXiv:quant-ph/0407010). Both the RY-only “amplitude distribution”
stage and the RZ “phase restoration” stage are supported, so general
complex amplitudes work end-to-end.
.. important::
**Pre-condition: the input register must be in the all-zero state**
$|0\rangle^{\otimes n}$. The Möttönen construction
decomposes the unitary that takes $|0\rangle^{\otimes n}$
to the target $|\psi\rangle$; applying it to any other
initial state yields a *different* output (the same unitary
applied to a different input), not the target amplitude vector.
There is no runtime guard for this — Qamomile does not track
qubit states — so it is the caller's responsibility to ensure the
register has not yet been mutated when an amplitude-encoding helper is
invoked. In practice, call these helpers immediately after
``qmc.qubit_array(n, ...)`` inside a kernel.The generic :func:amplitude_encoding API specifies the prepared state but not
the synthesis algorithm. Backends may therefore replace it with a native state
preparation implementation. Its portable Qamomile body currently uses the
Möttönen construction described below.
The :func:mottonen_amplitude_encoding API makes that construction part of the
callable identity, so a backend cannot replace it with a generic state
preparation implementation. The parametric companion
:func:mottonen_amplitude_encoding_from_angles emits the Möttönen Gray walk
directly. :func:amplitude_encoding_from_angles remains as a compatibility
wrapper for the parametric companion. Classical angle precomputation lives in
:mod:qamomile.linalg.mottonen so hybrid loops can compute angles outside a
kernel and bind them as runtime parameters.
Pipeline¶
Validate and normalise the input — see :func:
qamomile.linalg.mottonen.validate_and_normalize_amplitudes(length must be a power of two, all-zero rejected).Determine whether the input is genuinely complex (has a non-zero imaginary part). Real inputs (including complex with zero imag) keep the original signed-RY path — negative real amplitudes flow through the sign of
arctan2(a_1, a_0)naturally, with no RZ overhead. Complex inputs use the iterative disentangling construction.For real inputs, compute the per-level RY rotation angles by splitting each chunk into upper / lower halves and using
arctan2of the two sub-block norms (or signedarctan2at the leaf). See :func:qamomile.linalg.mottonen.compute_all_ry_angles_per_level.For complex inputs, iteratively disentangle the target amplitude vector qubit-by-qubit from LSB to MSB. See :func:
qamomile.linalg.mottonen.compute_disentangling_angles_per_level.At each level
k >= 1apply a uniformly controlled rotation over the previously preparedkqubits. We use the standard Gray-code RY / CNOT decomposition for the magnitude stage and the same structure with RZ for the phase stage. The emitted gate order is “all RY layers, then all RZ layers”. Pairwise[U_y^(k), U_z^(k')]does NOT commute in general (includingk != k'cases, because earlier RY targets can be controls of later RZ multiplexers), but the FULL sweep product equals the per-level interleaved product(U_z^(0) U_y^(0)) ... (U_z^(n-1) U_y^(n-1))as unitaries — this is a structural identity verified by :class:tests.circuit.stdlib.state_preparation.test_mottonen_amplitude_encoding.TestRyRzOrderingwith arbitrary (non-disentangling) per-level angles. Within each level the order RY-before-RZ is preserved in both schemes.
_MottonenAngles validates and normalizes eagerly, then caches the more
expensive angle precomputation. It is an internal classical helper rather than a
second frontend gate type; the frontend objects produced here are normal
QKernel instances decorated with @composite_gate.
Overview¶
| Function | Description |
|---|---|
amplitude_encoding | Prepare an amplitude-encoded state with a backend-selected synthesis. |
amplitude_encoding_from_angles | Apply Möttönen encoding from angles through the compatibility API. |
composite_gate | Define a named composite using the normal qkernel programming model. |
compute_all_ry_angles_per_level | Pre-compute every level’s Ry rotation angle vector (magnitude stage). |
compute_disentangling_angles_per_level | Iteratively disentangle to obtain both Ry and Rz angles per level. |
configure_composite | Configure a QKernel to remain visible as a named composite call. |
cx | CNOT (Controlled-X) gate. |
get_size | Return the size of a Vector handle as a Python integer. |
mottonen_amplitude_encoding | Prepare an amplitude-encoded state with the Möttönen construction. |
mottonen_amplitude_encoding_from_angles | Apply Möttönen amplitude encoding from pre-computed Ry / Rz angles. |
ry | Rotation around Y-axis: RY(angle) = exp(-i * angle/2 * Y). |
rz | Rotation around Z-axis: RZ(angle) = exp(-i * angle/2 * Z). |
validate_and_normalize_amplitudes | Validate an amplitude vector and return its normalised form. |
| Class | Description |
|---|---|
CallPolicy | Describe the default lowering policy for a callable call. |
QKernel | Decorator class for Qamomile quantum kernels. |
Functions¶
amplitude_encoding [source]¶
def amplitude_encoding(
qubits: Vector[Qubit],
amplitudes: Sequence[float] | Sequence[complex] | np.ndarray | Vector[Float],
) -> Vector[Qubit]Prepare an amplitude-encoded state with a backend-selected synthesis.
The semantic contract is that an all-zero n-qubit register becomes the
normalized state . The synthesis algorithm is
intentionally unspecified: a backend may use its native state-preparation
implementation. Qamomile’s portable fallback currently uses the Möttönen
construction.
State-preparation algorithms can implement different unitaries away from
the all-zero input even when they prepare the same target state. Use
:func:mottonen_amplitude_encoding when the exact construction, its
resource profile, or transformed uses such as inverse and control matter.
A concrete sequence or NumPy array may contain real or complex amplitudes.
A Vector[Float] parameter must be resolved through bindings at
compile time. For runtime-parametric Möttönen angles, use
:func:mottonen_amplitude_encoding_from_angles.
Parameters:
| Name | Type | Description |
|---|---|---|
qubits | Vector[Qubit] | Vector of n qubit handles in . |
amplitudes | Sequence[float] | Sequence[complex] | np.ndarray | Vector[Float] | Amplitude vector of length 2**n. Values are normalized automatically. Vector[Float] values must be concrete at trace time. |
Returns:
Vector[Qubit] — Vector[Qubit]: The input vector updated to the prepared-state handles.
Raises:
ValueError— If a vector shape is unresolved, the amplitudes are invalid or unavailable at trace time, or the register width does not match the amplitude-vector length.
Example::
@qmc.qkernel
def prepare() -> qmc.Vector[qmc.Bit]:
q = qmc.qubit_array(2, name="q")
q = amplitude_encoding(q, [1.0, 0.0, 0.0, 1.0])
return qmc.measure(q)amplitude_encoding_from_angles [source]¶
def amplitude_encoding_from_angles(
qubits: Vector[Qubit],
ry_angles: Sequence[float] | np.ndarray | Vector[Float],
rz_angles: Sequence[float] | np.ndarray | Vector[Float] | None = None,
) -> Vector[Qubit]Apply Möttönen encoding from angles through the compatibility API.
This function preserves the original public name and delegates directly to
:func:mottonen_amplitude_encoding_from_angles. New code should prefer the
algorithm-specific name because angle vectors define the Möttönen Gray-walk
decomposition rather than generic amplitude encoding.
Parameters:
| Name | Type | Description |
|---|---|---|
qubits | Vector[Qubit] | Vector of n qubit handles in . |
ry_angles | Sequence[float] | np.ndarray | Vector[Float] | Gray-walk Ry angles of length 2**n - 1. |
rz_angles | Sequence[float] | np.ndarray | Vector[Float] | None | Optional Gray-walk Rz angles of length 2**n - 1. |
Returns:
Vector[Qubit] — Vector[Qubit]: The input vector updated to the prepared-state handles.
Raises:
ValueError— If a concrete angle vector has the wrong length or the qubit-vector shape cannot be resolved.
composite_gate [source]¶
def composite_gate(
func: Callable[..., Any] | None = None,
*,
name: str = '',
implementations: Sequence[CallableImplementation] | None = None,
) -> QKernel[..., Any] | Callable[[Callable[..., Any]], QKernel[..., Any]]Define a named composite using the normal qkernel programming model.
The decorated object is a QKernel. Calls keep their named box in the IR,
while build(), draw(), estimate_resources(), control(), and
inverse() use the same interface as every other qkernel.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable[..., Any] | None | Function or qkernel to decorate. Defaults to None for decorator-with-arguments use. |
name | str | Public callable name. Defaults to the function name. |
implementations | Sequence[CallableImplementation] | None | Optional compiler implementation candidates. |
Returns:
QKernel[..., Any] | Callable[[Callable[..., Any]], QKernel[..., Any]] — QKernel[..., Any] | Callable[[Callable[..., Any]], QKernel[..., Any]]:
Configured qkernel or decorator.
Raises:
TypeError— If the decorator target is not callable.
Example:
>>> import qamomile.circuit as qmc
>>> @qmc.composite_gate(name="bell_pair")
... def bell_pair(
... a: qmc.Qubit, b: qmc.Qubit
... ) -> tuple[qmc.Qubit, qmc.Qubit]:
... a = qmc.h(a)
... return qmc.cx(a, b)compute_all_ry_angles_per_level [source]¶
def compute_all_ry_angles_per_level(amplitudes: np.ndarray, num_qubits: int) -> list[np.ndarray]Pre-compute every level’s Ry rotation angle vector (magnitude stage).
Implements the recursive magnitude-stage angle formula given in
Möttönen et al., arXiv:quant-ph/0407010, Section III, Eq. (8)
(with the leaf case matching the unnumbered angle
2 \arcsin(|a_{2j}| / \sqrt{|a_{2j-1}|^2 + |a_{2j}|^2})
just before Eq. (6), equivalent to 2 atan2(|a_1|, |a_0|)
on the leaf pair). The pre-condition is the all-zero state
; the formulas below describe the
angles needed to reach a real amplitudes from there.
For each level k (0 <= k < num_qubits) the amplitude
vector is split into 2**k equal chunks. Each chunk yields one
per-control-state angle α (Eq. (8)):
Intermediate levels (
chunk_size > 2): the angle rotates the target qubit so its|1>weight matches the lower-half block norm. Usingarctan2(norm_lower, norm_upper)keeps the formula well defined when the upper half has zero norm.Leaf level (
chunk_size == 2):α = 2 * arctan2(a_1, a_0)directly (signed, so negative amplitudes are preserved without a phase stage).
For k >= 1 the per-control-state angles are then transformed
to the Gray-walk basis via :func:_to_gray_walk_basis (paper
Eq. (3)).
Parameters:
| Name | Type | Description |
|---|---|---|
amplitudes | np.ndarray | Unit-norm real amplitude vector of length 2**num_qubits. |
num_qubits | int | Number of qubits in the target register. |
Returns:
list[np.ndarray] — list[np.ndarray]: A list of num_qubits arrays; the k-th
entry has length 2**k and holds the Gray-walk Ry
angles for that level.
compute_disentangling_angles_per_level [source]¶
def compute_disentangling_angles_per_level(
amplitudes: np.ndarray,
num_qubits: int,
) -> tuple[list[np.ndarray], list[np.ndarray]]Iteratively disentangle to obtain both Ry and Rz angles per level.
Implements the Möttönen disentangling sweep for general (complex)
amplitudes from Möttönen et al., arXiv:quant-ph/0407010,
Section III, Eqs. (4)-(8): the phase-equalisation rotation
Ξ_z (Eq. (4)) followed by the magnitude rotation, applied
pair-by-pair from LSB to MSB. Pre-condition is the all-zero
state ; the angles below are
those needed to reach the input amplitudes from there
(computed via the inverse sweep that disentangles the input).
At each step the amplitude vector is halved by pairing adjacent
entries; for the pair (a_0, a_1) we read off
Ry angle = 2 * arctan2(|a_1|, |a_0|)(magnitude split, paper Eq. (8) restricted to the leaf level — equivalently the unnumbered2 arcsin(...)form just before Eq. (6)),Rz angle = arg(a_1 / a_0)(phase difference, paper Eq. (5)),
and replace the pair with the single complex amplitude that
survives the implicit Rz^{-1} Ry^{-1} disentangling step
(paper Eq. (6) zeros out one of the pair entries; the
surviving amplitude is
which carries the averaged phase needed by the next outer step
of the sweep — the paper does not write β in this exact
closed form but the relation falls out of combining
Eqs. (5)-(7)). The full sweep is paper Eq. (7).
Zero-magnitude halves are handled gracefully by leaving the
corresponding angle at 0 (the underlying state has no support
there so the angle is immaterial). The returned per-level arrays
are already bit-reversed and gray-walk-transformed (paper
Eq. (3) applied per level via :func:_to_gray_walk_basis),
ready for the Möttönen Gray-walk emission.
Parameters:
| Name | Type | Description |
|---|---|---|
amplitudes | np.ndarray | Unit-norm complex amplitude vector of length 2**num_qubits. |
num_qubits | int | Number of qubits in the target register. |
Returns:
tuple[list[np.ndarray], list[np.ndarray]] — tuple[list[np.ndarray], list[np.ndarray]]:
(ry_angles_per_level, rz_angles_per_level) in
Gray-walk ordering. Each list has num_qubits entries;
the k-th entry holds 2**k angles for level k of
the forward emission.
configure_composite [source]¶
def configure_composite(
kernel: QKernel[..., Any],
*,
name: str | None = None,
namespace: str | None = None,
gate_type: CompositeGateType = CompositeGateType.CUSTOM,
policy: CallPolicy = CallPolicy.PRESERVE_BOX,
implementations: Sequence[CallableImplementation] | None = None,
semantic_arguments: Mapping[str, Any] | None = None,
) -> QKernel[..., Any]Configure a QKernel to remain visible as a named composite call.
This mutates and returns the same QKernel object. No wrapper class or alternate call protocol is introduced.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernel[..., Any] | Kernel to configure. |
name | str | None | Public callable name. Defaults to the kernel name. |
namespace | str | None | Explicit stable callable namespace. None derives one from the decorated function’s module, qualified name, and source location. Defaults to None. |
gate_type | CompositeGateType | Internal stdlib classification. Defaults to CUSTOM. |
policy | CallPolicy | Lowering policy. Defaults to PRESERVE_BOX. |
implementations | Sequence[CallableImplementation] | None | Optional implementation candidates. |
semantic_arguments | Mapping[str, Any] | None | Serializer-friendly arguments that are part of the operation’s meaning rather than its decomposition. Defaults to no semantic arguments. |
Returns:
QKernel[..., Any] — QKernel[..., Any]: The same configured kernel instance.
cx [source]¶
def cx(control: Qubit, target: Qubit) -> tuple[Qubit, Qubit]CNOT (Controlled-X) gate.
get_size [source]¶
def get_size(arr: Vector[_H]) -> intReturn the size of a Vector handle as a Python integer.
Resolves the leading axis of arr.shape through two forms a
Vector shape entry can take:
A plain Python
int(built-in bound shape; this is what you get fromqmc.qubit_array(N, ...)for literalN).A
UInthandle whose underlyingValuecarries a compile-time constant (set byuint(literal),_create_bound_input, or partial evaluation).
A UInt handle whose underlying Value is not a constant is
treated as an unresolved symbolic dimension and raises
ValueError even when the handle has the dataclass-default
init_value=0. Falling back to init_value for that case
would silently turn a runtime-symbolic Vector[Float] parameter
into a “size 0” array, hiding programming errors. Callers that
need to handle symbolic shapes (e.g., to emit a deferred callable
when the size is unknown) must catch the ValueError themselves.
Parameters:
| Name | Type | Description |
|---|---|---|
arr | Vector[Handle] | Vector handle whose first axis size is requested. |
Returns:
int — The first-axis size as a plain Python int.
Raises:
TypeError— If arr is not a 1-DVectorhandle (Vectoror itsVectorViewsubclass) — e.g., a scalarQubitwas passed where aVectoris required, a higher-rankMatrix/Tensorwas passed (this helper only resolves a 1-D first-axis size), or an unrelatedshape-bearing object such as a numpy array. This is a clearer signal than the bareAttributeErrorthatarr.shapewould otherwise raise, and it guards the stdlib / composite callers that resolve a register size through this helper.ValueError— If the shape cannot be resolved to a concrete integer — e.g., the Vector is a runtime-parametric handle without compile-time bindings, or carries aUIntdimension whose underlyingValuehas not been promoted to a constant.
mottonen_amplitude_encoding [source]¶
def mottonen_amplitude_encoding(
qubits: Vector[Qubit],
amplitudes: Sequence[float] | Sequence[complex] | np.ndarray | Vector[Float],
) -> Vector[Qubit]Prepare an amplitude-encoded state with the Möttönen construction.
This API makes Möttönen’s uniformly controlled Ry/Rz construction part of the callable identity. Backends therefore use Qamomile’s Möttönen body instead of replacing it with a generic native state-preparation operation. The input register must be in .
A concrete sequence or NumPy array may contain real or complex amplitudes.
A Vector[Float] parameter must be resolved through bindings at
compile time. For runtime parameters, precompute the Gray-walk angles and
call :func:mottonen_amplitude_encoding_from_angles.
Parameters:
| Name | Type | Description |
|---|---|---|
qubits | Vector[Qubit] | Vector of n qubit handles in . |
amplitudes | Sequence[float] | Sequence[complex] | np.ndarray | Vector[Float] | Amplitude vector of length 2**n. Values are normalized automatically. Vector[Float] values must be concrete at trace time. |
Returns:
Vector[Qubit] — Vector[Qubit]: The input vector updated to the prepared-state handles.
Raises:
ValueError— If a vector shape is unresolved, the amplitudes are invalid or unavailable at trace time, or the register width does not match the amplitude-vector length.
Example::
@qmc.qkernel
def prepare() -> qmc.Vector[qmc.Bit]:
q = qmc.qubit_array(2, name="q")
q = mottonen_amplitude_encoding(q, [1.0, 0.0, 0.0, 1.0])
return qmc.measure(q)mottonen_amplitude_encoding_from_angles [source]¶
def mottonen_amplitude_encoding_from_angles(
qubits: Vector[Qubit],
ry_angles: Sequence[float] | np.ndarray | Vector[Float],
rz_angles: Sequence[float] | np.ndarray | Vector[Float] | None = None,
) -> Vector[Qubit]Apply Möttönen amplitude encoding from pre-computed Ry / Rz angles.
.. important::
**Pre-condition: ``qubits`` must currently be in the all-zero
state** $|0\rangle^{\otimes n}$. The Möttönen Gray-walk
emission produced by these angle vectors only encodes the
intended state when starting from $|0\rangle^{\otimes n}$;
applied to any other input it produces ``U |\phi\rangle`` for
the same ``U`` and a different ``|\phi\rangle``, which is in
general not the target amplitude vector.Companion to :func:mottonen_amplitude_encoding for the parametric use
case: the user pre-computes the Gray-walk Ry (and optionally Rz)
angles classically with
:func:qamomile.linalg.compute_mottonen_amplitude_encoding_ry_angles
and
:func:qamomile.linalg.compute_mottonen_amplitude_encoding_rz_angles,
then passes them in as either concrete sequences or as
Vector[Float] handles obtained from kernel parameters. In the
latter case the angles can be left as runtime parameters
(transpiler.transpile(kernel, parameters=["ry_angles", ...]))
so the same compiled circuit can be re-bound to different
amplitude vectors without recompilation — useful inside hybrid
optimisation loops.
Unlike :func:mottonen_amplitude_encoding, this function does not create a
named composite invocation. The Ry / Rz / CNOT Gray-walk gates are emitted
directly into the surrounding kernel, so resource estimation and
visualization see the elementary operations.
Parameters:
| Name | Type | Description |
|---|---|---|
qubits | Vector[Qubit] | Vector of n qubit handles, expected to start in . |
ry_angles | Sequence[float] | np.ndarray | Vector[Float] | Gray-walk Ry angles for the magnitude stage. Must have length 2**n - 1. |
rz_angles | Sequence[float] | np.ndarray | Vector[Float] | None | Gray-walk Rz angles for the phase stage. Pass None (default) to skip the Rz stage entirely (real-amplitude path); otherwise must have length 2**n - 1 as well. |
Returns:
Vector[Qubit] — Vector[Qubit]: The same qubits vector, with each element
updated to the post-encoding qubit handle.
Raises:
ValueError— Ifry_angles/rz_anglesis a concrete sequence whose length does not match2**n - 1, or if thequbitsvector has an unresolved symbolic shape thatget_sizecannot reduce to a concrete integer. When the angle argument is aVector[Float]handle the length check is skipped (the shape may be symbolic at trace time); a runtime mismatch then surfaces as a backend bind-time error instead.
Example::
from qamomile.linalg import (
compute_mottonen_amplitude_encoding_ry_angles,
compute_mottonen_amplitude_encoding_rz_angles,
)
# Pre-compute classically (outside the kernel)
ry = compute_mottonen_amplitude_encoding_ry_angles(amps)
rz = compute_mottonen_amplitude_encoding_rz_angles(amps)
@qmc.qkernel
def prepare(
ry_a: qmc.Vector[qmc.Float],
rz_a: qmc.Vector[qmc.Float],
) -> qmc.Vector[qmc.Bit]:
q = qmc.qubit_array(2, name="q")
q = mottonen_amplitude_encoding_from_angles(q, ry_a, rz_a)
return qmc.measure(q)
exe = transpiler.transpile(prepare, parameters=["ry_a", "rz_a"])
# Same compiled circuit, re-bound at "runtime":
exe.run(transpiler.executor(),
bindings={"ry_a": ry.tolist(), "rz_a": rz.tolist()})ry [source]¶
def ry(
target: Union[Qubit, Vector[Qubit]],
angle: float | Float | UInt,
) -> Union[Qubit, Vector[Qubit]]Rotation around Y-axis: RY(angle) = exp(-i * angle/2 * Y).
Broadcasts the same angle over every qubit when called with a
Vector[Qubit].
Parameters:
| Name | Type | Description |
|---|---|---|
target | Union[Qubit, Vector[Qubit]] | A single Qubit or a Vector[Qubit]. |
angle | float | Float | UInt | Rotation angle in radians. |
Returns:
Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.
Raises:
TypeError— Iftargetis neither aQubitnor aVector[Qubit].
rz [source]¶
def rz(
target: Union[Qubit, Vector[Qubit]],
angle: float | Float | UInt,
) -> Union[Qubit, Vector[Qubit]]Rotation around Z-axis: RZ(angle) = exp(-i * angle/2 * Z).
Broadcasts the same angle over every qubit when called with a
Vector[Qubit].
Parameters:
| Name | Type | Description |
|---|---|---|
target | Union[Qubit, Vector[Qubit]] | A single Qubit or a Vector[Qubit]. |
angle | float | Float | UInt | Rotation angle in radians. |
Returns:
Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.
Raises:
TypeError— Iftargetis neither aQubitnor aVector[Qubit].
validate_and_normalize_amplitudes [source]¶
def validate_and_normalize_amplitudes(
amplitudes: Sequence[float] | Sequence[complex] | np.ndarray,
) -> tuple[np.ndarray, int, bool]Validate an amplitude vector and return its normalised form.
The Möttönen construction (arXiv:quant-ph/0407010, Section III) works on a unit-norm amplitude vector indexed by computational basis states; this helper enforces that pre-condition so the downstream angle computation can assume a well-formed input.
Inputs may be real or complex. A complex input whose imaginary
part is identically zero (within np.allclose tolerance) is
coerced to a real array; this preserves the cheaper signed-RY fast
path for vectors that happen to arrive boxed as complex.
Parameters:
| Name | Type | Description |
|---|---|---|
amplitudes | Sequence[float] | Sequence[complex] | np.ndarray | Amplitude vector. Must be a 1-D sequence whose length is a power of two and at least 2, with at least one non-zero entry. |
Returns:
tuple[np.ndarray, int, bool] — tuple[np.ndarray, int, bool]:
(normalized, num_qubits, is_complex) where
normalized is a unit-norm np.ndarray,
num_qubits is log2(len(amplitudes)), and
is_complex is True iff the input has a non-zero
imaginary component (and therefore needs the
phase-restoration stage downstream). When is_complex
is False, normalized.dtype is float; otherwise
it is complex.
Raises:
ValueError— If the input is not a 1-D vector (e.g., a nested sequence or a 2-Dnp.ndarray), the length is not a power of two (or is less than 2, i.e., would map to a zero-qubit register), or all amplitudes are zero.
Classes¶
CallPolicy [source]¶
class CallPolicy(enum.Enum)Describe the default lowering policy for a callable call.
Attributes¶
INLINENATIVE_FIRSTPRESERVE_BOX
QKernel [source]¶
class QKernel(QKernelBuildMixin, QKernelVisualizationMixin, Generic[P, R])Decorator class for Qamomile quantum kernels.
Constructor¶
def __init__(self, func: Callable[P, R]) -> NoneAttributes¶
block: Block Compile the function to a hierarchical Block if not already compiled.effects: KernelEffect Return cached semantic effects of this qkernel.funcinput_types: dict[str, Any] Return resolved and frozen frontend input annotations.nameoutput_types: list[Any] Return the resolved frontend annotation for every output slot.raw_funcreturn_type: Any Return the resolved and frozen complete return annotation.signature
qamomile.circuit.stdlib.multi_controlled_x¶
Provide a semantic multi-controlled X with a capability-driven fallback.
Overview¶
| Function | Description |
|---|---|
configure_composite | Configure a QKernel to remain visible as a named composite call. |
multi_controlled_x | Flip a target when every qubit in a control register is one. |
| Class | Description |
|---|---|
CallPolicy | Describe the default lowering policy for a callable call. |
Constants¶
mcx=multi_controlled_xShort public alias for :func:multi_controlled_x.
Functions¶
configure_composite [source]¶
def configure_composite(
kernel: QKernel[..., Any],
*,
name: str | None = None,
namespace: str | None = None,
gate_type: CompositeGateType = CompositeGateType.CUSTOM,
policy: CallPolicy = CallPolicy.PRESERVE_BOX,
implementations: Sequence[CallableImplementation] | None = None,
semantic_arguments: Mapping[str, Any] | None = None,
) -> QKernel[..., Any]Configure a QKernel to remain visible as a named composite call.
This mutates and returns the same QKernel object. No wrapper class or alternate call protocol is introduced.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernel[..., Any] | Kernel to configure. |
name | str | None | Public callable name. Defaults to the kernel name. |
namespace | str | None | Explicit stable callable namespace. None derives one from the decorated function’s module, qualified name, and source location. Defaults to None. |
gate_type | CompositeGateType | Internal stdlib classification. Defaults to CUSTOM. |
policy | CallPolicy | Lowering policy. Defaults to PRESERVE_BOX. |
implementations | Sequence[CallableImplementation] | None | Optional implementation candidates. |
semantic_arguments | Mapping[str, Any] | None | Serializer-friendly arguments that are part of the operation’s meaning rather than its decomposition. Defaults to no semantic arguments. |
Returns:
QKernel[..., Any] — QKernel[..., Any]: The same configured kernel instance.
multi_controlled_x [source]¶
def multi_controlled_x(controls: Vector[Qubit], target: Qubit) -> tuple[Vector[Qubit], Qubit]Flip a target when every qubit in a control register is one.
The function keeps the familiar qkernel call style while preserving one semantic operation for targets with an arbitrary-width controlled-X gate. Other targets execute the body through Qamomile’s controlled-gate lowering when their declared control-width profile admits it; narrower targets reject the call at the capability boundary.
Parameters:
| Name | Type | Description |
|---|---|---|
controls | Vector[Qubit] | Non-empty control register. |
target | Qubit | Target qubit to conditionally flip. |
Returns:
tuple[Vector[Qubit], Qubit] — tuple[Vector[Qubit], Qubit]: Updated controls and target.
Classes¶
CallPolicy [source]¶
class CallPolicy(enum.Enum)Describe the default lowering policy for a callable call.
Attributes¶
INLINENATIVE_FIRSTPRESERVE_BOX
qamomile.circuit.stdlib.qft¶
Provide QFT and inverse-QFT as ordinary named qkernels.
Overview¶
| Function | Description |
|---|---|
configure_composite | Configure a QKernel to remain visible as a named composite call. |
iqft | Apply the inverse quantum Fourier transform. |
qft | Apply the standard quantum Fourier transform. |
| Class | Description |
|---|---|
CallPolicy | Describe the default lowering policy for a callable call. |
CompositeGateType | Classify standard boxed quantum callables. |
Functions¶
configure_composite [source]¶
def configure_composite(
kernel: QKernel[..., Any],
*,
name: str | None = None,
namespace: str | None = None,
gate_type: CompositeGateType = CompositeGateType.CUSTOM,
policy: CallPolicy = CallPolicy.PRESERVE_BOX,
implementations: Sequence[CallableImplementation] | None = None,
semantic_arguments: Mapping[str, Any] | None = None,
) -> QKernel[..., Any]Configure a QKernel to remain visible as a named composite call.
This mutates and returns the same QKernel object. No wrapper class or alternate call protocol is introduced.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernel[..., Any] | Kernel to configure. |
name | str | None | Public callable name. Defaults to the kernel name. |
namespace | str | None | Explicit stable callable namespace. None derives one from the decorated function’s module, qualified name, and source location. Defaults to None. |
gate_type | CompositeGateType | Internal stdlib classification. Defaults to CUSTOM. |
policy | CallPolicy | Lowering policy. Defaults to PRESERVE_BOX. |
implementations | Sequence[CallableImplementation] | None | Optional implementation candidates. |
semantic_arguments | Mapping[str, Any] | None | Serializer-friendly arguments that are part of the operation’s meaning rather than its decomposition. Defaults to no semantic arguments. |
Returns:
QKernel[..., Any] — QKernel[..., Any]: The same configured kernel instance.
iqft [source]¶
def iqft(qubits: Vector[Qubit]) -> Vector[Qubit]Apply the inverse quantum Fourier transform.
Parameters:
| Name | Type | Description |
|---|---|---|
qubits | Vector[Qubit] | Register to transform. |
Returns:
Vector[Qubit] — Vector[Qubit]: Transformed register.
qft [source]¶
def qft(qubits: Vector[Qubit]) -> Vector[Qubit]Apply the standard quantum Fourier transform.
The Qamomile body remains attached to the named invocation for every register width. Backends may emit a native QFT, while other backends lower this same body during emission.
Parameters:
| Name | Type | Description |
|---|---|---|
qubits | Vector[Qubit] | Register to transform. |
Returns:
Vector[Qubit] — Vector[Qubit]: Transformed register.
Classes¶
CallPolicy [source]¶
class CallPolicy(enum.Enum)Describe the default lowering policy for a callable call.
Attributes¶
INLINENATIVE_FIRSTPRESERVE_BOX
CompositeGateType [source]¶
class CompositeGateType(enum.Enum)Classify standard boxed quantum callables.
Attributes¶
CUSTOMIQFTQFTQPE
qamomile.circuit.stdlib.qpe¶
Quantum Phase Estimation implementation.
Example:
@qmc.qkernel
def p_gate(q: qmc.Qubit, theta: float) -> qmc.Qubit:
return qmc.p(q, theta)
@qmc.qkernel
def circuit(theta: float) -> qmc.Float:
counting = qmc.qubit_array(3, name="counting")
target = qmc.qubit(name="target")
target = qmc.x(target)
phase = qmc.qpe(target, counting, p_gate, theta=theta)
return qmc.measure(phase)Overview¶
| Function | Description |
|---|---|
for_loop | Create a traced for loop in the Qamomile frontend. |
qpe | Quantum Phase Estimation. |
| Class | Description |
|---|---|
QKernelLike | Describe the frontend surface required by compiler entrypoints. |
Functions¶
for_loop [source]¶
def for_loop(
start,
stop,
step = 1,
var_name: str = '_loop_idx',
*,
captures: tuple[tuple[str, Any], ...] = (),
) -> Generator[UInt, None, None]Create a traced for loop in the Qamomile frontend.
Parameters:
| Name | Type | Description |
|---|---|---|
start | typing.Any | Inclusive loop start as an integer or UInt. |
stop | typing.Any | Exclusive loop stop as an integer or UInt. |
step | typing.Any | Nonzero loop step as an integer or UInt. Defaults to 1. |
var_name | str | Display name of the loop variable. Defaults to "_loop_idx". |
captures | tuple[tuple[str, typing.Any], ...] | Statically analyzed read-only body inputs. Defaults to an empty tuple. |
Yields:
UInt — The loop iteration variable (can be used as array index)
Raises:
TypeError— If a bound cannot be represented as a scalar IR value.ValueError— If the constructed loop has inconsistent region-result metadata.
Example:
@QKernel
def my_kernel(qubits: Array[Qubit, Literal[3]]) -> Array[Qubit, Literal[3]]:
for i in qm.range(3):
qubits[i] = h(qubits[i])
return qubits
@QKernel
def my_kernel2(qubits: Array[Qubit, Literal[5]]) -> Array[Qubit, Literal[5]]:
for i in qm.range(1, 4): # i = 1, 2, 3
qubits[i] = h(qubits[i])
return qubitsClassical scalar updates (total = total + i) become explicit
RegionArg records on the ForOperation: the loop enters with
the initializer, each iteration reads the previous iteration’s
value, and post-loop code reads the loop result.
qpe [source]¶
def qpe(
target: Qubit,
counting: Vector[Qubit],
unitary: QKernelLike,
**params: Any = {},
) -> QFixedQuantum Phase Estimation.
Estimates the phase φ where U|ψ> = e^{2πiφ}|ψ>.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Qubit | Eigenstate |psi> of the unitary. |
counting | Vector[Qubit] | Register that stores the phase estimate. |
unitary | QKernelLike | Unitary qkernel to control. |
**params | Any | Classical parameters forwarded to the unitary. |
Returns:
QFixed — Phase register as quantum fixed-point number
Classes¶
QKernelLike [source]¶
class QKernelLike(Protocol)Describe the frontend surface required by compiler entrypoints.
This protocol is intentionally structural. It lets decorator-created
composites reuse the qkernel inspection and build interface without making
them inherit from QKernel or exposing the compiler-facing callable
descriptor model as a frontend concept.
Attributes¶
block: Block Return the cached hierarchical body block.effects: KernelEffect Return cached semantic effects of the qkernel body.input_types: dict[str, Any] Return frontend input annotations by parameter name.name: str Return the user-facing callable name.output_types: list[Any] Return frontend output annotations.signature: inspect.Signature Return the Python call signature.
Methods¶
build¶
def build(self, parameters: list[str] | None = None, **kwargs: Any = {}) -> BlockBuild a traced body block.
Parameters:
| Name | Type | Description |
|---|---|---|
parameters | list[str] | None | Runtime parameter names to preserve. Defaults to None. |
**kwargs | Any | Compile-time bindings for non-parameter arguments. |
Returns:
Block — Traced hierarchical body block.
qamomile.circuit.stdlib.qsvt¶
Apply quantum singular value transformation to an LCU block encoding.
The public :func:qsvt helper composes a static
:class:~qamomile.circuit.stdlib.LCUBlockEncoding with a QSVT phase sequence.
Both inputs may remain unresolved while an enclosing qkernel is traced and
serialized. The block encoding is supplied through Qamomile’s static-binding
contract at transpile time, while phase values may be compile-time bindings or
backend runtime parameters when an explicit compile-time phase_count is
provided.
Overview¶
| Function | Description |
|---|---|
configure_composite | Configure a QKernel to remain visible as a named composite call. |
for_loop | Create a traced for loop in the Qamomile frontend. |
qsvt | Apply quantum singular value transformation to a block encoding. |
| Class | Description |
|---|---|
CallPolicy | Describe the default lowering policy for a callable call. |
Functions¶
configure_composite [source]¶
def configure_composite(
kernel: QKernel[..., Any],
*,
name: str | None = None,
namespace: str | None = None,
gate_type: CompositeGateType = CompositeGateType.CUSTOM,
policy: CallPolicy = CallPolicy.PRESERVE_BOX,
implementations: Sequence[CallableImplementation] | None = None,
semantic_arguments: Mapping[str, Any] | None = None,
) -> QKernel[..., Any]Configure a QKernel to remain visible as a named composite call.
This mutates and returns the same QKernel object. No wrapper class or alternate call protocol is introduced.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernel[..., Any] | Kernel to configure. |
name | str | None | Public callable name. Defaults to the kernel name. |
namespace | str | None | Explicit stable callable namespace. None derives one from the decorated function’s module, qualified name, and source location. Defaults to None. |
gate_type | CompositeGateType | Internal stdlib classification. Defaults to CUSTOM. |
policy | CallPolicy | Lowering policy. Defaults to PRESERVE_BOX. |
implementations | Sequence[CallableImplementation] | None | Optional implementation candidates. |
semantic_arguments | Mapping[str, Any] | None | Serializer-friendly arguments that are part of the operation’s meaning rather than its decomposition. Defaults to no semantic arguments. |
Returns:
QKernel[..., Any] — QKernel[..., Any]: The same configured kernel instance.
for_loop [source]¶
def for_loop(
start,
stop,
step = 1,
var_name: str = '_loop_idx',
*,
captures: tuple[tuple[str, Any], ...] = (),
) -> Generator[UInt, None, None]Create a traced for loop in the Qamomile frontend.
Parameters:
| Name | Type | Description |
|---|---|---|
start | typing.Any | Inclusive loop start as an integer or UInt. |
stop | typing.Any | Exclusive loop stop as an integer or UInt. |
step | typing.Any | Nonzero loop step as an integer or UInt. Defaults to 1. |
var_name | str | Display name of the loop variable. Defaults to "_loop_idx". |
captures | tuple[tuple[str, typing.Any], ...] | Statically analyzed read-only body inputs. Defaults to an empty tuple. |
Yields:
UInt — The loop iteration variable (can be used as array index)
Raises:
TypeError— If a bound cannot be represented as a scalar IR value.ValueError— If the constructed loop has inconsistent region-result metadata.
Example:
@QKernel
def my_kernel(qubits: Array[Qubit, Literal[3]]) -> Array[Qubit, Literal[3]]:
for i in qm.range(3):
qubits[i] = h(qubits[i])
return qubits
@QKernel
def my_kernel2(qubits: Array[Qubit, Literal[5]]) -> Array[Qubit, Literal[5]]:
for i in qm.range(1, 4): # i = 1, 2, 3
qubits[i] = h(qubits[i])
return qubitsClassical scalar updates (total = total + i) become explicit
RegionArg records on the ForOperation: the loop enters with
the initializer, each iteration reads the previous iteration’s
value, and post-loop code reads the loop result.
qsvt [source]¶
def qsvt(
signal: qmc.Vector[qmc.Qubit],
system: qmc.Vector[qmc.Qubit],
phases: qmc.Vector[qmc.Float],
encoding: LCUBlockEncoding,
phase_count: int | qmc.UInt | None = None,
) -> tuple[qmc.Vector[qmc.Qubit], qmc.Vector[qmc.Qubit]]Apply quantum singular value transformation to a block encoding.
For phases = (phi_0, ..., phi_d), Qamomile applies
R(phi_0), U, R(phi_1), U dagger, ..., where
R(phi) = exp(i * phi * (2 Pi - I)) and Pi projects the complete
signal register onto all zero. One clean internal auxiliary qubit realizes
these projector rotations and is restored after every phase. At least one
phase is required.
If the leading block of encoding.unitary is A / alpha, with
alpha = encoding.normalization, the supplied phase sequence transforms
singular values of A / alpha. Phase synthesis, polynomial parity, and
approximation-domain checks are problem dependent and remain the caller’s
responsibility; this helper implements the quantum sequence itself. The
input values must already use the projector-rotation convention above.
Raw phases produced for a different QSP signal operator or rotation
convention, including pyqsp’s Wx convention, must be converted first.
By default, phase_count comes from phases.shape[0]. This is the
shortest API when phases are supplied through bindings at transpile
time. To compile once and retain phases as a backend runtime parameter
array, pass a separate phase_count argument and bind that count at
transpile time; the phase values can then be supplied when the executable
runs. For a phase vector resolved through transpile-time bindings, an
explicit count selects a prefix; the vector must contain at least that many
values, and any remaining values are ignored. For a phase vector preserved
as a runtime parameter, the executable ABI requires exactly phase_count
values; shorter and longer runtime vectors are rejected. Omitting the count
applies the complete compile-time vector.
The helper emits serializable IR directly into the enclosing qkernel. That
qkernel may therefore be traced and serialized before either encoding
or the phase values are known. Do not capture a concrete descriptor in a
module global; declare an LCUBlockEncoding argument on the enclosing
qkernel and bind it after deserialization. A source-backed call rejects a
non-positive concrete count immediately; the equivalent invalid binding on
a deserialized template is rejected as a compilation error when the empty
selected phase prefix is resolved.
Parameters:
| Name | Type | Description |
|---|---|---|
signal | qmc.Vector[qmc.Qubit] | Signal register with exactly encoding.num_signal_qubits qubits. |
system | qmc.Vector[qmc.Qubit] | System register with exactly encoding.num_system_qubits qubits. |
phases | qmc.Vector[qmc.Float] | QSVT projector phases in radians, in sequence order. |
encoding | LCUBlockEncoding | Static exact LCU block encoding whose normalized leading block is transformed. |
phase_count | int | qmc.UInt | None | Number of phase elements to use. Defaults to the phase vector length. For compile-time phase bindings, an explicit count selects a prefix and the vector must contain at least that many values. When phases is preserved as a runtime parameter array, the count must be supplied at compile time and the runtime vector must have exactly that length. |
Returns:
tuple[qmc.Vector[qmc.Qubit], qmc.Vector[qmc.Qubit]] — tuple[qmc.Vector[qmc.Qubit], qmc.Vector[qmc.Qubit]]: Transformed signal
and system registers.
Raises:
TypeError— Ifphasesis not aqmc.Vector[qmc.Float]handle, or if an explicitphase_countis a boolean or is neither an integer nor a UInt handle.ValueError— If a concrete count is not positive.
Example:
>>> import qamomile.circuit as qmc
>>> from qamomile.circuit.serialization import deserialize, serialize
>>> from qamomile.linalg import PeriodicShiftLCU
>>> from qamomile.qiskit import QiskitTranspiler
>>> @qmc.qkernel
... def transform(
... encoding: qmc.LCUBlockEncoding,
... phases: qmc.Vector[qmc.Float],
... ) -> tuple[qmc.Vector[qmc.Bit], qmc.Vector[qmc.Bit]]:
... signal = qmc.qubit_array(encoding.num_signal_qubits, "signal")
... system = qmc.qubit_array(encoding.num_system_qubits, "system")
... signal, system = qmc.qsvt(signal, system, phases, encoding)
... return qmc.measure(signal), qmc.measure(system)
>>> payload = serialize(transform)
>>> received = deserialize(payload)
>>> lcu = PeriodicShiftLCU.from_coefficients(
... {-1: 1.0, 0: -2.0, 1: 1.0},
... register_sizes=(2,),
... )
>>> block_encoding = qmc.periodic_shift_lcu_block_encoding(lcu)
>>> executable = QiskitTranspiler().transpile(
... received,
... bindings={
... "encoding": block_encoding,
... "phases": [0.2, -0.4, 0.7],
... },
... )Classes¶
CallPolicy [source]¶
class CallPolicy(enum.Enum)Describe the default lowering policy for a callable call.
Attributes¶
INLINENATIVE_FIRSTPRESERVE_BOX
qamomile.circuit.stdlib.state_preparation¶
State-preparation building blocks.
Available routines:
:func:
computational_basis_state: prepare|bits>from via exact conditionalXpowers. The parameterized RX implementation includes phase compensation, sobitscan remain a runtime parameter and the routine can be controlled without exposing an unintended relative phase.:func:
amplitude_encoding: prepare an arbitrary real- or complex-amplitude state from . The synthesis method is unspecified, so a backend may select a native state-preparation implementation. Qamomile’s portable fallback currently uses the Möttönen construction.:func:
mottonen_amplitude_encoding: prepare the same target state while making Möttönen’s uniformly controlled Ry/Rz construction part of the API contract.:func:
mottonen_amplitude_encoding_from_angles: the parametric Möttönen companion. It accepts pre-computed Ry and optional Rz angles as concrete sequences orVector[Float]kernel parameters.:func:
amplitude_encoding_from_angles: compatibility name for :func:mottonen_amplitude_encoding_from_angles.
The classical Möttönen angle precomputation
(compute_mottonen_amplitude_encoding_ry_angles /
compute_mottonen_amplitude_encoding_rz_angles) lives in
:mod:qamomile.linalg. Import them from there directly when you need
to feed pre-computed angles into
mottonen_amplitude_encoding_from_angles::
from qamomile.linalg import (
compute_mottonen_amplitude_encoding_ry_angles,
compute_mottonen_amplitude_encoding_rz_angles,
)Overview¶
| Function | Description |
|---|---|
amplitude_encoding | Prepare an amplitude-encoded state with a backend-selected synthesis. |
amplitude_encoding_from_angles | Apply Möttönen encoding from angles through the compatibility API. |
mottonen_amplitude_encoding_from_angles | Apply Möttönen amplitude encoding from pre-computed Ry / Rz angles. |
Functions¶
amplitude_encoding [source]¶
def amplitude_encoding(
qubits: Vector[Qubit],
amplitudes: Sequence[float] | Sequence[complex] | np.ndarray | Vector[Float],
) -> Vector[Qubit]Prepare an amplitude-encoded state with a backend-selected synthesis.
The semantic contract is that an all-zero n-qubit register becomes the
normalized state . The synthesis algorithm is
intentionally unspecified: a backend may use its native state-preparation
implementation. Qamomile’s portable fallback currently uses the Möttönen
construction.
State-preparation algorithms can implement different unitaries away from
the all-zero input even when they prepare the same target state. Use
:func:mottonen_amplitude_encoding when the exact construction, its
resource profile, or transformed uses such as inverse and control matter.
A concrete sequence or NumPy array may contain real or complex amplitudes.
A Vector[Float] parameter must be resolved through bindings at
compile time. For runtime-parametric Möttönen angles, use
:func:mottonen_amplitude_encoding_from_angles.
Parameters:
| Name | Type | Description |
|---|---|---|
qubits | Vector[Qubit] | Vector of n qubit handles in . |
amplitudes | Sequence[float] | Sequence[complex] | np.ndarray | Vector[Float] | Amplitude vector of length 2**n. Values are normalized automatically. Vector[Float] values must be concrete at trace time. |
Returns:
Vector[Qubit] — Vector[Qubit]: The input vector updated to the prepared-state handles.
Raises:
ValueError— If a vector shape is unresolved, the amplitudes are invalid or unavailable at trace time, or the register width does not match the amplitude-vector length.
Example::
@qmc.qkernel
def prepare() -> qmc.Vector[qmc.Bit]:
q = qmc.qubit_array(2, name="q")
q = amplitude_encoding(q, [1.0, 0.0, 0.0, 1.0])
return qmc.measure(q)amplitude_encoding_from_angles [source]¶
def amplitude_encoding_from_angles(
qubits: Vector[Qubit],
ry_angles: Sequence[float] | np.ndarray | Vector[Float],
rz_angles: Sequence[float] | np.ndarray | Vector[Float] | None = None,
) -> Vector[Qubit]Apply Möttönen encoding from angles through the compatibility API.
This function preserves the original public name and delegates directly to
:func:mottonen_amplitude_encoding_from_angles. New code should prefer the
algorithm-specific name because angle vectors define the Möttönen Gray-walk
decomposition rather than generic amplitude encoding.
Parameters:
| Name | Type | Description |
|---|---|---|
qubits | Vector[Qubit] | Vector of n qubit handles in . |
ry_angles | Sequence[float] | np.ndarray | Vector[Float] | Gray-walk Ry angles of length 2**n - 1. |
rz_angles | Sequence[float] | np.ndarray | Vector[Float] | None | Optional Gray-walk Rz angles of length 2**n - 1. |
Returns:
Vector[Qubit] — Vector[Qubit]: The input vector updated to the prepared-state handles.
Raises:
ValueError— If a concrete angle vector has the wrong length or the qubit-vector shape cannot be resolved.
mottonen_amplitude_encoding_from_angles [source]¶
def mottonen_amplitude_encoding_from_angles(
qubits: Vector[Qubit],
ry_angles: Sequence[float] | np.ndarray | Vector[Float],
rz_angles: Sequence[float] | np.ndarray | Vector[Float] | None = None,
) -> Vector[Qubit]Apply Möttönen amplitude encoding from pre-computed Ry / Rz angles.
.. important::
**Pre-condition: ``qubits`` must currently be in the all-zero
state** $|0\rangle^{\otimes n}$. The Möttönen Gray-walk
emission produced by these angle vectors only encodes the
intended state when starting from $|0\rangle^{\otimes n}$;
applied to any other input it produces ``U |\phi\rangle`` for
the same ``U`` and a different ``|\phi\rangle``, which is in
general not the target amplitude vector.Companion to :func:mottonen_amplitude_encoding for the parametric use
case: the user pre-computes the Gray-walk Ry (and optionally Rz)
angles classically with
:func:qamomile.linalg.compute_mottonen_amplitude_encoding_ry_angles
and
:func:qamomile.linalg.compute_mottonen_amplitude_encoding_rz_angles,
then passes them in as either concrete sequences or as
Vector[Float] handles obtained from kernel parameters. In the
latter case the angles can be left as runtime parameters
(transpiler.transpile(kernel, parameters=["ry_angles", ...]))
so the same compiled circuit can be re-bound to different
amplitude vectors without recompilation — useful inside hybrid
optimisation loops.
Unlike :func:mottonen_amplitude_encoding, this function does not create a
named composite invocation. The Ry / Rz / CNOT Gray-walk gates are emitted
directly into the surrounding kernel, so resource estimation and
visualization see the elementary operations.
Parameters:
| Name | Type | Description |
|---|---|---|
qubits | Vector[Qubit] | Vector of n qubit handles, expected to start in . |
ry_angles | Sequence[float] | np.ndarray | Vector[Float] | Gray-walk Ry angles for the magnitude stage. Must have length 2**n - 1. |
rz_angles | Sequence[float] | np.ndarray | Vector[Float] | None | Gray-walk Rz angles for the phase stage. Pass None (default) to skip the Rz stage entirely (real-amplitude path); otherwise must have length 2**n - 1 as well. |
Returns:
Vector[Qubit] — Vector[Qubit]: The same qubits vector, with each element
updated to the post-encoding qubit handle.
Raises:
ValueError— Ifry_angles/rz_anglesis a concrete sequence whose length does not match2**n - 1, or if thequbitsvector has an unresolved symbolic shape thatget_sizecannot reduce to a concrete integer. When the angle argument is aVector[Float]handle the length check is skipped (the shape may be symbolic at trace time); a runtime mismatch then surfaces as a backend bind-time error instead.
Example::
from qamomile.linalg import (
compute_mottonen_amplitude_encoding_ry_angles,
compute_mottonen_amplitude_encoding_rz_angles,
)
# Pre-compute classically (outside the kernel)
ry = compute_mottonen_amplitude_encoding_ry_angles(amps)
rz = compute_mottonen_amplitude_encoding_rz_angles(amps)
@qmc.qkernel
def prepare(
ry_a: qmc.Vector[qmc.Float],
rz_a: qmc.Vector[qmc.Float],
) -> qmc.Vector[qmc.Bit]:
q = qmc.qubit_array(2, name="q")
q = mottonen_amplitude_encoding_from_angles(q, ry_a, rz_a)
return qmc.measure(q)
exe = transpiler.transpile(prepare, parameters=["ry_a", "rz_a"])
# Same compiled circuit, re-bound at "runtime":
exe.run(transpiler.executor(),
bindings={"ry_a": ry.tolist(), "rz_a": rz.tolist()})