Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

qamomile.circuit

Overview

FunctionDescription
bitCreate a Bit handle from a boolean/int literal or declare a named Bit parameter.
castCast a quantum value to a different type without allocating new qubits.
ccxToffoli (CCX) gate: flips target when both controls are |1>.
composite_gateDecorator to create a CompositeGate from a qkernel function or as a stub.
controlledCreate a controlled version of a quantum gate (QKernel).
cpControlled-Phase gate.
cxCNOT (Controlled-X) gate.
czCZ (Controlled-Z) gate.
expvalCompute the expectation value of an observable on a quantum state.
float_Create a Float handle from a float literal or declare a named Float parameter.
for_itemsBuilder function to create a for-items loop in Qamomile frontend.
hHadamard gate.
itemsIterate over dictionary key-value pairs.
measureMeasure a qubit or QFixed in the computational basis.
pPhase gate: P(theta)|1> = e^{i*theta}|1>.
qkernelDecorator to define a Qamomile quantum kernel.
qubitCreate a new qubit and emit a QInitOperation.
qubit_arrayCreate a new qubit array (vector/matrix/tensor) and emit QInitOperations.
rangeSymbolic range for use in qkernel for-loops.
rxRotation around X-axis: RX(angle) = exp(-i * angle/2 * X).
ryRotation around Y-axis: RY(angle) = exp(-i * angle/2 * Y).
rzRotation around Z-axis: RZ(angle) = exp(-i * angle/2 * Z).
rzzRZZ gate: exp(-i * angle/2 * Z ⊗ Z).
sS gate (square root of Z).
sdgS-dagger gate (inverse of S gate).
swapSWAP gate: exchanges two qubits.
tT gate (fourth root of Z).
tdgT-dagger gate (inverse of T gate).
uintCreate a UInt handle from an integer literal or declare a named UInt parameter.
xPauli-X gate (NOT gate).
yPauli-Y gate.
zPauli-Z gate.
ClassDescription
CompositeGateBase class for user-facing composite gate definitions.
QKernelDecorator class for Qamomile quantum kernels.

Functions

bit [source]

def bit(arg: bool | str | int) -> Bit

Create a Bit handle from a boolean/int literal or declare a named Bit parameter.


cast [source]

def cast(source: Vector[Qubit], target_type: type, *, int_bits: int = 0) -> QFixed

Cast a quantum value to a different type without allocating new qubits.

The cast performs a move: the source handle is consumed and cannot be reused after the cast. The returned handle references the same physical qubits.

Parameters:

NameTypeDescription
sourceVector[Qubit]The value to cast (currently supports Vector[Qubit])
target_typetypeThe target type class (currently supports QFixed)
int_bitsintFor QFixed, number of integer bits (default: 0 = all fractional)

Returns:

QFixed — A new handle of the target type referencing the same qubits.

Example:

@qmc.qkernel
def my_circuit():
    phase_register = qmc.qubit_array(5, name="phase")
    # ... apply some operations ...

    # Cast the qubit array to QFixed for measurement
    phase_qfixed = qmc.cast(phase_register, qmc.QFixed, int_bits=0)
    phase_value = qmc.measure(phase_qfixed)
    return phase_value

Raises:


ccx [source]

def ccx(control1: Qubit, control2: Qubit, target: Qubit) -> tuple[Qubit, Qubit, Qubit]

Toffoli (CCX) gate: flips target when both controls are |1>.

Parameters:

NameTypeDescription
control1QubitFirst control qubit.
control2QubitSecond control qubit.
targetQubitTarget qubit.

Returns:

tuple[Qubit, Qubit, Qubit] — Tuple of (control1_out, control2_out, target_out) after CCX.


composite_gate [source]

def composite_gate(
    func: Callable | None = None,
    *,
    stub: bool = False,
    name: str = '',
    num_qubits: int | None = None,
    num_controls: int = 0,
    resource_metadata: ResourceMetadata | None = None,
    gate_type: CompositeGateType = CompositeGateType.CUSTOM,
) -> _WrappedCompositeGate | _StubCompositeGate | Callable[[Callable], _WrappedCompositeGate | _StubCompositeGate]

Decorator to create a CompositeGate from a qkernel function or as a stub.

Usage with qkernel (implementation provided): composite_gate [source](name=“my_qft”) qkernel [source] def my_qft(q0: Qubit, q1: Qubit) -> tuple[Qubit, Qubit]: q0 = h(q0) q0, q1 = cp(q0, q1, pi/2) q1 = h(q1) return q0, q1

# Usage:
q0, q1 = my_qft(q0, q1)

Usage as stub (no implementation, for resource estimation): composite_gate [source]( stub=True, name=“oracle”, num_qubits=5, resource_metadata=ResourceMetadata(query_complexity=100, t_gates=10), ) def oracle(): pass

# Usage:
results = oracle(*qubits)
metadata = oracle.get_resource_metadata()

Parameters:

NameTypeDescription
funcCallable | NoneThe qkernel function (when used without arguments)
stubboolIf True, create a stub gate with no implementation
namestrName for the composite gate
num_qubitsint | NoneNumber of target qubits (required for stub)
num_controlsintNumber of control qubits (default: 0)
resource_metadataResourceMetadata | NoneResourceMetadata for resource estimation (stub mode)
gate_typeCompositeGateTypeThe type of composite gate (default: CUSTOM)

Returns:

_WrappedCompositeGate | _StubCompositeGate | Callable[[Callable], _WrappedCompositeGate | _StubCompositeGate] — A CompositeGate instance that can be called like a gate function.


controlled [source]

def controlled(qkernel: 'QKernel', num_controls: int | UInt = 1) -> ControlledGate

Create a controlled version of a quantum gate (QKernel).

Parameters:

NameTypeDescription
qkernel'QKernel'A QKernel defining the gate to control.
num_controlsint | UIntNumber of control qubits (default: 1). Can be int (concrete) or UInt (symbolic).

Returns:

ControlledGate — ControlledGate that can be called with (*controls, *targets, **params)

Example:

@qmc.qkernel
def rx_gate(q: Qubit, theta: float) -> Qubit:
    return qmc.rx(q, theta)

crx = qmc.controlled(rx_gate)
ctrl_out, tgt_out = crx(ctrl_qubit, target_qubit, theta=0.5)

# Double-controlled
ccrx = qmc.controlled(rx_gate, num_controls=2)
c0, c1, tgt = ccrx(ctrl0, ctrl1, target, theta=0.5)

cp [source]

def cp(control: Qubit, target: Qubit, theta: float | Float) -> tuple[Qubit, Qubit]

Controlled-Phase gate.


cx [source]

def cx(control: Qubit, target: Qubit) -> tuple[Qubit, Qubit]

CNOT (Controlled-X) gate.


cz [source]

def cz(control: Qubit, target: Qubit) -> tuple[Qubit, Qubit]

CZ (Controlled-Z) gate.


expval [source]

def expval(qubits: Vector[Qubit] | tuple[Qubit, ...], hamiltonian: Observable) -> Float

Compute the expectation value of an observable on a quantum state.

This function computes <psi|H|psi> where psi is the quantum state represented by the qubits and H is the Hamiltonian observable.

The quantum state (qubits) is NOT consumed by this operation - the qubits can still be used for further operations after expval.

Parameters:

NameTypeDescription
qubitsVector[Qubit] | tuple[Qubit, ...]The quantum register holding the prepared state. Can be a Vector[Qubit] or a tuple of individual Qubits.
hamiltonianObservableThe Observable parameter representing the Hamiltonian. The actual qamomile.observable.Hamiltonian is provided via bindings.

Returns:

Float — Float containing the expectation value.

Example:

import qamomile.circuit as qm
import qamomile.observable as qm_o

# Build Hamiltonian in Python
H = qm_o.Z(0) * qm_o.Z(1) + 0.5 * (qm_o.X(0) + qm_o.X(1))

@qm.qkernel
def vqe_step(q: qm.Vector[qm.Qubit], H: qm.Observable) -> qm.Float:
    # Ansatz
    q[0] = qm.ry(q[0], theta)
    q[0], q[1] = qm.cx(q[0], q[1])

    # Expectation value -> Float
    return qm.expval(q, H)

# Pass Hamiltonian via bindings
executable = transpiler.transpile(vqe_step, bindings={"H": H})

float_ [source]

def float_(arg: float | str) -> Float

Create a Float handle from a float literal or declare a named Float parameter.


for_items [source]

def for_items(
    d: Dict,
    key_var_names: list[str],
    value_var_name: str,
) -> Generator[tuple[Any, Any], None, None]

Builder function to create a for-items loop in Qamomile frontend.

This context manager creates a ForItemsOperation that iterates over dictionary (key, value) pairs. The operation is always unrolled at transpile time since quantum backends cannot natively iterate over classical data structures.

Parameters:

NameTypeDescription
dDictDict handle to iterate over
key_var_nameslist[str]Names of key unpacking variables (e.g., [“i”, “j”] for tuple keys)
value_var_namestrName of value variable (e.g., “Jij”)

Yields:

tuple[typing.Any, typing.Any] — Tuple of (key_handles, value_handle) for use in loop body

Example:

@qkernel
def ising_cost(
    q: Vector[Qubit],
    ising: Dict[Tuple[UInt, UInt], Float],
    gamma: Float,
) -> Vector[Qubit]:
    for (i, j), Jij in qmc.items(ising):
        q[i], q[j] = qmc.rzz(q[i], q[j], gamma * Jij)
    return q

h [source]

def h(qubit: Qubit) -> Qubit

Hadamard gate.


items [source]

def items(d: Dict) -> DictItemsIterator

Iterate over dictionary key-value pairs.

This function returns an iterator over (key, value) pairs from a Dict. Used for iterating over Ising coefficients and similar data structures.

Example:

for (i, j), Jij in qmc.items(ising):
    q[i], q[j] = qmc.rzz(q[i], q[j], gamma * Jij)

Parameters:

NameTypeDescription
dDictA Dict handle to iterate over

Returns:

DictItemsIterator — DictItemsIterator yielding (key, value) pairs


measure [source]

def measure(target: Union[Qubit, QFixed, Vector[Qubit]]) -> Union[Bit, Float, Vector[Bit]]

Measure a qubit or QFixed in the computational basis.

Performs a projective measurement in the Z-basis. The quantum resource is consumed by this operation and cannot be used afterwards.

Parameters:

NameTypeDescription
targetUnion[Qubit, QFixed, Vector[Qubit]]The quantum resource to measure. - Qubit: Returns a classical Bit - QFixed: Returns a Float (decoded from measured bits)

Returns:

Union[Bit, Float, Vector[Bit]] — Bit for Qubit input, Float for QFixed input.

Example:

@qkernel
def measure_qubit(q: Qubit) -> Bit:
    q = h(q)
    return measure(q)

@qkernel
def measure_qfixed(qf: QFixed) -> Float:
    # After QPE, qf holds phase bits
    return measure(qf)

p [source]

def p(qubit: Qubit, theta: float | Float) -> Qubit

Phase gate: P(theta)|1> = e^{i*theta}|1>.


qkernel [source]

def qkernel(func: Callable[P, R]) -> QKernel[P, R]

Decorator to define a Qamomile quantum kernel.

Parameters:

NameTypeDescription
funcCallable[P, R]The function to decorate.

Returns:

QKernel[P, R] — An instance of QKernel wrapping the function.


qubit [source]

def qubit(name: str) -> Qubit

Create a new qubit and emit a QInitOperation.


qubit_array [source]

def qubit_array(
    shape: UInt | int | tuple[UInt | int, ...],
    name: str,
) -> Vector[Qubit] | Matrix[Qubit] | Tensor[Qubit]

Create a new qubit array (vector/matrix/tensor) and emit QInitOperations.


range [source]

def range(
    stop_or_start: int | UInt,
    stop: int | UInt | None = None,
    step: int | UInt = 1,
) -> Iterator[UInt]

Symbolic range for use in qkernel for-loops.

This function accepts UInt (symbolic) values and is transformed by the AST transformer into for_loop() calls.

Example:

for i in qmc.range(n):          # 0 to n-1
for i in qmc.range(start, stop):  # start to stop-1
for i in qmc.range(start, stop, step):

rx [source]

def rx(qubit: Qubit, angle: float | Float) -> Qubit

Rotation around X-axis: RX(angle) = exp(-i * angle/2 * X).


ry [source]

def ry(qubit: Qubit, angle: float | Float) -> Qubit

Rotation around Y-axis: RY(angle) = exp(-i * angle/2 * Y).


rz [source]

def rz(qubit: Qubit, angle: float | Float) -> Qubit

Rotation around Z-axis: RZ(angle) = exp(-i * angle/2 * Z).


rzz [source]

def rzz(qubit_0: Qubit, qubit_1: Qubit, angle: float | Float) -> tuple[Qubit, Qubit]

RZZ gate: exp(-i * angle/2 * Z ⊗ Z).

The RZZ gate applies a rotation around the ZZ axis on two qubits.

Parameters:

NameTypeDescription
qubit_0QubitFirst qubit.
qubit_1QubitSecond qubit.
anglefloat | FloatRotation angle in radians.

Returns:

tuple[Qubit, Qubit] — Tuple of (qubit_0_out, qubit_1_out) after RZZ.


s [source]

def s(qubit: Qubit) -> Qubit

S gate (square root of Z).


sdg [source]

def sdg(qubit: Qubit) -> Qubit

S-dagger gate (inverse of S gate).


swap [source]

def swap(qubit_0: Qubit, qubit_1: Qubit) -> tuple[Qubit, Qubit]

SWAP gate: exchanges two qubits.

The SWAP gate swaps the states of two qubits.

Parameters:

NameTypeDescription
qubit_0QubitFirst qubit.
qubit_1QubitSecond qubit.

Returns:

tuple[Qubit, Qubit] — Tuple of (qubit_0_out, qubit_1_out) after SWAP.


t [source]

def t(qubit: Qubit) -> Qubit

T gate (fourth root of Z).


tdg [source]

def tdg(qubit: Qubit) -> Qubit

T-dagger gate (inverse of T gate).


uint [source]

def uint(arg: int | str) -> UInt

Create a UInt handle from an integer literal or declare a named UInt parameter.


x [source]

def x(qubit: Qubit) -> Qubit

Pauli-X gate (NOT gate).


y [source]

def y(qubit: Qubit) -> Qubit

Pauli-Y gate.


z [source]

def z(qubit: Qubit) -> Qubit

Pauli-Z gate.

Classes

CompositeGate [source]

class CompositeGate(abc.ABC)

Base class for user-facing composite gate definitions.

Subclasses can define composite gates in two ways:

  1. Using _decompose() (recommended for users): Define the gate decomposition using frontend syntax (same as qkernel [source]).

    class QFT(CompositeGate):
        def __init__(self, num_qubits: int):
            self._num_qubits = num_qubits
    
        @property
        def num_target_qubits(self) -> int:
            return self._num_qubits
    
        def _decompose(self, qubits: Vector[Qubit]) -> Vector[Qubit]:
            # Use frontend syntax: qm.h(), qm.cp(), qm.range(), etc.
            n = self._num_qubits
            for j in qmc.range(n - 1, -1, -1):
                qubits[j] = qmc.h(qubits[j])
                for k in qmc.range(j - 1, -1, -1):
                    angle = math.pi / (2 ** (j - k))
                    qubits[j], qubits[k] = qmc.cp(qubits[j], qubits[k], angle)
            return qubits
    
        def _resources(self) -> ResourceMetadata:
            return ResourceMetadata(t_gates=0)
  2. Using get_implementation() (advanced): Return a pre-built BlockValue directly.

Example usage:

# Factory function pattern
def qft(qubits: Vector[Qubit]) -> Vector[Qubit]:
    n = _get_size(qubits)
    return QFT(n)(qubits)

# Direct class usage
result = QFT(3)(*qubit_list)

Attributes

Methods

build_decomposition
def build_decomposition(self, *qubits: Qubit = (), **params: Any = {}) -> 'BlockValue | None'

Build the decomposition circuit dynamically.

Override this method to provide a decomposition that depends on runtime arguments (e.g., QPE needs the unitary BlockValue).

This method is called by InlinePass when inlining composite gates that have dynamic implementations.

Parameters:

NameTypeDescription
*qubitsQubitThe qubits passed to the gate
**paramsAnyAdditional parameters (e.g., unitary for QPE)

Returns:

'BlockValue | None' — BlockValue containing the decomposition, or None if not available.

Example:

class QPE(CompositeGate):
    def build_decomposition(self, *qubits, **params):
        unitary = params.get("unitary")
        # Build QPE circuit using the unitary
        return self._build_qpe_impl(qubits, unitary)
get_implementation
def get_implementation(self) -> 'BlockValue | None'

Get the implementation BlockValue, if any.

Return None for stub gates (used in resource estimation). Override in subclasses to provide implementation.

Note: If _decompose() is defined, it takes precedence over this method.

get_resource_metadata
def get_resource_metadata(self) -> ResourceMetadata | None

Get resource estimation metadata.

Returns _resources() if defined, otherwise None. Override _resources() to provide resource hints.

get_resources_for_strategy
def get_resources_for_strategy(self, strategy_name: str | None = None) -> ResourceMetadata | None

Get resource metadata for a specific strategy.

Parameters:

NameTypeDescription
strategy_namestr | NoneStrategy to query, or None for default

Returns:

ResourceMetadata | None — ResourceMetadata for the strategy, or None if not available

get_strategy
@classmethod
def get_strategy(cls, name: str | None = None) -> 'DecompositionStrategy | None'

Get a registered decomposition strategy.

Parameters:

NameTypeDescription
namestr | NoneStrategy name, or None for default strategy

Returns:

'DecompositionStrategy | None' — DecompositionStrategy instance, or None if not found

list_strategies
@classmethod
def list_strategies(cls) -> list[str]

List all registered strategy names.

Returns:

list[str] — List of strategy names

register_strategy
@classmethod
def register_strategy(cls, name: str, strategy: 'DecompositionStrategy') -> None

Register a decomposition strategy for this gate type.

Parameters:

NameTypeDescription
namestrStrategy identifier (e.g., “standard”, “approximate”)
strategy'DecompositionStrategy'DecompositionStrategy instance

Example:

QFT.register_strategy("approximate", ApproximateQFTStrategy(k=3))
set_default_strategy
@classmethod
def set_default_strategy(cls, name: str) -> None

Set the default decomposition strategy.

Parameters:

NameTypeDescription
namestrStrategy name to use as default

Raises:


QKernel [source]

class QKernel(Generic[P, R])

Decorator class for Qamomile quantum kernels.

Constructor

def __init__(self, func: Callable[P, R]) -> None

Attributes

Methods

build
def build(self, parameters: list[str] | None = None, **kwargs: Any = {}) -> Graph

Build the computation graph by tracing this kernel.

Parameters:

NameTypeDescription
parameterslist[str] | NoneList of argument names to keep as unbound parameters. - None (default): Auto-detect parameters (non-Qubit args without value/default) - []: No parameters (all non-Qubit args must have value/default) - [“name”]: Explicit parameter list Only float, int, UInt, and their arrays are allowed as parameters.
**kwargsAnyConcrete values for non-parameter arguments.

Returns:

Graph — The traced computation graph ready for transpilation.

Raises:

Example:

@qm.qkernel
def circuit(q: Qubit, theta: float) -> Qubit:
    q = qm.rx(q, theta)
    return q

# Auto-detect theta as parameter
graph = circuit.build()

# Explicit parameter list
graph = circuit.build(parameters=["theta"])

# theta bound to concrete value
graph = circuit.build(theta=0.5)

# Transpile with binding
transpiler = QiskitTranspiler()
result = transpiler.emit(graph, binding={"theta": 0.5})
draw
def draw(
    self,
    inline: bool = False,
    fold_loops: bool = True,
    expand_composite: bool = False,
    inline_depth: int | None = None,
    **kwargs: Any = {},
) -> Any

Visualize the circuit using Matplotlib.

This method builds the computation graph and creates a static visualization. Parameters are auto-detected: non-Qubit arguments without concrete values are shown as symbolic parameters.

Parameters:

NameTypeDescription
inlineboolIf True, expand CallBlockOperation contents (inlining). If False (default), show CallBlockOperation as boxes.
fold_loopsboolIf True (default), display ForOperation as blocks instead of unrolling. If False, expand loops and show all iterations.
expand_compositeboolIf True, expand CompositeGateOperation (QFT, IQFT, etc.). If False (default), show as boxes. Independent of inline.
inline_depthint | NoneMaximum nesting depth for inline expansion. None means unlimited (default). 0 means no inlining, 1 means top-level only, etc. Only affects CallBlock/ControlledU, not CompositeGate.
**kwargsAnyConcrete values for arguments. Arguments not provided here (and without defaults) will be shown as symbolic parameters.

Returns:

Any — matplotlib.figure.Figure object.

Raises:

Example:

import qamomile.circuit as qm

@qm.qkernel
def inner(q: qm.Qubit) -> qm.Qubit:
    return qm.x(q)

@qm.qkernel
def circuit(q: qm.Qubit, theta: float) -> qm.Qubit:
    q = inner(q)
    q = qm.h(q)
    q = qm.rx(q, theta)
    return q

# Draw with auto-detected symbolic parameter (theta)
fig = circuit.draw()

# Draw with bound parameter
fig = circuit.draw(theta=0.5)

# Draw with blocks as boxes (default)
fig = circuit.draw()

# Draw with blocks expanded (inlined)
fig = circuit.draw(inline=True)

# Draw with loops folded (shown as blocks)
fig = circuit.draw(fold_loops=True)

# Draw with composite gates expanded
fig = circuit.draw(expand_composite=True)
estimate_resources
def estimate_resources(self, *, bindings: dict[str, Any] | None = None) -> ResourceEstimate

Estimate all resources for this kernel’s circuit.

Convenience method that delegates to the module-level estimate_resources function, eliminating the need to access .block directly.

Parameters:

NameTypeDescription
bindingsdict[str, Any] | NoneOptional concrete parameter bindings (scalars and dicts). Dict values trigger |key| cardinality substitution.

Returns:

ResourceEstimate — ResourceEstimate with qubits, gates, and parameters.

Example:

>>> @qm.qkernel
... def bell() -> qm.Vector[qm.Qubit]:
...     q = qm.qubit_array(2)
...     q[0] = qm.h(q[0])
...     q[0], q[1] = qm.cx(q[0], q[1])
...     return q
>>> est = bell.estimate_resources()
>>> print(est.qubits)  # 2

Submodules