Qamomile v0.14.0 adds LCU block encodings for Pauli, Ising-Z, and periodic-shift operators, together with qmc.qsvt for quantum singular value transformation (QSVT). It also adds quantum arithmetic circuits such as constant addition and rewrites Shor order finding as an iterative algorithm that uses fewer logical qubits. The new qmc.ekera_hastad_factoring API constructs the quantum part of Ekerå–Håstad factoring.
pip install qamomile==0.14.0Breaking Changes¶
Several functions have moved to different import paths.
shor_order_findingmoved fromqamomile.circuit.stdlibtoqamomile.circuit.algorithm.modular_incrementandmodular_decrementmoved in the opposite direction, fromqamomile.circuit.algorithmand itsarithmeticsubpackage toqamomile.circuit.stdlib. The top-levelqmc.shor_order_finding,qmc.modular_increment, andqmc.modular_decrementimports remain available (#608, #613).The qkernel returned by
qmc.shor_order_findingno longer has thenargument for specifying the quantum-register width. The width is calculated automatically frommodulus.bit_length(). Useprecisionto specify the number of phase bits andwindow_sizeto specify how many qubits modular multiplication processes at once. Execution requires a backend that supports mid-circuit measurement, reset, and feed-forward (#613).qmc.modmul_constnow uses an FTQC-oriented implementation with measurement and reset. The width ofregmust be known whenqmc.modmul_constis called, and the newwindow_sizeargument specifies how many input qubits are processed at once during modular multiplication (#613).
New Features¶
LCU block encodings and QSVT¶
qamomile.linalg now provides PauliLCU for general complex square matrices whose dimensions are powers of two, and PeriodicShiftLCU for one- or multidimensional periodic-shift operators. The corresponding block encoding APIs are qmc.pauli_lcu_block_encoding and qmc.periodic_shift_lcu_block_encoding. This release also adds APIs for Ising-Z, identity, and block encodings assembled from existing block encodings. Each API returns an instance containing its normalization, signal-register width, system-register width, and a reusable unitary qkernel.
qmc.qsvt applies a caller-supplied projector-phase sequence to any LCUBlockEncoding. Phase values may be fixed through transpile-time bindings. To retain the phase sequence as a runtime parameter, fix phase_count through bindings and specify parameters=["phases"]. Phase synthesis for a desired polynomial and conversion from other QSP conventions are not provided, so callers must prepare the phases in advance (#598, #608, #611, #618).
import numpy as np
import qamomile.circuit as qmc
from qamomile.linalg import PauliLCU
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)
matrix = np.array([[1.0, 0.0], [0.0, -1.0]], dtype=complex)
block_encoding = qmc.pauli_lcu_block_encoding(PauliLCU.from_matrix(matrix))
transpiler = QiskitTranspiler()
executable = transpiler.transpile(
transform,
bindings={
"encoding": block_encoding,
"phases": [0.0, 0.0],
},
)Arithmetic and lower-width factoring circuits¶
The standard library adds constant addition, controlled constant addition, constant modular addition, and a function that uses a quantum register as an address to look up a table value and XOR it into another quantum register. The existing qmc.shor_order_finding has also been updated to use windowed modular multiplication.
qmc.ekera_hastad_factoring constructs the quantum part of Ekerå–Håstad factoring for a product of two primes with similar bit lengths. It returns measured bits for the classical computation that recovers the factors, rather than returning the factors themselves. The circuit reduces the number of logical qubits used at once by reusing qubits after measurement and reset. Classical post-processing that recovers the factors from the measurements is not included (#613).
import qamomile.circuit as qmc
from qamomile.qiskit import QiskitTranspiler
order_finding = qmc.shor_order_finding(
base=2,
modulus=15,
precision=2,
)
short_dlp = qmc.ekera_hastad_factoring(
generator=2,
modulus=21,
window_size=1,
)
transpiler = QiskitTranspiler()
order_executable = transpiler.transpile(order_finding)
short_dlp_executable = transpiler.transpile(short_dlp)See Tutorial 05 — Resource Estimation.
qmc.struct, fixed-length Bit arrays, and register-width calculations¶
The qmc.struct decorator makes helper-based implementations of large algorithms easier to organize. It cannot be used as a qkernel argument or return value. qmc.bit_array creates a zero-initialized, fixed-length one-dimensional Vector[Bit], allowing measurement results to be stored by index and returned as one value (#613, #623).
The new classical-value operations qmc.log2 and qmc.ceil are evaluated immediately when their inputs are known. When inputs are unresolved, the operations remain symbolic in resource estimates and must be supplied through transpile-time bindings before the circuit is generated (#615).
import qamomile.circuit as qmc
from qamomile.qiskit import QiskitTranspiler
@qmc.struct
class Workspace:
qubits: qmc.Vector[qmc.Qubit]
@qmc.qkernel
def collect_bits(size: qmc.UInt) -> qmc.Vector[qmc.Bit]:
width = qmc.ceil(qmc.log2(size))
workspace = Workspace(qmc.qubit_array(width, "workspace"))
measured = qmc.measure(workspace.qubits)
output = qmc.bit_array(width, name="output")
for index in qmc.range(width):
output[index] = measured[index]
return output
transpiler = QiskitTranspiler()
executable = transpiler.transpile(
collect_bits,
bindings={"size": 9},
)Internal Changes¶
First-class qkernel effects¶
QKernel.effects reports a KernelEffect flag set containing MEASUREMENT, RESET, and FEED_FORWARD; KernelEffect.NONE denotes a unitary body. Effects propagate through nested callable definitions and are reconstructed after serialization (#613).
import qamomile.circuit as qmc
from qamomile.qiskit import QiskitTranspiler
@qmc.qkernel
def reset_and_read() -> tuple[qmc.Bit, qmc.Bit]:
qubit = qmc.x(qmc.qubit("qubit"))
qubit, before = qmc.measure_reset(qubit)
after = qmc.measure(qubit)
return before, after
effects = reset_and_read.effects
transpiler = QiskitTranspiler()
executable = transpiler.transpile(reset_and_read)Explicit region dataflow¶
Structured if, for, and while regions now record their captures, carried values, arguments, and yields explicitly. These interfaces are preserved through Protobuf serialization and checked before lowering (#616).
import qamomile.circuit as qmc
from qamomile.qiskit import QiskitTranspiler
@qmc.qkernel
def fill_register(size: qmc.UInt) -> qmc.Vector[qmc.Bit]:
qubits = qmc.qubit_array(size, "qubits")
for index in qmc.range(size):
qubits[index] = qmc.x(qubits[index])
return qmc.measure(qubits)
transpiler = QiskitTranspiler()
executable = transpiler.transpile(
fill_register,
bindings={"size": 3},
)Bug Fixes¶
Serialization of control, inverse, and SELECT calls has been fixed. Quantum kernels containing
qmc.controlorqmc.inversecan now be transpiled correctly after serialization and deserialization. Invalid inverse calls that treat a qubit array as one control qubit are rejected, and SELECT cases whose classical arguments precede the quantum register are restored with the correct argument order (#605, #606, #608).Switching from a backend-specific implementation to the portable implementation no longer leaves partially generated gates in the circuit. If a backend-specific implementation cannot complete a callable, Qamomile discards the gates it added before generating the portable version (#607).
Documentation¶
Tutorial 05 — Resource Estimation now derives concrete costs for quantum arithmetic circuits, iterative Shor order finding, and Ekerå–Håstad’s quantum stage (#613).
The algorithm index now links correctly to Möttönen Amplitude Encoding and describes its Qamomile APIs more clearly (#620).
Multidimensional QFT for Estimating Nanosheet Material Properties has a clearer title and corrected paper citation (#621).
Pauli Correlation Encoding has clearer section names and cross-references for its MaxCut workflow, along with a clearer description in the algorithm index (#622).