quchip.viz.results¶
Simulation-result plots: populations, snapshots, expectations, Wigner.
These helpers consume a SimulationResult
(which is backend-agnostic) and emit Matplotlib figures. None of them
depend on a specific solver backend: partial-trace, expect, and ket
construction all go through Backend.
References
Nielsen & Chuang, Quantum Computation and Quantum Information, Cambridge University Press (2010) — density matrices, populations.
Wigner, “On the Quantum Correction for Thermodynamic Equilibrium”, Phys. Rev. 40, 749 (1932) — original Wigner-function definition.
Cahill & Glauber, “Density Operators and Quasiprobability Distributions”, Phys. Rev. 177, 1882 (1969) — Laguerre-polynomial expansion used by
_wigner_from_density_matrix().Leonhardt, Essential Quantum Optics, Cambridge University Press (2010) — modern continuous-variable treatment of the Wigner function.
Functions
|
Plot dict-form expectation values over time. |
|
Plot basis-state populations over time. |
|
Plot a single stored state at time-index index. |
|
Plot the Wigner quasi-probability distribution of a stored state. |
- quchip.viz.results.plot_populations(result, *, trace_out=None, computational=False, ax=None, linewidth=2.5, legend=True, colors=None, threshold=0.01)[source]¶
Plot basis-state populations over time.
The figure has time (ns) on the x-axis and population
p_n(t) = Tr(|n><n| rho(t))on the y-axis, one line per represented-basis ket|n> = |n_1 n_2 ...>of the retained subsystems. States whose peak population stays below threshold are hidden; set threshold to0to show every state.- Parameters:
result (SimulationResult) – Output of
quchip.engine.simulate().trace_out (device, label, or list thereof, optional) – Subsystems to partial-trace over before computing populations. Accepts either device objects or their string labels (UX favourability). Requires
options={"store_states": True}on the solver call.computational (bool) – When
True, restricts computational subsystems to their{|0>, |1>}subspace.ax (matplotlib.axes.Axes, optional) – Existing axes to draw onto. When
Nonea new figure is created.linewidth (float) – Line width for every population trace.
legend (bool) – Whether to draw a legend of the visible states.
colors (dict, optional) – Per-state colour overrides, keyed by the same basis-state tuples used internally; unlisted states fall back to a
tab20cycle.threshold (float) – Populations whose time-max falls below this value are omitted.
- Returns:
The figure holding the population-trace axes (
ax.figurewhen ax was given).- Return type:
Figure
- Raises:
RuntimeError – trace_out is given but no states were stored (pass
options={"store_states": True}to the solver).ValueError – trace_out would remove every subsystem.
- quchip.viz.results.plot_state(result, index, *, trace_out=None, computational=False, mode='population', ax=None, cmap='RdBu_r', color=None)[source]¶
Plot a single stored state at time-index index.
Two modes are supported:
"population"— a bar chart of diagonal elementsp_n."dm"— side-by-side heatmaps ofRe(rho)andIm(rho); the colormap cmap is divergent, and both heatmaps share one symmetric normalization (vmin=-m, vmax=+mform = max(|Re(rho)|, |Im(rho)|)) so their colours are directly comparable — an entry that looks equally saturated in both panels really is equal in magnitude.
When both computational and non-computational subsystems are present, pass trace_out to focus on a target register and/or computational
= Trueto restrict to the{|0>, |1>}subspace on computational devices (see Nielsen & Chuang, Ch. 2).- Parameters:
result (SimulationResult) – Output of
quchip.engine.simulate(), withoptions={"store_states": True}.index (int) – Stored-time index to plot. Supports Python-style negative indexing (
-1is the last stored time); must satisfy-N <= index < NforN = len(result.times).trace_out (device, label, or list thereof, optional) – Subsystems to partial-trace over before plotting.
computational (bool) – When
True, restricts computational subsystems to their{|0>, |1>}subspace.mode ({"population", "dm"}) – Which representation to draw.
ax (matplotlib.axes.Axes, optional) – For
mode="population": a single axes (orNonefor a new figure). Formode="dm": an iterable of exactly two axes(real_ax, imag_ax)(orNonefor a new 1x2 figure).cmap (str) – Divergent colormap for
mode="dm"heatmaps.color (str, optional) – Bar colour override for
mode="population". Defaults to a per-statetab10cycle.
- Returns:
The figure holding the plotted axes (
ax.figurewhen ax was given).- Return type:
Figure
- Raises:
IndexError – index is outside
[-N, N)forN = len(result.times).ValueError – mode is not
"population"or"dm", or trace_out would remove every subsystem.RuntimeError – No states were stored (pass
options={"store_states": True}to the solver).
- quchip.viz.results.plot_expectation(result, *, keys=None, ax=None, linewidth=2.5, legend=True, real=True)[source]¶
Plot dict-form expectation values over time.
The x-axis is time (ns); the y-axis is
observable_traces[key].values— the post-processed recorded trace for each observableOregistered in the solver’se_opsdict. This is not unconditionallyTr(O rho(t)): depending on how the observable was requested,.valuesmay already include demodulation, phase correction, or band summation (seeObservableTrace; its.rawfield holds the pre-processing quantity instead). When real isTrue(the default) onlyReof the trace is drawn; whenFalseboth the real part (solid) and imaginary part (dashed, lower alpha) are drawn in the same colour per key.- Parameters:
result (SimulationResult) – Output of
quchip.engine.simulate(), withe_opspassed as a dict.keys (list, optional) – Each entry is either a bare key (
"cav") or a(key, index)tuple selecting one element of a list-valued observable, matched against the registeredobservable_traceskeys first — see_collect_expectation_traces(). String and device/drive keys are resolved withresolve_labelso both are accepted interchangeably. Defaults to every registered trace.ax (matplotlib.axes.Axes, optional) – Existing axes to draw onto. When
Nonea new figure is created.linewidth (float) – Line width for every trace.
legend (bool) – Whether to draw a legend of the plotted keys.
real (bool) – When
True, draw only the real part of each trace; whenFalse, draw both the real (solid) and imaginary (dashed) parts.
- Returns:
The figure holding the expectation-trace axes (
ax.figurewhen ax was given).- Return type:
Figure
- Raises:
- quchip.viz.results.plot_wigner(result, index=-1, *, trace_out=None, xvec=None, yvec=None, ax=None, cmap='RdBu_r', colorbar=True)[source]¶
Plot the Wigner quasi-probability distribution of a stored state.
Axes are the phase-space quadratures
x(position-like) andp(momentum-like); the colourmap is divergent and symmetric about zero so negative regions — the hallmark of non-classical states — stand out directly.When xvec is not supplied the plot window is auto-sized from the mean photon number
<n> = Tr(rho n_hat)of the reduced state (computed directly fromdiag(rho)to avoid an O(d^2) matmul for a diagonal-only observable), extending to at least+/-3.Exactly one subsystem must remain after trace_out — a Wigner function is a single-mode phase-space picture, and its basis indices are interpreted directly as photon numbers
n = 0, 1, 2, .... This is checked; what is not, and cannot be, checked from result metadata alone is the remaining precondition: the retained subsystem’s represented basis must actually be a photon-number ladder (true for a bosonic mode such asResonator, false for a device whose represented basis is not Fock, e.g. a charge- or flux-basis qubit) — passing such a device silently produces a Wigner-shaped plot with no such physical meaning.- Parameters:
result (SimulationResult) – Output of
quchip.engine.simulate(), withoptions={"store_states": True}.index (int) – Stored-time index to plot. Supports Python-style negative indexing (
-1, the default, is the last stored time); must satisfy-N <= index < NforN = len(result.times).trace_out (device, label, or list thereof, optional) – Subsystems to partial-trace over before plotting. Required whenever more than one subsystem is stored — see Raises.
xvec (ndarray, optional) – Phase-space grids for the
x/pquadratures. Defaults to an auto-sized, evenly spaced grid (see above); yvec defaults to xvec when only xvec is given.yvec (ndarray, optional) – Phase-space grids for the
x/pquadratures. Defaults to an auto-sized, evenly spaced grid (see above); yvec defaults to xvec when only xvec is given.ax (matplotlib.axes.Axes, optional) – Existing axes to draw onto. When
Nonea new figure is created.cmap (str) – Divergent colormap, symmetric about zero.
colorbar (bool) – Whether to attach a colorbar.
- Returns:
The figure holding the Wigner-function axes (
ax.figurewhen ax was given).- Return type:
Figure
- Raises:
IndexError – index is outside
[-N, N)forN = len(result.times).ValueError – More or fewer than one subsystem remains after trace_out; the message lists the retained device labels and a trace_out value that isolates a single one of them.
RuntimeError – No states were stored (pass
options={"store_states": True}to the solver).
References
Wigner, Phys. Rev. 40, 749 (1932).
Cahill & Glauber, Phys. Rev. 177, 1882 (1969).
Leonhardt, Essential Quantum Optics (2010), Ch. 3.