quchip.analysis.cross_resonance

Cross-resonance Hamiltonian tomography analysis.

Fits the target qubit’s Bloch-vector trajectories from a CR pulse-duration sweep. Extracts the six effective Hamiltonian coefficients {IX, IY, IZ, ZX, ZY, ZZ} in GHz (the package’s units contract).

The CR effective Hamiltonian in the two-qubit subspace is:

H_eff = (I ⊗ A + Z ⊗ B) / 2, A, B ∈ span{X, Y, Z}

which expands to six coefficients:

ω_IX, ω_IY, ω_IZ (control-state-independent) ω_ZX, ω_ZY, ω_ZZ (control-state-dependent)

in units of ordinary frequency (GHz).

References

Sheldon, Magesan, Chow, Gambetta, “Procedure for systematically tuning up cross-talk in the cross resonance gate”, PRA 93, 060302(R) (2016).

Unit convention: public durations are in ns and returned coefficients are in GHz. The fit runs internally in Hz/seconds (the conditioning heuristics are tuned for CR-tomography scales, following Sheldon et al.); both conversions happen exactly once at the public boundary. Multiply by 2π to get angular frequency.

Functions

analyze_cr_susceptibility(chip, control, ...)

Return the dressed weak-drive CR response of one directed edge.

analyze_cross_resonance(durations, ctrl0, ctrl1)

Extract CR effective Hamiltonian coefficients from Bloch tomography data.

bloch_model(t, px, py, pz, td, bx, by, bz)

Model the Bloch-vector evolution under a constant drive Hamiltonian with a single decay envelope.

Classes

CRHamiltonianResult(IX, IY, IZ, ZX, ZY, ZZ, ...)

Store CR Hamiltonian coefficients in GHz and local uncertainty estimates.

CRSusceptibilityResult(m_control_0, ...)

Store weak-drive CR coefficients per unit of programmed drive amplitude.

quchip.analysis.cross_resonance.bloch_model(t, px, py, pz, td, bx, by, bz)[source]

Model the Bloch-vector evolution under a constant drive Hamiltonian with a single decay envelope.

The model assumes a drive Hamiltonian

H = π (px X + py Y + pz Z)

so the Bloch vector precesses at frequency \(f = \sqrt{p_x^2 + p_y^2 + p_z^2}\) Hz about the axis \(\hat{n} = (p_x, p_y, p_z)/f\). A single exponential envelope \(\exp(-t / t_d)\) damps all three Bloch components equally, without separate \(T_1\) and \(T_2\) decay processes.

Parameters:
  • t ((N,) ndarray) – Times in seconds.

  • px (float) – Drive Hamiltonian coefficients in Hz (ordinary frequency).

  • py (float) – Drive Hamiltonian coefficients in Hz (ordinary frequency).

  • pz (float) – Drive Hamiltonian coefficients in Hz (ordinary frequency).

  • td (float) – Decay time constant in seconds.

  • bx (float) – Bloch vector offset (fixed point, reached asymptotically).

  • by (float) – Bloch vector offset (fixed point, reached asymptotically).

  • bz (float) – Bloch vector offset (fixed point, reached asymptotically).

Returns:

Rows are [⟨X(t)⟩, ⟨Y(t)⟩, ⟨Z(t)⟩].

Return type:

(3, N) ndarray

class quchip.analysis.cross_resonance.CRHamiltonianResult(IX, IY, IZ, ZX, ZY, ZZ, IX_err, IY_err, IZ_err, ZX_err, ZY_err, ZZ_err, params_ctrl0=None, params_ctrl1=None, cov_ctrl0=None, cov_ctrl1=None, cost_ctrl0=None, cost_ctrl1=None, converged=None, message='')[source]

Bases: object

Store CR Hamiltonian coefficients in GHz and local uncertainty estimates.

The uncertainties use a local, residual-scaled covariance, even when per-point standard deviations supply weights. An unavailable estimate is None. Convergence alone does not establish identifiability.

All six quantities are ordinary frequency (not angular). Multiply by 2π to convert to rad/ns. The convention agrees with Sheldon et al. (PRA 93, 060302(R), 2016):

H_eff = (I ⊗ A + Z ⊗ B) / 2

where A = ω_IX X + ω_IY Y + ω_IZ Z and B = ω_ZX X + ω_ZY Y + ω_ZZ Z.

params_ctrl0 / params_ctrl1 hold the raw fit output [px, py, pz, td, bx, by, bz] for each control state. They are diagnostics only and stay in the fit’s internal units (px/py/pz in Hz, td in seconds).

Variables:
  • ZZ (IX, IY, IZ, ZX, ZY,) – Fitted ordinary-frequency coefficients in GHz.

  • ZZ_err (IX_err, IY_err, IZ_err, ZX_err, ZY_err,) – Local residual-scaled uncertainty estimates in GHz.

  • params_ctrl1 (params_ctrl0,) – Raw fit parameters for the two control states.

  • cov_ctrl1 (cov_ctrl0,) – Raw local covariance matrices.

  • cost_ctrl1 (cost_ctrl0,) – Least-squares costs.

  • converged (bool or None) – Fit convergence status.

  • message (str) – Solver status message.

IX: float
IY: float
IZ: float
ZX: float
ZY: float
ZZ: float
IX_err: float | None
IY_err: float | None
IZ_err: float | None
ZX_err: float | None
ZY_err: float | None
ZZ_err: float | None
params_ctrl0: ndarray | None = None
params_ctrl1: ndarray | None = None
cov_ctrl0: ndarray | None = None
cov_ctrl1: ndarray | None = None
cost_ctrl0: float | None = None
cost_ctrl1: float | None = None
converged: bool | None = None
message: str = ''
coeffs()[source]

Return {name: (value_ghz, err_ghz)} for all six coefficients.

summary()[source]

Print and return a formatted summary of all six coefficients.

class quchip.analysis.cross_resonance.CRSusceptibilityResult(m_control_0, m_control_1, IX_per_amplitude, ZX_per_amplitude, control, target, drive)[source]

Bases: object

Store weak-drive CR coefficients per unit of programmed drive amplitude.

For control-state-conditioned target-transition matrix elements

\[m_z = \langle\widetilde{z_c,1_t}|D_c|\widetilde{z_c,0_t}\rangle,\]

the effective-Hamiltonian convention

\[H_\mathrm{eff} = \tfrac{1}{2}[\mathrm{Re}(C_I)IX + \mathrm{Im}(C_I)IY + \mathrm{Re}(C_Z)ZX + \mathrm{Im}(C_Z)ZY]\]

gives IX_per_amplitude = (m_0 + m_1)/2 and ZX_per_amplitude = (m_0 - m_1)/2 for a real carrier’s peak amplitude. The raw matrix elements retain the full drive operator normalization. Complex values encode IX+i IY and ZX+i ZY in the raising convention. Their real and imaginary parts multiply Hermitian X and Y operators.

Variables:
  • m_control_1 (m_control_0,) – Dressed target-transition matrix elements, conditioned on the control in |0> and in |1>.

  • ZX_per_amplitude (IX_per_amplitude,) – Complex weak-drive X/Y coefficients per unit of scheduled peak amplitude.

  • drive (control, target,) – Resolved labels.

m_control_0: Any
m_control_1: Any
IX_per_amplitude: Any
ZX_per_amplitude: Any
control: str
target: str
drive: str
quchip.analysis.cross_resonance.analyze_cr_susceptibility(chip, control, target, *, drive=None)[source]

Return the dressed weak-drive CR response of one directed edge.

The analysis projects the physical control-line operator onto the target’s dressed 0 -> 1 transition twice, with the control in |0> and in |1>. It does no pulse, no rotating-frame solve, and no time evolution.

Parameters:
  • chip (Chip) – Coupled chip with attached control equipment.

  • control (str | 'BaseDevice') – Directed CR control and target, as device objects or labels.

  • target (str | 'BaseDevice') – Directed CR control and target, as device objects or labels.

  • drive (str | 'BaseDrive' | None) – Control line to project. If omitted, the function selects the unique wired device-target line attached to control.

Returns:

Conditional matrix elements and the related IX and ZX complex X/Y coefficients per unit of scheduled peak amplitude. Carrier selection contributes a factor of one half.

Return type:

CRSusceptibilityResult

Raises:

ValueError – If the edge is a self-edge, control equipment is absent, implicit drive resolution is ambiguous, or the selected line does not target the control.

References

Magesan and Gambetta, Phys. Rev. A 101, 052308 (2020). https://arxiv.org/abs/1804.04073. Malekakhlagh, Magesan, and McKay, Phys. Rev. A 102, 042605 (2020). https://arxiv.org/abs/2005.00133.

quchip.analysis.cross_resonance.analyze_cross_resonance(durations, ctrl0, ctrl1, sigma_ctrl0=None, sigma_ctrl1=None, t_offset=0.0)[source]

Extract CR effective Hamiltonian coefficients from Bloch tomography data.

Fits the target qubit’s Bloch trajectory under a CR pulse to the analytic model in bloch_model(), once with the control qubit in |0⟩ and once in |1⟩. Combining the two fits isolates the six coefficients {IX, IY, IZ, ZX, ZY, ZZ}.

The decomposition is:

p_ctrl0 = (I/2) part → ω_IX, ω_IY, ω_IZ
p_ctrl1 = (Z/2) part → ω_ZX, ω_ZY, ω_ZZ

Specifically:

ω_ZQ = (p_ctrl0_Q - p_ctrl1_Q) / 2 ω_IQ = (p_ctrl0_Q + p_ctrl1_Q) / 2

for Q ∈ {X, Y, Z}.

Parameters:
  • durations ((N,) ndarray) – CR pulse durations in ns (the package convention). They must be monotone but need not be equally spaced. The function converts them to seconds once, at its boundary, for the fit.

  • ctrl0 (dict or 2D ndarray) – Target qubit’s Bloch trajectory with the control in |0⟩. Give a dict with keys "x", "y", "z" or a 2D array with shape (3, N) or (N, 3) (see _as_xyz()).

  • ctrl1 (dict or 2D ndarray) – Same, with the control in |1⟩.

  • sigma_ctrl0 (dict with keys "x", "y", "z" (optional)) – Per-point standard deviations for the control-|0⟩ data, used as inverse weights in the least-squares fit.

  • sigma_ctrl1 (dict with keys "x", "y", "z" (optional)) – Same for the control-|1⟩ data.

  • t_offset (float) – Subtract this offset (in ns) from durations before the fit, e.g. to exclude a pulse-ramp transient.

Returns:

Six coefficients in GHz (the package’s units contract). The function converts the Hz-valued fit internals exactly once, at this boundary. The uncertainties are local, residual-scaled covariance estimates, even when per-point standard deviations supply weights. An unavailable one-sigma uncertainty is None. converged and message report the optimizer outcome separately from the fit quality and the local uncertainty, so you can still examine nonconverged candidates.

Return type:

CRHamiltonianResult

Raises:

RuntimeError – If no initial guess gives a finite candidate for one of the control states.

Examples

>>> import numpy as np
>>> from quchip import analyze_cross_resonance
>>> durations = np.linspace(0, 400, 20)  # ns
>>> ctrl0 = {"x": np.sin(0.02 * durations), "y": np.zeros_like(durations),
...          "z": np.cos(0.02 * durations)}
>>> ctrl1 = {"x": np.sin(0.03 * durations), "y": np.zeros_like(durations),
...          "z": np.cos(0.03 * durations)}
>>> result = analyze_cross_resonance(durations, ctrl0, ctrl1)
>>> zx, zx_err = result.coeffs()["ZX"]  # GHz