qrisp.gidney_cq_venting_adder#
- gidney_cq_venting_adder(d: int | BigInteger, target: QuantumVariable, c_in: QuantumBool | None = None, c_out: QuantumBool | None = None, ctrl: QuantumVariable | QuantumBool | None = None) None[source]#
In-place classical-quantum adder using Gidney’s carry-venting technique.
Adds a classical integer \(d\) and an optional carry-in \(c_{\text{in}}\) to a quantum register, storing the result back in the same register.
Uses 3 clean ancillae (allocated internally) and no external dirty workspace. The target register is split in half — each half serves as dirty storage for the other half’s carry chain — keeping the total qubit count to
n + 3. For registers with fewer than 6 qubits the split-half path is replaced bygidney_adder()(unitary, no vents), which avoids a nested-q_cond tracing-session issue for n=5. This matches the paper’s strategy of using a clean adder when enough ancillae are available.Heavily adapted from the reference implementation released with arXiv:2507.23079 at https://zenodo.org/records/15866587.
Warning
This function requires dynamic (JASP) mode and does not work in static circuit generation, because it relies on mid-circuit measurements (venting) whose outcomes determine subsequent operations.
- Parameters:
- targetQuantumVariable
Target register, little-endian (index 0 = LSB). Modified in place.
- dint or BigInteger
Classical addend (compile-time constant).
- c_inQuantumBool | None
Quantum carry-in. None is treated as \(\ket{0}\).
- Returns:
- None
- Raises:
- TypeError
If
dis aQuantumVariableor list (must be a classical integer).- TypeError
If
targetis not aQuantumVariable.- RuntimeError
If called outside dynamic (JASP) tracing mode.
Examples
Basic addition in dynamic (JASP) mode:
from qrisp import QuantumFloat, measure, gidney_cq_venting_adder from qrisp.jasp import jaspify @jaspify def main(): target = QuantumFloat(5) target[:] = 2 gidney_cq_venting_adder(7, target) return measure(target) result = main() # result is 9 (2 + 7 = 9)
Addition with a carry-in qubit:
@jaspify def main(): target = QuantumFloat(4) target[:] = 5 c_in = QuantumFloat(1) c_in[:] = 1 gidney_cq_venting_adder(2, target, c_in=c_in[0]) return measure(target) result = main() # result is 8 (5 + 2 + carry_in = 8)
Controlled addition (zero extra Toffoli cost):
from qrisp import control, QuantumBool @jaspify def main(): target = QuantumFloat(5) target[:] = 10 ctrl = QuantumBool() ctrl[:] = 1 with control(ctrl): gidney_cq_venting_adder(5, target) return measure(target) result = main() # result is 15 (10 + 5 = 15) # when ctrl is not provided, target stays unchanged