quchip.backend.qutip¶
QuTiP backend implementation of the quchip.backend.protocol contract.
QuTiP stores operators as qutip.Qobj (sparse CSR by default, dense on
request). This backend lowers engine IR into Qobj / QobjEvo form and
dispatches the sesolve/mesolve drivers directly.
The reusable loky process pool parallelizes batched sweeps and
heterogeneous problem lists.
References
Johansson, Nation, Nori — QuTiP 2, Comput. Phys. Commun. 183, 1760 (2012)
Breuer & Petruccione — The Theory of Open Quantum Systems (OUP, 2002)
Classes
Concrete backend that uses QuTiP. |
- class quchip.backend.qutip.QuTiPBackend[source]¶
Bases:
BackendConcrete backend that uses QuTiP.
Operator=State=qutip.Qobj.Example
>>> from quchip.backend.qutip import QuTiPBackend >>> backend = QuTiPBackend() >>> a = backend.destroy(3) >>> float((a.dag() * a).diag()[2].real) 2.0
- property array_module: Any¶
Return the array module used by backend-aware numeric code.
Returns
numpyfor CPU-only backends andjax.numpyfor JAX-traceable backends. Engine code that must stay differentiable (signal evaluation, frame assembly) routes array operations through this module, so the dynamiqs backend stays JAX-traceable end to end.
- to_array(op)[source]¶
Return a dense array (native to
array_module) for op.- Parameters:
op (Operator) – Backend-native operator.
- overlap(a, b)[source]¶
Return the scalar inner product ⟨a|b⟩ for two kets.
- Parameters:
a (State) – Kets in the same Hilbert space, where the first is conjugated.
b (State) – Kets in the same Hilbert space, where the first is conjugated.
- norm(state_or_op)[source]¶
Return the native QuTiP norm.
- Parameters:
state_or_op (qutip.Qobj) – Ket or bra for the Euclidean norm, or matrix for the trace norm.
- Returns:
Qobj.norm()with its default norm selection.- Return type:
- trace(op)[source]¶
Return the scalar trace
Tr(op).- Parameters:
op (Operator) – Backend-native operator.
- destroy(n)[source]¶
Build the annihilation operator \(\hat a\) for an n-level Fock space.
- Parameters:
n (int) – Positive Hilbert-space dimension. Number states go from 0 to n - 1.
- create(n)[source]¶
Build the creation operator \(\hat a^\dagger\) for an n-level Fock space.
- Parameters:
n (int) – Positive Hilbert-space dimension. Number states go from 0 to n - 1.
- number(n)[source]¶
Build the number operator \(\hat n = \hat a^\dagger \hat a\).
- Parameters:
n (int) – Positive Hilbert-space dimension. Number states go from 0 to n - 1.
- identity(n)[source]¶
Build the identity operator for an n-level space.
- Parameters:
n (int) – Positive Hilbert-space dimension. Number states go from 0 to n - 1.
- from_array(data, dims=None)[source]¶
Construct a native operator from a dense matrix.
dims accepts quchip’s row/col layout (
[[row_dims], [col_dims]]) or a flat list.Nonemeans a single subsystem of sizedata.shape[0].- Parameters:
data (array_like) – Dense matrix in the requested tensor-product basis.
dims (list or None, default None) – Subsystem dimensions, flat or [[row_dims], [column_dims]]. None treats the row space as one subsystem.
- compact_operator(rows, columns, values, size)[source]¶
Construct an operator on
sizecompact excitation states from its entries.Repeated entries add. Each backend chooses the storage. The default stores a dense matrix, which keeps traced values traced, and raises
MemoryErrorbefore it allocates one that cannot fit.
- compact_operators_fit(size, count)[source]¶
Return whether
countcompact operators onsizestates fit in the available memory.The default stores each as a dense matrix, as
compact_operator()does.
- linear_combination(terms)[source]¶
Return
Σᵢ cᵢ·Aᵢ, adding the terms in order.A backend can accumulate concrete terms in its native layout, whereas this default uses operator arithmetic. A coefficient of exactly
1adds its operator unscaled.- Parameters:
terms (sequence of (scalar, Operator)) – At least one coefficient and operator pair on a common space.
- to_canonical_operator(op)[source]¶
Serialize a native operator into the backend-agnostic canonical IR.
- Parameters:
op (Operator) – Backend-native operator.
- from_canonical_operator(canonical)[source]¶
Reconstruct a native operator from the canonical IR payload.
- Parameters:
canonical (CanonicalOperator) – Backend-neutral matrix payload with its tensor dimensions and basis metadata.
- coerce_operator(op)[source]¶
Coerce an array-like local operator into backend-native form.
Mirrors
coerce_state()for operators. Device-side accessors for physical coupling (for example,charge_coupling_operator()) return dense, trace-safe arrays, not backend-native operators. Composition entry points (tensor(),dag()) send their operands through this hook, so both forms compose freely. A backend whose native operators are already arrays overrides this method with a trace-safe passthrough.- Parameters:
op (Operator) – Backend-native operator.
- dag(op)[source]¶
Return the Hermitian conjugate
op†.- Parameters:
op (Operator) – Backend-native operator.
- eigenenergies(op)[source]¶
Return the ascending eigenvalues of a Hermitian operator.
- Parameters:
op (Operator) – Hermitian operator to diagonalize.
- eigensystem_data(op)[source]¶
Return ascending eigenvalues, stacked eigenvector matrix, and lazy eigenstates.
- Parameters:
op (Operator) – Hermitian operator to diagonalize.
- expect(op, state)[source]¶
Return the expectation value ⟨state|op|state⟩ for a ket or a density matrix.
- Parameters:
op (Operator) – Observable with the same tensor dimensions as state.
state (State) – Ket or density matrix, not normalized by the method.
- expect_over_time(op, stacked_states)[source]¶
Return ⟨op⟩(t) for every save point, as one
(T,)array inarray_module.Accepts a ket stack
(T, n, 1)(returns ⟨ψ|op|ψ⟩) or a density-matrix stack(T, n, n)(returnsTr(op·ρ)). One matrix product replaces the per-pointexpectloop. Every intermediate stays inarray_module, so the JAX backend keeps the trace differentiable.- Parameters:
op (Operator) – Observable in the tensor-product basis of the states.
stacked_states (array_like) – Backend-stacked kets or density matrices from stack_states.
- ptrace(state, keep, dims)[source]¶
Reduce a composite state onto subsystem(s) keep with a partial trace.
- permute_state(state, dims, order)[source]¶
Reorder the subsystems of a composite state.
dimsare the subsystem levels in state’s current tensor order.orderfollows thenumpy.transposeconvention, whereorder[i]is the subsystem index in the current order that becomes positioniafter the permutation, soorder == list(range(len(dims)))is a no-op.Default, correct for all backends: densify, reshape to one axis per subsystem,
transpose, and reshape back. A ket reshapes/transposes once. A density matrix applies the same subsystem permutation to the row index group and to the column index group. Concrete backends can override this method with a native reorder (e.g. QuTiP’sQobj.permute), which stays sparse-friendly and keeps the dims metadata.Every array operation goes through
array_module(never barenumpy), so a traced state stays traced end to end under the dynamiqs backend.
- tensor(*operators)[source]¶
Return the tensor product of operators, and keep the subsystem dims metadata.
- Parameters:
*operators (Operator) – Factors in tensor-product order.
- embed_two_body(op_ab, index_a, index_b, dims)[source]¶
Embed a two-body operator on devices index_a ⊗ index_b into the full space.
Handles the subsystem SWAP when
index_a > index_band the identity-padding for non-adjacent devices. Backends with sparse layouts do not materialize the dense full matrix.- Parameters:
- tensor_states(*states)[source]¶
Return the tensor product of states (defaults to
tensor()).- Parameters:
*states (State) – Factors in tensor-product order.
- coherent(n, alpha)[source]¶
Build the coherent state \(|\alpha\rangle\) truncated to n Fock levels.
Built from the analytic series \(|\alpha\rangle = e^{-|\alpha|^2/2} \sum_k \alpha^k/\sqrt{\Gamma(k+1)}\,|k\rangle\).
- state_to_dm(state)[source]¶
Return a density matrix, or pass state through if state is already one.
- Parameters:
state (State) – Ket or density matrix to inspect or convert.
- is_ket(state)[source]¶
Return whether state is a ket (flat or column vector) rather than a density matrix.
- Parameters:
state (State) – Ket or density matrix to inspect or convert.
- is_native_state(state)[source]¶
Return whether state is already represented by this backend.
- Parameters:
state (State) – Ket or density matrix to inspect or convert.
- resolve_solver_options(options, *, metadata, tlist)[source]¶
Resolve QuTiP integration options without changing the input mapping.
- Parameters:
options (dict) – Native QuTiP settings, e.g.
method,atol,rtol,nsteps(step ceiling), andmax_step(ns). Unspecified step controls use engine hints, and explicit settings take priority. For method-specific keys, see QuTiP solver options. Select the saved-state storage via the simulation’sstatesargument.metadata (dict) – Lowering hints, including ordinary-GHz spectral/carrier bounds.
tlist (array_like) – Save-time grid in ns, used to estimate integration budgets.
- Returns:
Copied options, with the missing integration defaults filled.
- Return type:
- coerce_state(state, dims=None)[source]¶
Convert a foreign-native state into this backend’s native form.
The solve boundary calls this method so that a per-call
backend=override (seeQuantumSequence.simulate()) accepts initial states built under another backend. For example, a QuTiPQobjfromchip.state(...)given to a dynamiqs gradient solve. Default: pass through unchanged.dimsare the chip’s subsystem levels, for backends whose state type carries tensor structure.
- solve_problem(problem)[source]¶
Lower and solve a
SolveProblem(the single-element entry point).Delegates to
SolveProblem.solver_name(). It usessesolveonly for a ket with no collapse operators andmesolveotherwise, unlessproblem.solverforces a choice.- Parameters:
problem (SolveProblem) – Complete captured Hamiltonian, initial state, time grid, observables and solver settings.
- Returns:
Native solver payload for the requested calculation.
- Return type:
- trajectory_view(native, problem, *, index, states, deterministic)[source]¶
Read one view of a native stochastic result of this backend.
- Parameters:
native (object) – Native stochastic result that
solve_problem()returned.problem (SolveProblem) – Captured request, with its solver, state storage and native options.
index (int or None) – Kept trajectory, or
Nonefor the native ensemble average.states (bool) – Whether to read the saved states.
deterministic (bool) – Whether to read the deterministic no-click run instead.
- Returns:
Expectation values, state history and final state. Each entry is
Nonewhen the native result does not keep it.- Return type:
- trajectory_records(native, problem)[source]¶
Read the diffusive measurement currents of a native stochastic result.
- Parameters:
native (object) – Native stochastic result that
solve_problem()returned.problem (SolveProblem) – Captured request, with its solver and native options.
- Returns:
Currents of shape
(runs, channels, intervals), or(runs, channels, 2, intervals)for heterodyne detection, and the sampling of the signal in each interval:"start","middle","end"or"mean".- Return type:
- trajectory_clicks(native, problem)[source]¶
Read the jump events of a native stochastic result.
- Parameters:
native (object) – Native stochastic result that
solve_problem()returned.problem (SolveProblem) – Captured request, with its solver and native options.
- Returns:
For each run, its click times and the native jump-operator index of each click; the sampling weight of each run; the weight of the no-click run that the native sampling solves apart; and whether each run filled its native click buffer.
- Return type:
- trajectory_run_expect(native, problem)[source]¶
Read the expectation values of every kept run of a native stochastic result.
- Parameters:
native (object) – Native stochastic result that
solve_problem()returned.problem (SolveProblem) – Captured request, with its native expectation operators.
- Returns:
One array of shape
(runs, times)for each native expectation operator.- Return type:
- sesolve(H, psi0, tlist, e_ops=None, options=None)[source]¶
Solve the Schrödinger equation \(i\hbar \partial_t |\psi\rangle = H |\psi\rangle\).
- Parameters:
H (Any) – Native Hamiltonian (
Qobj/QobjEvoor dynamiqsTimeQArray).psi0 (Any) – Initial ket.
tlist (Any) – Save times in ns.
e_ops (list[Any] | None) – Optional observables. The solver accumulates ⟨ψ|Oᵢ|ψ⟩ along the trajectory.
options (dict[str, Any] | None) – Backend-specific options dict. For the supported keys, see each backend’s
resolve_solver_options.
- mesolve(H, rho0, tlist, c_ops=None, e_ops=None, options=None)[source]¶
Solve the Lindblad master equation (Lindblad 1976; Breuer & Petruccione 2002).
Integrates \(\dot\rho = -i[H,\rho] + \sum_k \mathcal D[L_k]\rho\) with \(\mathcal D[L]\rho = L\rho L^\dagger - \tfrac12\{L^\dagger L, \rho\}\).
- Parameters:
H (object) – Native Hamiltonian, already scaled to angular frequency in rad/ns. Do not multiply by 2*pi again.
rho0 (State) – Initial density matrix, or a ket that the concrete solver accepts.
tlist (array_like, shape (nt,)) – Save times in ns, strictly increasing.
c_ops (list of Operator or None, default None) – Collapse operators including square-root rates in 1/sqrt(ns). None gives no dissipators.
e_ops (list of Operator or None, default None) – Observables in output order. None requests no expectation traces.
options (dict or None, default None) – Native integration options. See the concrete backend’s resolve_solver_options method.
- Returns:
Saved states, expectation traces and solver diagnostics.
- Return type:
- steadystate(problem, *, prepared=None, guess=None)[source]¶
Solve a static Lindblad generator with
qutip.steadystate().- Parameters:
problem (SteadyStateProblem) – Captured static model, observables, and stationary solver options.
prepared (PreparedStationary or None, default None) – Matching prepared generator.
Nonebuilds it.guess (Qobj or None, default None) – Stationary state of a related generator. If this generator annihilates the state to round-off, the method returns it without solving and the stats record
guess_reused.
- Returns:
Stationary density matrix and convergence diagnostics.
- Return type:
Notes
problem.optionsaccepts native QuTiP stationary-solver keywords, e.g.method(default"direct") andsolver(default None). quchip consumesrank_tolerance(singular-value cutoff, default automatic) anddiagnostic_max_dimension(default 16). Above that Hilbert dimension, the nullity is not computed, andNonemeans unchecked, not a unique state.
- stationary_bytes(engine_result)[source]¶
Return the estimated bytes of the sparse LU factors of a stationary generator.
The method builds the generator again. The estimate is low, as
sparse_lu_bytes()says.- Parameters:
engine_result (EngineResult) – Captured static Hamiltonian and collapse channels.
- linear_response(problem)[source]¶
Solve one passive-linear input-output problem in the backend’s native arrays.
- Parameters:
problem (LinearResponseProblem) – Captured passive-linear model, selected ports, probe frequencies, and incident amplitudes.
- Returns:
Scattering response, internal amplitudes and numerical diagnostics.
- Return type:
- coherence_response(problem)[source]¶
Solve a frequency response on adjacent excitation-sector coherences.
- Parameters:
problem (CoherenceResponseProblem) – Sector Hamiltonians, channels and frozen-reference probe sources.
- stationary_resolvent(engine_result, sources, observables, frequencies, *, prepared=None)[source]¶
Evaluate trace-zero stationary resolvents in native backend arrays.
For each ordinary-GHz offset
f, form and factor the trace-constrained shifted Liouvillian once, then solve(L + i 2π f) X = sourcewithTr(X) = 0for every named source column. ReturnTr(observable X)keyed by(source, observable). The engine supplies canonical operators. The backend owns Liouvillian construction, factorization, and solves.- Parameters:
engine_result (EngineResult) – Captured static operating point.
sources (tuple of (str, CanonicalOperator)) – Named source columns for the constrained linear systems.
observables (tuple of (str, CanonicalOperator)) – Named operators evaluated against each solution.
frequencies (array_like) – Offset frequencies in ordinary GHz.
prepared (PreparedStationary or None, default None) – Matching prepared generator.
Nonebuilds it.
- Returns:
Arrays keyed by (source_name, observable_name), indexed by frequency.
- Return type:
- stationary_propagate(engine_result, initial, observables, times, *, prepared=None)[source]¶
Propagate an operator under a static Liouvillian and evaluate observables.
initialdoes not have to be a normalized density matrix. This supports quantum-regression queries, and the backend keeps ownership of the propagation algorithm and the numerical Liouvillian.- Parameters:
engine_result (EngineResult) – Captured static operating point.
initial (CanonicalOperator) – Initial operator. Regression queries need neither normalization nor positivity.
observables (tuple of (str, CanonicalOperator)) – Named operators evaluated after propagation.
times (array_like) – Propagation delays in ns.
prepared (PreparedStationary or None, default None) – Matching prepared generator.
Nonebuilds it.
- Returns:
Observable names mapped to arrays indexed by delay.
- Return type:
- parallel_solve_problems(problems, *, progress=True, max_workers=None)[source]¶
Solve large, structurally heterogeneous problem lists through loky workers.
- Parameters:
- Returns:
Backend results in input order, or
Noneto keep the engine’s structural-group dispatch.- Return type:
list[SolverResult] | None
- batched_sesolve(problems, *, n_jobs=-1, progress=True)[source]¶
Solve multiple sesolve problems, sequentially by default.
Backends that can vectorize (dynamiqs
vmap) or parallelize (QuTiP with loky) override this method. Each problem dict carries the same kwargs assesolve().- Parameters:
- Returns:
Results in input order.
- Return type:
list of SolverResult
- batched_mesolve(problems, *, n_jobs=-1, progress=True)[source]¶
Solve multiple mesolve problems, sequentially by default.
- Parameters:
- Returns:
Results in input order.
- Return type:
list of SolverResult
- prepare_hamiltonian(description, tlist=None)[source]¶
Convert a
EngineResultinto aQobjorQobjEvo.Each dynamic coefficient is band-normalized. Every carrier stays analytic, and only its slow, carrier-free envelope is sampled on tlist, locally densified around each window edge. This avoids the cubic-spline error of a pre-sampled full
envelope·carrierproduct, even for resonant carriers in the lab frame.- Parameters:
description (EngineResult) – Captured engine Hamiltonian and channels in solver units.
tlist (array_like) – Requested save times in ns, used by native time-dependent lowering.
- Returns:
Native right-hand side and numerical integration hints.
- Return type:
- prepare_batch(batch)[source]¶
Build a deferred-construction batch whose workers build each element’s
QobjEvo.Only the slow, carrier-free envelope is sampled on the user grid, locally densified around each window edge, and the carriers stay analytic.
- Parameters:
batch (SolveBatch) – Batch of captured problems with compatible save grids.
- Returns:
Eager, native-vectorized, or deferred representation selected by this backend.
- Return type:
- solve_batch(batch, *, progress=True, max_workers=None)[source]¶
Solve a
SolveBatch, with theQobjEvofor each element built in loky workers.- Parameters:
batch (SolveBatch) – Captured problems and batch parameter values.
progress (bool, default True) – Request a batch progress display.
max_workers (int or None, default None) – Worker processes.
Nonetakes the CPU count that loky reports, which honorsLOKY_MAX_CPU_COUNT, or fewer when the available memory cannot hold them.1solves in this process.
- Returns:
Results in batch order.
- Return type:
list of SolverResult