Overview¶
| Function | Description |
|---|---|
hamiltonian_to_quri_operator | Convert qamomile.observable.Hamiltonian to QURI Parts Operator. |
to_quri_operator | Convert Hamiltonian to QURI Parts Operator. |
| Class | Description |
|---|---|
QamomileQuriPartsTranspileError | Exception raised for errors in the Qamomile to QURI Parts conversion process. |
QuriPartsEmitPass | QURI Parts-specific emission pass. |
QuriPartsExecutor | QURI Parts quantum executor. |
QuriPartsGateEmitter | GateEmitter implementation for QURI Parts. |
QuriPartsTranspiler | QURI Parts transpiler for qamomile.circuit module. |
Functions¶
hamiltonian_to_quri_operator [source]¶
def hamiltonian_to_quri_operator(hamiltonian: qm_o.Hamiltonian) -> 'Operator'Convert qamomile.observable.Hamiltonian to QURI Parts Operator.
Parameters:
| Name | Type | Description |
|---|---|---|
hamiltonian | qm_o.Hamiltonian | The qamomile Hamiltonian to convert. |
Returns:
'Operator' — QURI Parts Operator representation.
Example:
import qamomile.observable as qm_o
from qamomile.quri_parts.observable import hamiltonian_to_quri_operator
H = qm_o.Z(0) * qm_o.Z(1) + 0.5 * (qm_o.X(0) + qm_o.X(1))
operator = hamiltonian_to_quri_operator(H)to_quri_operator [source]¶
def to_quri_operator(hamiltonian: qm_o.Hamiltonian) -> 'Operator'Convert Hamiltonian to QURI Parts Operator.
Convenience alias for :func:hamiltonian_to_quri_operator.
Parameters:
| Name | Type | Description |
|---|---|---|
hamiltonian | qm_o.Hamiltonian | The qamomile Hamiltonian to convert. |
Returns:
'Operator' — QURI Parts Operator representation.
Classes¶
QamomileQuriPartsTranspileError [source]¶
class QamomileQuriPartsTranspileError(QamomileCompileError)Exception raised for errors in the Qamomile to QURI Parts conversion process.
QuriPartsEmitPass [source]¶
class QuriPartsEmitPass(StandardEmitPass['qp_c.LinearMappedUnboundParametricQuantumCircuit'])QURI Parts-specific emission pass.
Uses StandardEmitPass with QuriPartsGateEmitter for gate emission. QURI Parts does not support native control flow, so all loops are unrolled.
Constructor¶
def __init__(
self,
bindings: dict[str, Any] | None = None,
parameters: list[str] | None = None,
)Initialize the QURI Parts emit pass.
Parameters:
| Name | Type | Description |
|---|---|---|
bindings | dict[str, Any] | None | Parameter bindings for the circuit |
parameters | list[str] | None | List of parameter names to preserve as backend parameters |
QuriPartsExecutor [source]¶
class QuriPartsExecutor(QuantumExecutor['qp_c.LinearMappedUnboundParametricQuantumCircuit'])QURI Parts quantum executor.
Supports both sampling and expectation value estimation. Uses Qulacs backend by default for efficient simulation.
Example:
executor = QuriPartsExecutor() # Uses Qulacs by default
counts = executor.execute(circuit, shots=1000)
# counts: {"00": 512, "11": 512}Constructor¶
def __init__(self, sampler: Any = None, estimator: Any = None, seed: int | None = None)Initialize executor with optional sampler, estimator, and seed.
Parameters:
| Name | Type | Description |
|---|---|---|
sampler | Any | QURI Parts sampler. Defaults to None, meaning a qulacs vector sampler is created lazily on first use. |
estimator | Any | QURI Parts parametric estimator. Defaults to None, meaning a qulacs parametric estimator is created lazily on first use. |
seed | int | None | Optional random seed forwarded to the qulacs vector sampler so that sampling is reproducible. When set, two execute calls with the same seed and circuit return identical shot counts, which unblocks reproducible tutorials and benchmarks. Defaults to None, meaning sampling is non-deterministic. The seed is only applied to the default qulacs sampler; it is ignored when a custom sampler is supplied, since an arbitrary sampler has no standard seed interface. |
Attributes¶
non_parametric_estimator: Any Lazy initialization of non-parametric estimator.parametric_estimator: Any Lazy initialization of parametric estimator for optimization.sampler: Any Lazy initialization of sampler.
Methods¶
bind_parameters¶
def bind_parameters(
self,
circuit: 'qp_c.LinearMappedUnboundParametricQuantumCircuit',
bindings: dict[str, Any],
parameter_metadata: ParameterMetadata,
) -> 'ImmutableBoundParametricQuantumCircuit'Bind parameter values to the QURI Parts circuit.
QURI Parts requires parameter values as a sequence in the order parameters were added to the circuit.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | 'qp_c.LinearMappedUnboundParametricQuantumCircuit' | The unbound parametric circuit |
bindings | dict[str, Any] | Dictionary of parameter name to value |
parameter_metadata | ParameterMetadata | Metadata about the parameters |
Returns:
'ImmutableBoundParametricQuantumCircuit' — Bound parametric circuit
Raises:
QamomileQuriPartsTranspileError— If a required parameter binding is missing frombindings.
estimate¶
def estimate(
self,
circuit: 'qp_c.LinearMappedUnboundParametricQuantumCircuit',
hamiltonian: 'qm_o.Hamiltonian',
params: Sequence[float] | None = None,
) -> floatEstimate expectation value <psi|H|psi>.
Also accepts a native quri_parts.core.operator.Operator at
runtime for convenience (auto-conversion is skipped in that case).
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | 'qp_c.LinearMappedUnboundParametricQuantumCircuit' | The unbound parametric circuit (state preparation ansatz) |
hamiltonian | 'qm_o.Hamiltonian' | Hamiltonian to measure (qamomile Hamiltonian or native QURI Parts Operator at runtime) |
params | Sequence[float] | None | Parameter values for the parametric circuit |
Returns:
float — Real part of the expectation value
estimate_expectation¶
def estimate_expectation(
self,
circuit: 'qp_c.LinearMappedUnboundParametricQuantumCircuit',
hamiltonian: 'qp_o.Operator',
param_values: Sequence[float],
) -> floatEstimate expectation value of hamiltonian for a circuit.
Handles both unbound parametric circuits (used during optimization)
and already-bound or non-parametric circuits. When the circuit has
already been bound (e.g., by _run_expval in ExecutableProgram),
apply_circuit produces a GeneralCircuitQuantumState instead
of a ParametricCircuitQuantumState, so we dispatch to the
non-parametric estimator automatically.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | 'qp_c.LinearMappedUnboundParametricQuantumCircuit' | The quantum circuit (unbound parametric or bound/concrete) |
hamiltonian | 'qp_o.Operator' | QURI Parts Operator representing the Hamiltonian |
param_values | Sequence[float] | Sequence of parameter values in order (ignored for bound/non-parametric circuits) |
Returns:
float — Real part of the expectation value
execute¶
def execute(self, circuit: Any, shots: int) -> dict[str, int]Execute circuit and return bitstring counts.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | Any | The quantum circuit to execute (bound or unbound) |
shots | int | Number of measurement shots |
Returns:
dict[str, int] — Dictionary mapping bitstrings to counts (e.g., {“00”: 512, “11”: 512})
QuriPartsGateEmitter [source]¶
class QuriPartsGateEmitterGateEmitter implementation for QURI Parts.
Emits individual quantum gates to QURI Parts circuits.
QURI Parts parametric circuits accept angles in dictionary form: {parameter: coefficient, CONST: constant_offset}
Constructor¶
def __init__(self) -> NoneInitialize the emitter.
Attributes¶
measurement_mode: MeasurementMode QURI Parts always uses STATIC measurement (sampler handles it).
Methods¶
append_gate¶
def append_gate(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
gate: Any,
qubits: list[int],
) -> NoneAppend a gate to the circuit.
Since circuit_to_gate returns None, this is only called with QURI Parts native gates which can be extended into the circuit.
circuit_to_gate¶
def circuit_to_gate(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
name: str = 'U',
) -> AnyQURI Parts doesn’t support converting circuits to gates.
Returns None to signal that manual decomposition should be used.
combine_symbolic¶
def combine_symbolic(self, kind: BinOpKind, lhs: Any, rhs: Any) -> 'dict[Parameter, float]'Combine two angle operands as a QURI Parts linear-combination dict.
QURI Parts’ Parameter is Rust-backed and exposes no Python
arithmetic operators (param * float raises TypeError).
The only supported representation for parametric angles is the
linear-combination dict consumed by
LinearMappedUnboundParametricQuantumCircuit.add_Parametric*,
which fundamentally cannot express non-linear combinations
(parameter × parameter, parameter ** n, etc.). This override
produces such a dict for every linear case and raises a clear
QamomileQuriPartsTranspileError for non-linear cases instead
of letting the underlying TypeError bubble up.
Parameters:
| Name | Type | Description |
|---|---|---|
kind | BinOpKind | The BinOpKind from the IR. |
lhs | Any | Left operand (numeric, QURI Parts Parameter, or an existing linear-combination dict). |
rhs | Any | Right operand (same shapes). |
Returns:
'dict[Parameter, float]' — A fresh dict[Parameter, float] representing the linear
'dict[Parameter, float]' — combination of the operands.
Raises:
QamomileQuriPartsTranspileError— When the operation cannot be expressed as a linear combination (e.g.param * param,param / param,param ** n,param // n, division by zero in the symbolic path).
create_circuit¶
def create_circuit(
self,
num_qubits: int,
num_clbits: int,
) -> 'LinearMappedUnboundParametricQuantumCircuit'Create a new QURI Parts parametric circuit.
Note: QURI Parts does not support classical bits in circuits. The num_clbits parameter is accepted for interface compatibility but is not used.
create_parameter¶
def create_parameter(self, name: str) -> 'Parameter'Create a QURI Parts parameter and register it with the circuit.
emit_barrier¶
def emit_barrier(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
qubits: list[int],
) -> NoneNo-op: QURI Parts doesn’t support barrier instructions.
emit_ch¶
def emit_ch(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
control: int,
target: int,
) -> NoneEmit controlled-Hadamard gate using decomposition.
Follows the shared CH_DECOMPOSITION recipe from
qamomile.circuit.transpiler.decompositions.
emit_cp¶
def emit_cp(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
control: int,
target: int,
angle: float | Any,
) -> NoneEmit controlled-Phase gate using decomposition.
Follows the shared CP_DECOMPOSITION recipe from
qamomile.circuit.transpiler.decompositions.
Inlined here because QURI Parts parametric angles use dict representation.
emit_crx¶
def emit_crx(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
control: int,
target: int,
angle: float | Any,
) -> NoneEmit controlled-RX gate using decomposition.
CRX(ctrl, tgt, θ) = RZ(tgt, π/2) CNOT(ctrl, tgt) RY(tgt, -θ/2) CNOT(ctrl, tgt) RY(tgt, θ/2) RZ(tgt, -π/2)
emit_cry¶
def emit_cry(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
control: int,
target: int,
angle: float | Any,
) -> NoneEmit controlled-RY gate using decomposition.
Follows the shared CRY_DECOMPOSITION recipe from
qamomile.circuit.transpiler.decompositions.
Inlined here because QURI Parts parametric angles use dict representation.
emit_crz¶
def emit_crz(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
control: int,
target: int,
angle: float | Any,
) -> NoneEmit controlled-RZ gate using decomposition.
Follows the shared CRZ_DECOMPOSITION recipe from
qamomile.circuit.transpiler.decompositions.
Inlined here because QURI Parts parametric angles use dict representation.
emit_cx¶
def emit_cx(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
control: int,
target: int,
) -> NoneEmit CNOT (controlled-X) gate.
emit_cy¶
def emit_cy(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
control: int,
target: int,
) -> NoneEmit controlled-Y gate using decomposition.
Follows the shared CY_DECOMPOSITION recipe from
qamomile.circuit.transpiler.decompositions.
emit_cz¶
def emit_cz(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
control: int,
target: int,
) -> NoneEmit controlled-Z gate.
emit_h¶
def emit_h(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
qubit: int,
) -> NoneEmit Hadamard gate.
emit_measure¶
def emit_measure(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
qubit: int,
clbit: int,
) -> NoneNo-op: QURI Parts circuits don’t support measurement gates.
Measurement is handled separately by samplers/estimators.
emit_p¶
def emit_p(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
qubit: int,
angle: float | Any,
) -> NoneEmit Phase gate using U1.
P(θ) = U1(θ) = diag(1, e^{iθ}). For non-parametric angles we use the native U1 gate which is mathematically identical to the Phase gate. For parametric angles we fall back to ParametricRZ because QURI Parts does not provide a ParametricU1 gate. RZ differs only by a global phase: P(θ) = e^{iθ/2} · RZ(θ), which is physically irrelevant for single-qubit usage. Controlled-phase (CP) has its own decomposition and does not go through this path.
emit_rx¶
def emit_rx(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
qubit: int,
angle: float | Any,
) -> NoneEmit RX rotation gate.
emit_ry¶
def emit_ry(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
qubit: int,
angle: float | Any,
) -> NoneEmit RY rotation gate.
emit_rz¶
def emit_rz(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
qubit: int,
angle: float | Any,
) -> NoneEmit RZ rotation gate.
emit_rzz¶
def emit_rzz(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
qubit1: int,
qubit2: int,
angle: float | Any,
) -> NoneEmit RZZ gate using ParametricPauliRotation.
emit_s¶
def emit_s(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
qubit: int,
) -> NoneEmit S (phase) gate.
emit_sdg¶
def emit_sdg(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
qubit: int,
) -> NoneEmit S-dagger (inverse S) gate.
emit_swap¶
def emit_swap(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
qubit1: int,
qubit2: int,
) -> NoneEmit SWAP gate.
emit_t¶
def emit_t(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
qubit: int,
) -> NoneEmit T gate.
emit_tdg¶
def emit_tdg(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
qubit: int,
) -> NoneEmit T-dagger (inverse T) gate.
emit_toffoli¶
def emit_toffoli(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
control1: int,
control2: int,
target: int,
) -> NoneEmit Toffoli (CCX) gate.
emit_x¶
def emit_x(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
qubit: int,
) -> NoneEmit Pauli-X gate.
emit_y¶
def emit_y(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
qubit: int,
) -> NoneEmit Pauli-Y gate.
emit_z¶
def emit_z(
self,
circuit: 'LinearMappedUnboundParametricQuantumCircuit',
qubit: int,
) -> NoneEmit Pauli-Z gate.
gate_controlled¶
def gate_controlled(self, gate: Any, num_controls: int) -> AnyCreate controlled version of a gate.
Returns None since QURI Parts doesn’t support this natively.
gate_inverse¶
def gate_inverse(self, gate: Any) -> AnyReturn the inverse of a concrete QURI Parts circuit.
Parameters:
| Name | Type | Description |
|---|---|---|
gate | Any | Candidate QURI Parts circuit to invert. Runtime parametric circuits are expected to fall back to Qamomile’s gate-by-gate inverse implementation. |
Returns:
Any — Inverted QURI Parts circuit when inverse_circuit can
handle gate; otherwise None so callers can fall back to
Qamomile-level decomposition.
gate_power¶
def gate_power(self, gate: Any, power: int) -> AnyCreate gate raised to a power.
Returns None since QURI Parts doesn’t support this natively.
supports_for_loop¶
def supports_for_loop(self) -> boolQURI Parts does not support native for loops.
supports_gate_inverse¶
def supports_gate_inverse(self) -> boolReport QURI Parts circuit inverse support.
Returns:
bool — True because gate_inverse can invert concrete
bool — QURI Parts circuits. The backend still reports no reusable
bool — gate support, so inverse blocks normally use the
bool — transpiler-level native path rather than the shared
bool — blockvalue_to_gate path.
supports_if_else¶
def supports_if_else(self) -> boolQURI Parts does not support native if/else.
supports_while_loop¶
def supports_while_loop(self) -> boolQURI Parts does not support native while loops.
QuriPartsTranspiler [source]¶
class QuriPartsTranspiler(Transpiler['qp_c.LinearMappedUnboundParametricQuantumCircuit'])QURI Parts transpiler for qamomile.circuit module.
Converts Qamomile QKernels into QURI Parts quantum circuits.
Example:
from qamomile.quri_parts import QuriPartsTranspiler
import qamomile.circuit as qm
@qm.qkernel
def bell_state(q0: qm.Qubit, q1: qm.Qubit) -> tuple[qm.Bit, qm.Bit]:
q0 = qm.h(q0)
q0, q1 = qm.cx(q0, q1)
return qm.measure(q0), qm.measure(q1)
transpiler = QuriPartsTranspiler()
circuit = transpiler.to_circuit(bell_state)Methods¶
executor¶
def executor(
self,
sampler: Any = None,
estimator: Any = None,
seed: int | None = None,
) -> QuriPartsExecutorCreate a QURI Parts executor.
Parameters:
| Name | Type | Description |
|---|---|---|
sampler | Any | Optional custom sampler. Defaults to None, meaning the qulacs vector sampler is used. |
estimator | Any | Optional custom estimator. Defaults to None, meaning the qulacs parametric estimator is used. |
seed | int | None | Optional random seed forwarded to the qulacs vector sampler for reproducible sampling. Defaults to None, meaning sampling is non-deterministic. The seed is ignored when a custom sampler is supplied, since an arbitrary sampler has no standard seed interface. |
Returns:
QuriPartsExecutor — Executor configured for this backend, bound
to the given seed.