Skip to content

Choose a tag to compare

@positr0nium positr0nium released this 22 Jun 21:56
· 635 commits to main since this release

Qrisp 0.9

A redesigned backend interface anchors Qrisp 0.9, alongside the Quantum Singular Value Transform (QSVT) at the heart of a new suite of BlockEncoding transformations, including the new FOQCS-LCU (Fast One-Qubit-Controlled Select Linear Combination of Unitaries) block encoding method and Dalzell's optimal Quantum Linear System Solver. Complementing these core advancements are a full circuit optimization pass manager, and new state preparation primitives. Richer QuantumArray arithmetic and meaningful upgrades to arithmetic subroutines, including a new Gidney adder based on venting carries via mid-circuit measurements,
round things out.

QSVT and Singular Value Transformations

With Qrisp 0.9, the Quantum Singular Value Transform (QSVT) framework (PR #607) is now available as the primary tool for matrix inversion and singular value processing to operators that aren't necessarily Hermitian. The BlockEncoding class gains the following new methods:

  • svt (PR #607): Applies a polynomial to the singular values of a block-encoded operator, supporting both even and odd parity polynomials in either the Chebyshev or Polynomial basis.
  • pseudo_inv (PR #607): Using Quantum Singular Value Transform, this function returns a block encoding that approximates the threshold pseudoinverse by ignoring singular values below a specific limit to regularize ill-conditioned linear systems.
  • inv now uses QSVT by default (PR #607), succeeding the previous QET approach which was limited to Hermitian operators. A method keyword lets you switch between QSVT, GQSVT, or QET (Quantum Eigenvalue Transform) as needed.
  • dagger (PR #607): Returns the adjoint of a block-encoded operator.

The BlockEncoding class gains the following new constructors:

  • from_eye (PR #479): Constructs a BlockEncoding of a 2-D array with ones on a specified diagonal and zeros elsewhere. A positive diagonal_index selects an upper subdiagonal, a negative value a lower subdiagonal, and 0 (the default) the main diagonal.

  • from_projector (PR #479): Constructs a BlockEncoding of the projector $|\phi\rangle\langle\psi|$, or, when kernel=True, of the kernel projector $\mathbb{I} - |\phi\rangle\langle\phi|$. Both left and right states may be specified as integers (computational basis states) or as arbitrary state-preparation callables.

  • from_foqcs_lcu_operator (PR #597): Constructs a BlockEncoding from a QubitOperator using the Fast One-Qubit-Controlled Select LCU (FOQCS-LCU) algorithm. The operator is analyzed automatically and the appropriate PREP subroutine — Heisenberg or spin-glass — is selected. Supported operators include arbitrary one-body fields and same-axis two-body couplings of the form $P_i P_j$ with $P \in {X, Y, Z}$.

  • from_foqcs_lcu_prep: (PR #597): Experimental FOQCS-LCU constructor for users who supply their own right and left PREP subroutines ($P_R$ and $P_L$), enabling custom FOQCS-LCU block encodings beyond the built-in Heisenberg and spin-glass models.

  • from_lcu (PR #647): now supports general complex coefficients (previously, only real non-negative coefficients were supported).

  • QSVT and GQSVT (introduced in PR #607 and PR #479) perform (Generalized) Quantum Singular Value Transform for fixed parity real or complex polynomials, respectively.

Two further standalone functions round out the qrisp.gqsp module (PR #479): dalzell_inversion, Qrisp's implementation of the Dalzell Quantum Linear System Solver via QSVT-based kernel reflection, and pseudo_inversion (PR #479): for QSVT-based threshold pseudoinversion (also reachable as BlockEncoding.pseudo_inv).

Backend Interface Redesign

The backend interface has been redesigned from the ground up for a cleaner, more modular abstraction (#331 and its follow-ups). The new Backend class provides a consistent interface for both simulators and hardware backends, abstracting away the differences and allowing users to switch between them seamlessly.

  • Improved error handling: The backend interface now includes more robust error handling and clearer error messages, making it easier to diagnose and fix issues when running circuits.
  • New abstract Backend class: The new base abstraction for all backends, offering run_async(circuits, shots) for an immediate Job (Future-style) alongside a synchronous run(circuits, shots) wrapper for convenience, plus batched() to obtain a BatchedBackend and retrieve_job(job_id) to look up a previously submitted job.
  • BackendLike protocol: A structural typing protocol that both Backend and BatchedBackend satisfy, so type hints stay flexible.
  • Job class: Tracks the lifecycle of a single execution with submit(), result(), cancel(), and status().
  • BatchedBackend reworked: Does not inherit from Backend. Circuits queued via run() are executed once dispatch() is called. batched_measurement is deprecated in favor of get_measurement() with a BatchedBackend directly.
  • Backend migrations: DefaultBackend is now QrispSimulatorBackend. QiskitBackend, QiskitRuntimeBackend, AQTBackend, and IQMBackend have all been brought up to the new API. VirtualBackend is kept as a deprecated drop-in subclass.
  • A leaner core: The old BackendClient/BackendServer (qunicorn) network infrastructure and the Docker-based backends have been removed entirely.

Circuit Optimization Pass Manager

Qrisp 0.9 ships a complete circuit optimization pass management system (#564). PassManager keeps an ordered list of CircuitPass instances, runs them via .run(qc), and verifies correctness with .verify(qc). Built-in passes handle canceling adjacent gate-inverse pairs, fusing consecutive single-qubit gates, commuting and resolving SWAP networks, removing barriers, reverse-parallelization, manual qubit layout, gate basis conversion (to CX/CZ/PRY), decomposition, Gray-synth Toffoli synthesis, canceling zero-controlled gates, arranging SWAPs for smarter routing, and visualizing optimization culprits.

Additional Updates

BlockEncoding refactored (#628): Rebuilt around a Base Class + Facade pattern. The old monolith is now split across block_encoding_base.py (abstract base), block_encoding.py (facade), constructors/, and transformations/, making extensions easier.

COLD improvements (#614): The DCQOProblem class gets a smoother scheduling function, automatic g/g_deriv computation, a precision parameter for expectation-value accuracy, and exp_value_backend for hardware-based optimization.

Dicke state and unbalanced W state (#572): New dicke_state and unbalanced_w_state deterministic state preparation routines, based on the algorithm in arXiv:1904.07358.

QuantumArray upgrades (#519): In-place arithmetic (iadd, isub, imul), element-wise logical operations (and, or, xor), and reductions via all() / any().

Gidney carry-venting adder (#537): New gidney_cq_venting_adder implements the classical-quantum in-place adder from arXiv:2507.23079. Instead of propagating carries through the full register, each carry is measured in the X-basis ("vented") as soon as it is no longer needed. A split-half design uses the target register itself as dirty workspace, keeping the total qubit overhead to just 3 clean ancillae. The adder requires dynamic (JASP) mode and supports c_in, c_out, and zero-overhead control via the custom_control decorator.

Arithmetic enhancements: Gidney adder refactored (#473) with c_in/c_out support; Cuccaro adder gains matching c_in/c_out interface (#615); BigInteger Montgomery arithmetic fixes and rebuilt QuantumModulus constructor (#495).

Typing module (#543): New qrisp.typing module with QubitLike, ClbitLike, FloatLike, ScalarLike, NDArrayLike, and ArrayLike.

Other improvements: QuantumCircuit class refactored (#461, #486, #489, #526); Polished reflection (#627), amplitude_amplification (#588), QAE (#589), and grovers_alg (#587) functions; MLIR / xDSL dialect (#465); StableHLO lowering (#577); composite gate interpreter (#593); BoundQubitTerm/BoundQubitOperator removed (#559); QubitOperator._to_pauli_dict() and zero-multiplication fix (#612); MaxCut module refactored (#542); benchmarking callback threshold (#505); depth metric negative slicing (#451); controlled-U3 compilation fixes (#551); Catalyst 0.15 compatibility (#568).

Compatibility

  • Backend API breaking change: Backend is now the base abstraction for all backends. VirtualBackend still works, but only as a deprecated drop-in subclass. DefaultBackend is now QrispSimulatorBackend. batched_measurement is deprecated in favor of BatchedBackend.dispatch().
  • BoundQubitTerm and BoundQubitOperator removed; use QubitTerm / QubitOperator instead.
  • The old qunicorn-based BackendClient/BackendServer network infrastructure and the Docker-based backends have been removed.
  • New convert_to_cirq and convert_from_cirq functions for bidirectional Qrisp-Cirq conversion (#610).
  • jrange step argument removed (#652): Passing three arguments to jrange now raises a TypeError. Use a step-1 loop and multiply the loop variable by the desired step.

First Time Contributors 🎉