Models
Bases: Module
Abstract physical model.
Subclasses are immutable equinox modules (JAX pytrees), so they can be jitted, vmapped and differentiated through.
Parameter contract (used by :class:~qenvs.wrappers.randomization.ParameterRandomization):
a model declares its randomisable Hamiltonian parameters in :meth:parameter_specs
and implements :meth:with_parameters (a pure function, safe inside jit and
vmap). The default with_parameters replaces the fields of the same name, so a
model whose parameters are fields only has to declare them. Dissipation rates and
structural sizes are never declared: naming one raises an error with the reason
(non_parameters maps such field names to the reason).
dim
abstractmethod
property
Hilbert-space dimension.
is_open
property
Whether the model has dissipation.
n_controls
property
Number of control channels.
battery_hamiltonian()
Energy-storage Hamiltonian H_B (ground energy 0); battery models override.
battery_reduced(qstate)
Reduced battery state and the battery Hamiltonian acting on it.
Energy and ergotropy of a battery are properties of the battery
subsystem alone. Models with ancillas (a charger cavity, a bath mode)
override this to partial-trace them out and return H_B on the
battery space. The default returns the full state and
:meth:battery_hamiltonian.
check_parameters(**values)
Validate concrete parameter values before and after applying them.
Before: every name is declared, every value is a finite real number inside the
support of its :class:ParameterSpec. After: the drift Hamiltonian of
with_parameters(**values) is Hermitian (relative tolerance
HERMITIAN_CHECK_RTOL). Raises ValueError naming the offending parameter.
Needs concrete values (call it outside jit).
controls()
abstractmethod
Control operators H_k; the total Hamiltonian is H_0 + sum_k u_k(t) H_k.
correlation_observables()
Hermitian second-order observables of the "correlations" observation mode.
Default: none. Models define the second moments that matter for their task (the Dicke models give the six symmetrised second moments of the collective spin).
drift()
abstractmethod
Drift (uncontrolled) Hamiltonian H_0.
evolve(state, hamiltonian, duration, *, method=None)
Evolve state under hamiltonian for duration and return the final state.
Uses the Schrodinger equation for closed models and the Lindblad master equation otherwise. Density matrices are always accepted.
The ODE method (adaptive Tsit5 by default) takes as many internal
integration steps as needed inside duration: the agent's control
period and the integrator's time step are independent. For piecewise
constant Hamiltonians dynamiqs.method.Expm() is exact.
hamiltonian(amplitudes)
Constant total Hamiltonian for fixed control amplitudes of shape (n_controls,).
initial_state()
abstractmethod
Initial state (ket for closed systems, density matrix otherwise).
jump_ops()
Lindblad jump operators. Empty list means closed (unitary) dynamics.
observables()
Named Hermitian observables reported by environments (may be empty).
parameter_specs()
Randomisable Hamiltonian parameters: name to :class:ParameterSpec (default: none).
parameter_values()
Current (nominal) value of every declared parameter, in the unit of its spec.
pwc_hamiltonian(times, amplitudes)
Piecewise-constant Hamiltonian.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
times
|
Array
|
interval boundaries, shape |
required |
amplitudes
|
Array
|
control amplitudes, shape |
required |
with_parameters(**values)
Return a copy of the model with the named parameters replaced (pure, jit and vmap safe).
Only declared parameters (:meth:parameter_specs) may be named; anything else
(a dissipation rate, levels, a typo) raises ValueError with the reason. The
values are not range-checked here (they may be tracers); use
:meth:check_parameters for concrete values. The default implementation swaps the
fields of the same name with equinox.tree_at.
Declaration of one randomisable Hamiltonian parameter of a model.
Attributes:
| Name | Type | Description |
|---|---|---|
unit |
str
|
unit of the parameter value, for example |
support |
tuple[float, float]
|
closed interval |
w_ref |
float
|
model reference width in the unit of the parameter: a typical device
to device or calibration to calibration spread. It is used only to
normalise the oracle observation |
contains(value)
Whether value lies in the closed support interval.
Bases: Model
Driven qubit with optional T1/T_phi dissipation.
Attributes:
| Name | Type | Description |
|---|---|---|
omega0 |
float
|
qubit (battery) frequency, sets the energy unit of |
detuning |
float
|
drive-qubit detuning |
gamma1 |
float
|
relaxation rate (0 = none). |
gamma_phi |
float
|
pure dephasing rate (0 = none). |
initial |
str
|
|
battery_hamiltonian()
H_B = omega0 |1><1| (ground energy set to zero).
parameter_specs()
detuning: (-inf, inf), reference width 0.05.
The detuning has no sign constraint. The reference width 0.05 is about 3% of the
Rabi rate pi / T = 1.57 of the default pi pulse (T = 2): a visible but
small error (about 1 - F = 1e-3), the scale of a calibration drift relative to
the drive strength. Units are those of the model (omega0 = 1).
Bases: Model
Driven qubit battery with a thermal bath and pure dephasing.
Attributes:
| Name | Type | Description |
|---|---|---|
omega0 |
float
|
qubit (battery) frequency, sets the energy unit of |
detuning |
float
|
drive-qubit detuning |
gamma1 |
float
|
bath coupling rate; the emission rate is |
n_th |
float
|
Bose occupation of the bath at the qubit frequency (0 = zero temperature). |
gamma_phi |
float
|
pure dephasing rate (0 = none). |
initial |
str
|
|
thermal_population
property
Excited-state population n_th / (2 n_th + 1) of the Gibbs state at the bath.
battery_hamiltonian()
H_B = omega0 |1><1| (ground energy set to zero).
parameter_specs()
detuning: (-inf, inf), reference width 0.05 (see :class:TwoLevel).
Bases: Model
N two-level cells collectively coupled to one cavity mode (Dicke / Tavis-Cummings).
Attributes:
| Name | Type | Description |
|---|---|---|
n_cells |
int
|
number of cells |
n_photons |
int | None
|
initial cavity Fock number; |
n_max |
int | None
|
Fock cutoff. |
omega0 |
float
|
cell transition frequency, energy unit of |
omega_c |
float
|
cavity frequency (detuning |
rwa |
bool
|
|
kappa |
float
|
cavity photon loss rate (jump |
gamma |
float
|
collective emission rate (jump |
gamma_phi |
float
|
collective dephasing rate (jump |
cutoff
property
Fock cutoff n_max with its default resolved.
dim_battery
property
Dimension of the symmetric spin subspace, N + 1.
dim_cavity
property
Dimension of the truncated Fock space, n_max + 1.
j
property
Collective spin j = N/2.
photons
property
Initial cavity photon number (n_photons with its default resolved).
a()
Cavity annihilation operator 1 (x) a.
adag()
Cavity creation operator 1 (x) a^dag.
battery_hamiltonian()
H_B = omega0 (Jz + N/2) on the full space (0 all ground, N omega0 charged).
battery_reduced(qstate)
Reduced cell state tr_cavity(rho) and H_B on the Dicke space.
Energy and ergotropy are properties of the cells, so the cavity (subsystem 1)
is traced out first. Evaluating the ergotropy on the full cells+cavity state
with H_B (x) 1 would give ergotropy == energy for every pure global
state (closed dynamics); on the reduced state it is strictly smaller whenever
the cells are entangled with the cavity.
correlation_observables()
Second moments of the collective spin on the full (cells x cavity) space.
Jx2, Jy2, Jz2, JxJy, JyJz and JzJx, where the mixed ones
are symmetrised, JxJy = (Jx Jy + Jy Jx)/2, so all six are Hermitian (checked).
excitation_number()
Total excitation number a^dag a + Jz + N/2 (conserved by Tavis-Cummings).
initial_state()
All cells in the ground state, cavity in Fock state |n_photons>.
jminus()
Collective lowering operator J- (x) 1.
jplus()
Collective raising operator J+ (x) 1.
jz()
Collective inversion Jz (x) 1 with eigenvalues -N/2, ..., N/2.
local_battery_hamiltonian()
H_B = omega0 (Jz + N/2) on the (N + 1)-dimensional Dicke space alone.
number()
Photon number a^dag a.
parameter_specs()
omega_c in [0, inf), reference width 0.05.
Units are those of the model (omega0 = omega_c = 1 by default). A frequency is
non-negative. 0.05 is a 5% spread, the order of the frequency mismatch between an
emitter ensemble and its cavity. omega0 is not declared in this release (it is
also the energy unit of H_B; see non_parameters). It is a modest
perturbation of the charging protocol: with the constant coupling g = 0.25
over the default episode (20 steps of 0.2, N = 3) the stored energy
<H_B> changes from 2.582 to 2.568 for omega_c = 0.95 or 1.05
(0.5%) and to 2.527 for omega_c = 1.1; a pulse tuned for the nominal
detuning loses more.
top_fock()
Projector 1 (x) |n_max><n_max| on the highest kept Fock level.
Its expectation value is the population at the Fock cutoff; a value that is
not negligible means the truncation is affecting the dynamics (raise n_max).
Bases: Model
N cells collectively coupled to a cavity, with local and collective dissipation.
Attributes:
| Name | Type | Description |
|---|---|---|
n_cells |
int
|
number of cells |
n_photons |
int | None
|
initial cavity Fock number; |
n_max |
int | None
|
Fock cutoff. |
omega0 |
float
|
cell transition frequency, energy unit of |
omega_c |
float
|
cavity frequency. |
rwa |
bool
|
|
kappa |
float
|
cavity loss rate (jump |
gamma |
float
|
collective emission rate (jump |
gamma_phi |
float
|
collective dephasing rate (jump |
gamma_local |
float
|
per-cell emission rate (jump |
gamma_phi_local |
float
|
per-cell dephasing rate (jump |
pumping_local |
float
|
per-cell incoherent pumping rate (jump |
cutoff
property
Fock cutoff n_max with its default resolved.
n_photons for rwa=True (exact only without local pumping, which requires an
explicit n_max) and n_photons + 4 for rwa=False (no convergence guarantee).
dim
property
Dimension 2^N (n_max + 1) of the stored (Schur-basis) density matrix.
dim_cavity
property
Dimension of the truncated Fock space, n_max + 1.
dim_cells
property
Dimension of the full cell space, 2^N.
is_open
property
Always True: the state is a density matrix even with every rate at zero.
j
property
Largest collective spin N/2 (the symmetric sector).
layout
property
Static index maps of the permutation-invariant representation.
liouvillian_dim
property
Number of independent entries sum_j ((2j + 1)(n_max + 1))^2.
photons
property
Initial cavity photon number (n_photons with its default resolved).
sectors
property
(j, d_j) of every sector in storage order (j = N/2 first).
a()
Cavity annihilation operator 1 (x) a.
adag()
Cavity creation operator 1 (x) a^dag.
battery_hamiltonian()
H_B = omega0 (Jz + N/2) on the full stored space.
battery_reduced(qstate)
Full 2^N-dimensional cell state (cavity traced out) and H_B on it.
Both are written in the Schur basis; energy and ergotropy are basis independent,
so they equal those of the cell state in the computational basis. The eigenvalues
of the reduced state are those of every block sigma_j divided by d_j, each
repeated d_j times (see :meth:ergotropy_from_blocks).
correlation_observables()
Second moments of the collective spin on the full 2^N (n_max + 1) stored space.
Jx2, Jy2, Jz2, JxJy, JyJz and JzJx (the mixed ones
symmetrised, all Hermitian, checked), built from the collective operators in the
Schur basis, so each is block diagonal with identical copies per sector.
dicke_density(qstate)
Cell state in the Dicke basis: block-diagonal (n_ds, n_ds), unit trace.
n_ds = sum_j (2j + 1); blocks sigma_j (cavity traced out) for
j = N/2, N/2 - 1, ..., m ascending inside a block. This is the
representation of Shammah et al. (2018) and QuTiP PIQS (which orders m
descending inside a block).
dissipator()
Constant (collective + local) part of the Liouvillian on the compact vector.
The array is cached and shared between models with equal parameters, so it is read-only; copy it before modifying.
ergotropy_from_blocks(qstate)
Ergotropy of the full cell state from the Dicke blocks and their degeneracies.
Eigenvalues of every cell block sigma_j divided by d_j and repeated
d_j times give the 2^N spectrum of the cell state; H_B has level
k omega0 with multiplicity C(N, k). Equals the ergotropy of
:meth:battery_reduced (checked in the validation).
evolve(state, hamiltonian, duration, *, method=None)
Exact step vec sigma -> expm(L(H) duration) vec sigma for a constant H.
method is ignored (the matrix exponential is exact for piecewise-constant
controls); time-dependent Hamiltonians are rejected.
excitation_number()
a^dag a + Jz + N/2 (conserved by closed Tavis-Cummings dynamics only).
from_blocks(vec)
Stored density matrix (d_j copies of sigma_j / d_j) from the compact vector.
initial_state()
All cells ground (j = N/2, m = -N/2), cavity in |n_photons> (density matrix).
jminus()
Collective lowering operator J- (x) 1.
jplus()
Collective raising operator J+ (x) 1 in the stored basis.
jump_ops()
Not available: local jumps act across copies of the multiplicity space.
The dissipation enters :meth:evolve through :meth:liouvillian. Raising
here prevents a generic solver from silently dropping the local processes.
jz()
Collective inversion Jz (x) 1.
liouvillian(hamiltonian)
Full Liouvillian -i [H, .] + D on the compact vector for a collective H.
H is given in the stored basis (e.g. model.hamiltonian(g)); only its sector
blocks are used (a collective Hamiltonian is block diagonal with identical copies).
local_battery_hamiltonian()
H_B on the 2^N cell space (Schur basis).
Level k omega0 has multiplicity C(N, k).
number()
Photon number a^dag a.
parameter_specs()
omega_c in [0, inf), reference width 0.05.
Same declaration and justification as :meth:DickeBattery.parameter_specs
(omega0 is not declared in this release).
symmetric_projector()
Projector on the symmetric sector j = N/2 (the subspace of battery/Dicke-v0).
Its trace is (N + 1) times the cavity dimension n_max + 1.
to_blocks(qstate)
Compact vector of the joint blocks sigma_j = d_j R_j (row-major, sum of traces 1).
top_fock()
Projector on the highest kept Fock level (Fock truncation monitor).
Its expectation value is the convergence diagnostic of the cutoff (info['top_fock'],
the same name as in battery/Dicke-v0): a population that is not negligible means
the truncation affects the dynamics, so raise n_max. It is the only guard when
pumping_local > 0 or rwa=False.
Bases: Model
Lambda system |1> <-> |2> <-> |3> driven by pump and Stokes fields.
Attributes:
| Name | Type | Description |
|---|---|---|
delta_one_photon |
float
|
one-photon (pump) detuning |
delta_two_photon |
float
|
two-photon detuning |
gamma |
float
|
total spontaneous-emission rate of |2> (0 = closed system). The decay branches equally into |1> and |3>; losses to states outside the Lambda manifold are not modelled. |
initial |
str
|
|
controls()
[pump, Stokes]: (|1><2| + h.c.) / 2 and (|3><2| + h.c.) / 2.
drift()
Delta |2><2| + delta |3><3|.
jump_ops()
Spontaneous emission from |2> with equal branching into |1> and |3>.
observables()
Bare-state populations p1, p2, p3.
parameter_specs()
Both detunings: (-inf, inf); reference widths 0.05 and 0.01.
Units are those of the Rabi frequencies (the default bound is 1, T = 20).
Adiabatic transfer tolerates a one-photon detuning of a few percent of the peak
Rabi frequency, but is more sensitive to the two-photon detuning, which tilts the
dark state; its reference width is therefore five times smaller. Measured on the
reference STIRAP pulse of the default task: 1 - F is 3.6e-3 at nominal, 4.2e-3
for delta_one_photon = 0.05, 3.8e-3 for delta_two_photon = 0.01 and 9.7e-3
for delta_two_photon = 0.05.
Bases: Model
Multi-level transmon (Duffing oscillator) with I/Q drive and optional T1/T2.
UNITS: time in ns, angular frequency in rad/ns; the fields below are in GHz (ordinary frequency) and microseconds.
Attributes:
| Name | Type | Description |
|---|---|---|
levels |
int
|
number of transmon levels kept (>= 2; 3 captures leakage to |2>). |
anharmonicity_ghz |
float
|
|
detuning_ghz |
float
|
|
t1_us |
float | None
|
energy relaxation time T1 in microseconds ( |
t2_us |
float | None
|
coherence time T2 in microseconds, |
initial |
str
|
initial level as a string, |
alpha
property
Anharmonicity in rad/ns.
delta
property
Detuning f_q - f_d in rad/ns.
gamma1
property
Relaxation rate 1/T1 in 1/ns (0 if t1_us is None).
gamma_phi
property
Pure dephasing rate 1/T_phi = 1/T2 - 1/(2 T1) in 1/ns (0 if t2_us is None).
from_properties(props, *, levels=3, detuning_ghz=0.0)
classmethod
Build a transmon from device properties (explicit units or SI values).
props is a mapping with anharmonicity_ghz, t1_us, t2_us and
frequency_ghz, or with the SI values (seconds and hertz, each either a bare
number or a (value, timestamp) tuple) that Qiskit's
BackendProperties.qubit_property(q) returned: 'T1', 'T2',
'frequency', 'anharmonicity'. Qiskit is not imported. The rotating-frame
model does not use the qubit frequency (give the drive offset as detuning_ghz);
read it with :func:qenvs.pulses.parse_properties if you want it as pulse metadata.
A missing anharmonicity keeps the model default and emits a UserWarning; missing
t1_us / t2_us mean no dissipation from that source. T2 > 2 T1 raises
ValueError. See :func:qenvs.pulses.parse_properties for the accepted keys.
number()
Number operator n = a^dag a.
parameter_specs()
detuning_ghz on the whole line and anharmonicity_ghz in (-inf, 0] (GHz).
Reference widths: 2 MHz for the detuning (frequency drift and two-level-system
shifts of a fixed-frequency transmon between calibrations are of order 0.1 to a few
MHz, against the 50 MHz Rabi bound of the gate tasks) and 5 MHz for the
anharmonicity (about 1.5% of -340 MHz, the device-to-device spread of a
fabricated junction). A transmon anharmonicity is negative, so a Gaussian offset
needs a TruncatedNormal. At this width the anharmonicity barely changes the
error of the reference X-gate pulse, so a robustness
result under anharmonicity_ghz alone at w_ref is close to a null test; widen
it deliberately if that axis is the point.
Bases: Model
Control and target transmon with exchange coupling, both driven at the target frequency.
UNITS: time in ns, angular frequency in rad/ns; the fields below are in GHz (ordinary frequency) and microseconds. Tensor order control (x) target.
Attributes:
| Name | Type | Description |
|---|---|---|
levels |
int
|
levels kept per transmon (>= 2; 3 captures leakage to |2>). |
detuning_ghz |
float
|
|
anharmonicity_c_ghz |
float
|
control anharmonicity |
anharmonicity_t_ghz |
float
|
target anharmonicity |
coupling_ghz |
float
|
exchange coupling |
t1_c_us, |
t2_c_us
|
control T1 / T2 in microseconds ( |
t1_t_us, |
t2_t_us
|
target T1 / T2 in microseconds. |
initial |
str
|
initial computational state |
alpha_c
property
Control anharmonicity in rad/ns.
alpha_t
property
Target anharmonicity in rad/ns.
computational_indices
property
Indices of |00>, |01>, |10>, |11> (control digit first) in the d^2 basis.
coupling
property
Exchange coupling J in rad/ns.
delta
property
Detuning 2 pi (f_c - f_t) in rad/ns.
dressed_energies()
Drift eigenvalues assigned to |00>, |01>, |10>, |11> by maximal overlap (rad/ns).
Energies are in the common frame; E11 - E10 - E01 + E00 is frame independent.
frame_unitary(duration)
exp(+i Delta n_c T): common frame to bare qubit frames after T = duration ns.
numbers()
Number operators (n_c, n_t).
ops()
Dense ladder operators (a, b) of control and target on the d^2 space.
parameter_specs()
Both anharmonicities and the coupling, in GHz.
Supports: anharmonicities (-inf, 0], coupling [0, inf) (a negative exchange
sign is a different device, not a variation of this one). Reference widths: 5 MHz
for each anharmonicity and 0.3 MHz for the coupling (10% of the nominal 3 MHz, the
usual fabrication spread of a capacitive coupling). The detuning is not declared in
this release; see non_parameters for the reason.
static_zz()
Static ZZ rate zeta = E11 - E10 - E01 + E00 of the dressed states (rad/ns).
Exact diagonalisation of the undriven Hamiltonian; with H_ZZ = (zeta / 4) Z (x) Z
this is the shift of the |11> energy relative to the uncoupled sum.
Bases: Model
Model defined by user supplied matrices: H(t) = H_0 + sum_k u_k(t) H_k plus Lindblad ops.
Build it with HamiltonianModel(...) or the equivalent
:meth:from_operators; both validate their inputs (see the module docstring).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
drift
|
object
|
drift Hamiltonian |
required |
controls
|
object
|
control operators |
required |
jump_ops
|
object
|
Lindblad jump operators |
()
|
initial_state
|
object | None
|
normalised ket ( |
None
|
observables
|
Mapping[str, object] | None
|
mapping name to Hermitian operator, reported in |
None
|
battery_hamiltonian
|
object | None
|
Hermitian |
None
|
battery_subsystems
|
tuple[int, ...] | None
|
optional increasing tuple of retained tensor-factor indices. Supply with subsystem_hamiltonian instead of battery_hamiltonian. |
None
|
subsystem_hamiltonian
|
object | None
|
Hermitian Hamiltonian on the retained factors, ground energy zero. Energy agrees with its full-space embedding; ergotropy is computed after partial trace. |
None
|
dims
|
Sequence[int] | None
|
subsystem dimensions of a composite system, e.g. |
None
|
parameters
|
Mapping[str, Sequence[object]] | None
|
named real drift parameters, mapping name to
|
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
on any violated construction guarantee, naming the operator. |
Attributes:
| Name | Type | Description |
|---|---|---|
drift_matrix |
Array
|
stored |
control_matrices |
Array
|
stored controls, shape |
jump_matrices |
Array
|
stored jump operators, shape |
initial_matrix |
Array
|
stored initial state, ket |
observable_matrices |
dict[str, Array]
|
stored observables by name. |
battery_matrix |
Array | None
|
stored |
dims |
tuple[int, ...]
|
composite subsystem dimensions (static). |
parameter_nominals |
dict[str, Array]
|
current values |
parameter_matrices |
dict[str, Array]
|
operators |
parameter_spec_items |
tuple[tuple[str, ParameterSpec], ...]
|
|
is_open
property
True when the model carries jump operators or a mixed (density-matrix) state.
battery_reduced(qstate)
Return the declared battery subsystem, or preserve the legacy full-state path.
drift()
H_0, plus sum_k p_k O_k over the parameter terms (names in sorted order).
evolve(state, hamiltonian, duration, *, method=None)
Evolve as :meth:Model.evolve, keeping the composite dims on the result.
dynamiqs 0.3.6 drops the subsystem dims of a density matrix integrated with
Expm ((2, 2) becomes (4,)), which breaks ptrace and the lax.scan
carry of an environment rollout; they are restored here.
from_operators(drift, controls, jump_ops=(), initial_state=None, observables=None, battery_hamiltonian=None, dims=None, parameters=None, *, battery_subsystems=None, subsystem_hamiltonian=None)
classmethod
Build and validate a model from operators; see the class docstring for the arguments.
parameter_specs()
The parameter terms declared with parameters= (empty if there are none).
parameter_values()
Current values p_k of the parameter terms.
with_parameters(**values)
Copy with the named parameter terms set to values (pure, jit and vmap safe).
Pulses
Pulse I/O and device parameters for hardware toolchains.
A :class:Pulse is an immutable record of a piecewise-constant pulse as QEnvS produces
it (the actions of a rollout): the samples, the sample period, the channel names, the
units and the provenance. It serialises losslessly to JSON and NPZ, converts transmon
amplitudes between rad/ns and MHz, refines a pulse exactly onto a finer sample grid
(for example 2/9 ns) and pads it with zeros to the granularity of an arbitrary waveform
generator.
UNITS: dt_ns is the sample period in nanoseconds for the transmon tasks (units
'rad/ns', amplitudes are angular frequencies Omega, the Rabi frequency is
Omega / (2 pi)). For the tasks in units of the transition frequency (units
'dimensionless') the field keeps the name dt_ns but holds the dimensionless
period in units of 1 / omega0; the MHz helpers refuse such pulses.
:func:parse_properties reads device parameters (frequency, anharmonicity, T1, T2) from a
plain mapping with explicit units or with the SI values that Qiskit's
BackendProperties.qubit_property returned; it is the engine behind
:meth:qenvs.models.transmon.Transmon.from_properties. Nothing here imports Qiskit.
QEnvS does not model an AWG transfer function, does not calibrate amplitudes and does not
talk to hardware; see docs/guides/pulses.md.
DeviceProperties
dataclass
Device parameters in the units of :class:~qenvs.models.transmon.Transmon.
None means "not given". frequency_ghz is not used by the rotating-frame model
(only the detuning from the drive matters); keep it as pulse metadata.
Pulse
Immutable piecewise-constant pulse.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
samples
|
Any
|
amplitudes, shape |
required |
dt_ns
|
float
|
sample period (ns for |
required |
channels
|
Sequence[str] | None
|
one unique name per column; default |
None
|
units
|
str
|
|
UNITS_RAD_PER_NS
|
metadata
|
Mapping[str, Any] | None
|
JSON-compatible mapping (task id, task kwargs, qenvs version, fidelity, ...); deep-copied, so later changes of the argument do not leak in. |
None
|
Attributes:
| Name | Type | Description |
|---|---|---|
samples |
ndarray
|
read-only |
metadata |
dict[str, Any]
|
a fresh deep copy on every access (the record itself cannot change). |
channels
property
Channel names, one per column.
dt_ns
property
Sample period (ns for 'rad/ns' pulses).
duration_ns
property
Total duration n_samples * dt_ns.
metadata
property
Provenance and optional numbers; a fresh deep copy on every access.
n_channels
property
Number of channels.
n_samples
property
Number of samples.
samples
property
Read-only (n, channels) float64 array.
units
property
Units of the amplitudes: 'rad/ns' or 'dimensionless'.
area()
Per-channel area sum(samples) * dt_ns, shape (channels,) (rad for rad/ns).
On resonance a constant-phase drive with area theta on channel I rotates a
two-level system by theta about x (pi for an X gate).
from_actions(actions, dt, *, task_id=None, task_kwargs=None, channels=None, units=None, **metadata)
classmethod
Record the actions of a rollout (shape (horizon, action_dim)) as a pulse.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
actions
|
Any
|
numpy or jax array of actions, |
required |
dt
|
float
|
the control period of the environment ( |
required |
task_id
|
str | None
|
registered task id; sets the units from |
None
|
task_kwargs
|
Mapping[str, Any] | None
|
kwargs the task was made with, kept as provenance (must be JSON compatible). |
None
|
channels
|
Sequence[str] | None
|
explicit channel names. |
None
|
units
|
str | None
|
explicit units; defaults to the task's, or |
None
|
**metadata
|
Any
|
extra JSON-compatible provenance, e.g. |
{}
|
The metadata always records the qenvs_version, plus task_id and
task_kwargs when given. Float32 actions are widened to float64 exactly.
from_dict(data)
classmethod
Inverse of :meth:to_dict; rejects unknown schemas and missing fields.
from_json(source)
classmethod
Read a pulse from JSON text, a path to a JSON file or an already parsed mapping.
A str whose first non-blank character is { is JSON text; any other str
and any path-like object is a file name.
from_npz(path)
classmethod
Read an archive written by :meth:to_npz (allow_pickle=False).
from_rabi_mhz(rabi_mhz, dt_ns, *, channels=('I', 'Q'), **kwargs)
classmethod
Build a 'rad/ns' pulse from Rabi frequencies in MHz (shape (n, channels)).
Inverse of :meth:rabi_mhz up to rounding. kwargs go to :meth:from_actions
(task_id, task_kwargs, metadata); units is fixed to 'rad/ns'.
pad(n_samples=None, *, multiple=None)
Append zeros: to a total of n_samples samples, or to the next multiple.
Give exactly one of the two. pad(multiple=16) meets an AWG granularity of 16
samples. The padded pulse records the original length in
metadata['unpadded_n_samples']; :meth:resample scales it, so resample first
and pad second. The zeros are idle time: when a padded pulse is simulated, the drift
(detuning, anharmonicity) and, in an open system, T1/T2 decay act during it, whereas
hardware frame tracking does not.
rabi_mhz()
Rabi frequency in MHz of every sample, samples / (2 pi) * 1e3 ('rad/ns' only).
resample(sample_dt_ns)
Refine the pulse onto a finer grid by sample-and-hold; exact for piecewise-constant.
Every sample is repeated k = dt_ns / sample_dt_ns times and the new period is
dt_ns / k. k must be an integer to within 1e-9 relative; a ratio below 1
(coarsening) or a non-integer ratio raises ValueError, because the held pulse
would no longer be the same function of time. The metadata records the factor in
metadata['resampled']; a task_kwargs entry still describes the original task.
An existing metadata['unpadded_n_samples'] is multiplied by k so that it keeps
counting samples of the new grid; the intended order is resample, then pad.
to_actions()
Writable float64 copy of the samples, shape (n, channels): env.rollout input.
to_dict()
JSON-compatible dictionary with 'schema': 'qenvs.pulse/v1'.
to_json(path=None, *, indent=None)
JSON text, written to path too if given.
The text is ASCII and floats use the shortest round-trip repr, so it is lossless.
to_npz(path, *, compressed=False)
Write a NumPy .npz archive (no pickle); float64 samples are stored bit-exactly.
A str or path is written as given (no .npz is appended behind your back);
a binary file object is also accepted.
mhz_to_rad_per_ns(rabi_mhz)
Angular frequency in rad/ns of a Rabi frequency in MHz: 2 pi * rabi_mhz * 1e-3.
parse_properties(props)
Read device parameters from a mapping, with units in the key names or in SI.
Accepted keys (other keys, such as readout errors, are ignored):
- explicit units:
frequency_ghz,anharmonicity_ghz,t1_us,t2_us; - SI, as returned by Qiskit's
BackendProperties.qubit_property(q), a mapping{'T1': (seconds, timestamp), 'T2': (seconds, timestamp), 'frequency': (Hz, timestamp), 'anharmonicity': (Hz, timestamp)}; every value may also be a bare number.
Qiskit is not imported; anything shaped like this works. Supplying the same quantity in
both forms, a key such as t1_ms (a unit-suffixed name this function does not
know), T2 > 2 T1, or a non-positive T1 or T2 raises an error instead of guessing.
rad_per_ns_to_mhz(omega)
Rabi frequency in MHz of an angular frequency omega in rad/ns: omega / (2 pi) * 1e3.
A constant Omega = pi / 20 rad/ns for 20 ns is a pi pulse and gives 25 MHz.
Gate fidelity tools
Gate targets and gate-quality measures for (possibly leaky) unitaries and channels.
Conventions:
- Basis index 0 is the ground state, index 1 the excited state; a
k-level target acts on the firstklevels (the computational subspace) of ad-level system. Every fidelity and leakage function also acceptssubspace: a sequence ofkbasis indices that span the computational subspace, in the order of the target's basis (for two qutrits in control (x) target order,(0, 1, 3, 4)). The defaultNonemeans the firstklevels. -
Average gate fidelity is averaged over Haar-random pure inputs inside the computational subspace and compares with the ideal output (Wood and Gambetta, Phys. Rev. A 97, 032306 (2018), Eqs. (5)-(6))::
F = [k (1 - L) + k^2 F_pro] / (k (k + 1)) = (k F_pro + 1 - L) / (k + 1)
with leakage rate L = Tr[(1 - P) E(P / k)] and process fidelity
F_pro = (1/k^2) sum_ij <i| U_t^dag E(|i><j|) U_t |j>. For a unitary U this
reduces to the closed form of Pedersen, Moller and Molmer, Phys. Lett. A 367, 47
(2007): F = [Tr(M M^dag) + |Tr M|^2] / (k (k + 1)) with M = P_k U_t^dag U P_k.
Global phases are irrelevant; relative phases (including Z errors) count.
* Superoperators use dynamiqs' column-stacking vectorisation, vec(rho)[i + d j] =
rho[i, j] (checked against dq.vectorize and mesolve), so
vec(U rho U^dag) = (conj(U) kron U) vec(rho).
All functions accept JAX arrays or dynamiqs QArray objects and broadcast over
leading batch dimensions.
apply_superop(s, rho)
Apply a column-stacking superoperator s (d^2 x d^2) to rho (d x d).
average_gate_fidelity(u, target, *, subspace=None)
Average gate fidelity of a d-level unitary u against a k-level target.
F = [Tr(M M^dag) + |Tr M|^2] / (k (k + 1)), M = target^dag P u P
(Pedersen et al. 2007), with P the projector on the first k levels or on the
basis states listed in subspace (in the target's basis order). Population leaked
out of the subspace lowers Tr(M M^dag) and |Tr M|. Equal to 1 iff u acts
as target on the subspace up to a global phase. Batched over leading dimensions
of u.
gate(name)
Named single-qubit target as a (2, 2) complex array (see :data:TARGETS).
leakage(u, k=2, *, subspace=None)
Leakage rate of a unitary out of the first k levels (or out of subspace).
L = 1 - (1/k) sum_{i,j<k} |u_ji|^2, evaluated as the equivalent (for unitary
u) sum of leaked populations (1/k) sum_{i<k, j>=k} |u_ji|^2, which avoids
cancellation when L is tiny and stays non-negative. When subspace is given,
k = len(subspace) and the sums run over those indices and their complement.
rz(theta)
Rz(theta) = diag(exp(-i theta/2), exp(i theta/2)).
superop_average_gate_fidelity(s, target, *, subspace=None)
Average gate fidelity of a (leaky) channel s against a k-level target.
F = (k F_pro + 1 - L') / (k + 1) with 1 - L' = Tr[P E(P / k)] (Wood and
Gambetta 2018, Eq. (6)), computed as an exact Haar average over pure inputs in the
computational subspace (first k levels, or subspace). Equals
:func:average_gate_fidelity for a unitary channel.
superop_leakage(s, k=2, *, subspace=None)
Leakage rate L = Tr[(1 - P) E(P / k)] of a channel (Wood and Gambetta 2018, Eq. (2)).
Equals 1 - Tr[P E(P / k)] for a trace-preserving map and reduces to
:func:leakage for a unitary channel. P projects on the first k levels or,
when given, on subspace (then k = len(subspace)).
superop_process_fidelity(s, target, *, subspace=None)
Process fidelity on the subspace (1/k^2) sum_ij <i|U_t^dag E(|i><j|) U_t|j>.
unitary_to_superop(u)
Column-stacking superoperator of rho -> u rho u^dag: conj(u) kron u.
Thermodynamic and information observables shared by models and environments.
energy(state, hamiltonian)
Mean energy tr(rho H) (real).
ergotropy(state, hamiltonian)
Maximum work extractable by a unitary (Allahverdyan et al., 2004).
E = tr(rho H) - min_U tr(U rho U^dag H), where the minimum is attained by the
passive state: eigenvalues of rho in decreasing order paired with eigenvalues
of H in increasing order.
fidelity(state, target)
State fidelity in [0, 1].
For a pure target (ket) this is <t|rho|t>, which equals the Uhlmann
fidelity and, unlike the general square-root formula, has a finite gradient
when state is a density matrix (the general formula differentiates
sqrt of a rank-1 matrix and returns NaN). Mixed targets fall back to
dynamiqs.fidelity.