Python library for simulating superconducting qubits with energy spectra, plotting, and QuTiP integration
—
Tools for building and analyzing coupled qubit-oscillator systems with arbitrary interaction terms. Enables simulation of circuit QED architectures, multi-qubit systems, and complex quantum devices.
Container class for managing multiple quantum subsystems and their interactions, providing a unified interface for composite system analysis.
class HilbertSpace:
def __init__(self, subsystem_list: list = None, interaction_list: list = None,
ignore_low_overlap: bool = False, evals_method: str = None,
evals_method_options: dict = None, esys_method: str = None,
esys_method_options: dict = None):
"""
Composite quantum system container.
Parameters:
- subsystem_list (list): List of quantum systems to include
- interaction_list (list): Optional list of interaction terms
- ignore_low_overlap (bool): Whether to ignore low overlap warnings
- evals_method (str): Method for eigenvalue calculations
- evals_method_options (dict): Options for eigenvalue method
- esys_method (str): Method for eigensystem calculations
- esys_method_options (dict): Options for eigensystem method
"""
def add_system(self, subsystem) -> int:
"""
Add a quantum system to the composite space.
Parameters:
- subsystem: Quantum system object (qubit, oscillator, etc.)
Returns:
- int: Index of the added subsystem
"""
def add_interaction(self, check_validity: bool = True, id_str: str = None, **kwargs):
"""
Add interaction term between subsystems. Supports multiple interfaces.
Parameters:
- check_validity (bool): Whether to validate the interaction
- id_str (str): Optional identifier for the interaction
- **kwargs: Interaction specification (varies by interface used)
"""
def eigenvals(self, evals_count: int = 6) -> np.ndarray:
"""Calculate dressed eigenvalues of composite system."""
def eigensys(self, evals_count: int = 6) -> tuple:
"""Calculate dressed eigenvalues and eigenvectors."""
def hamiltonian(self) -> np.ndarray:
"""Full Hamiltonian matrix including interactions."""
def bare_hamiltonian(self) -> np.ndarray:
"""Bare Hamiltonian without interactions."""
def interaction_hamiltonian(self) -> np.ndarray:
"""Interaction Hamiltonian only."""
def generate_lookup(self) -> None:
"""Generate lookup tables for dressed states."""
def bare_eigenvals(self, subsys: int, evals_count: int = 6) -> np.ndarray:
"""Eigenvalues of individual subsystem."""
def subsystem_count(self) -> int:
"""Number of subsystems in composite space."""
def dimension(self) -> int:
"""Total Hilbert space dimension."""
def subsystem_dims(self) -> list:
"""Dimensions of individual subsystems."""Classes for specifying coupling between quantum subsystems with flexible operator definitions.
class InteractionTerm:
def __init__(self, g_strength: float, op1, op2, subsys1: int, subsys2: int):
"""
Interaction term between two subsystems.
Parameters:
- g_strength (float): Coupling strength coefficient
- op1: Operator matrix for first subsystem
- op2: Operator matrix for second subsystem
- subsys1 (int): Index of first subsystem
- subsys2 (int): Index of second subsystem
"""
def hamiltonian_term(self, subsystem_list: list) -> np.ndarray:
"""Generate Hamiltonian contribution for this interaction."""
class InteractionTermStr:
def __init__(self, g_strength: float, operator1_name: str, subsys1: int,
operator2_name: str, subsys2: int):
"""
String-based interaction term specification.
Parameters:
- g_strength (float): Coupling strength
- operator1_name (str): Name of operator on first subsystem
- subsys1 (int): Index of first subsystem
- operator2_name (str): Name of operator on second subsystem
- subsys2 (int): Index of second subsystem
"""Harmonic and anharmonic oscillator implementations for modeling cavity modes and other coherent degrees of freedom.
class Oscillator:
def __init__(self, E_osc: float, truncated_dim: int):
"""
Harmonic oscillator for cavity modes.
Parameters:
- E_osc (float): Oscillator frequency
- truncated_dim (int): Number of Fock states to include
"""
def eigenvals(self, evals_count: int = 6) -> np.ndarray:
"""Harmonic oscillator eigenvalues."""
def eigensys(self, evals_count: int = 6) -> tuple:
"""Harmonic oscillator eigensystem."""
@property
def annihilation_operator(self) -> np.ndarray:
"""Lowering operator matrix."""
@property
def creation_operator(self) -> np.ndarray:
"""Raising operator matrix."""
@property
def number_operator(self) -> np.ndarray:
"""Number operator matrix."""
@property
def position_operator(self) -> np.ndarray:
"""Position quadrature operator."""
@property
def momentum_operator(self) -> np.ndarray:
"""Momentum quadrature operator."""
class KerrOscillator:
def __init__(self, E_osc: float, K: float, truncated_dim: int):
"""
Kerr-nonlinear oscillator.
Parameters:
- E_osc (float): Linear oscillator frequency
- K (float): Kerr nonlinearity strength
- truncated_dim (int): Fock space truncation
"""
def hamiltonian(self) -> np.ndarray:
"""Kerr oscillator Hamiltonian including nonlinearity."""import scqubits as scq
import numpy as np
# Create subsystems
transmon = scq.Transmon(EJ=25.0, EC=0.2, ng=0.0, ncut=30)
cavity = scq.Oscillator(E_osc=6.0, truncated_dim=4)
# Create composite system
hilbert_space = scq.HilbertSpace([transmon, cavity])
# Add dispersive interaction (chi coupling)
g = 0.1 # coupling strength in GHz
hilbert_space.add_interaction(
g_strength=g,
op1=transmon.n_operator,
op2=cavity.creation_operator + cavity.annihilation_operator
)
# Calculate dressed spectrum
dressed_evals = hilbert_space.eigenvals(evals_count=12)
print("Dressed energy levels:", dressed_evals)
# Compare to bare energies
bare_transmon = transmon.eigenvals(evals_count=3)
bare_cavity = cavity.eigenvals(evals_count=4)
print("Bare transmon levels:", bare_transmon)
print("Bare cavity levels:", bare_cavity)# Create two qubits
qubit1 = scq.Transmon(EJ=20.0, EC=0.3, ng=0.0, ncut=25)
qubit2 = scq.Transmon(EJ=18.0, EC=0.25, ng=0.0, ncut=25)
# Create composite system
two_qubit_system = scq.HilbertSpace([qubit1, qubit2])
# Add capacitive coupling
J = 0.02 # coupling strength
two_qubit_system.add_interaction(
g_strength=J,
op1=qubit1.n_operator,
op2=qubit2.n_operator
)
# Calculate spectrum
spectrum = two_qubit_system.eigenvals(evals_count=16)
# Analyze level structure
from scqubits.utils.misc import make_bare_labels
bare_labels = make_bare_labels([qubit1, qubit2])# Parameter sweep of composite system
cavity = scq.Oscillator(E_osc=6.0, truncated_dim=3)
transmon = scq.Transmon(EJ=25.0, EC=0.2, ng=0.0, ncut=20)
system = scq.HilbertSpace([transmon, cavity])
# Add interaction
system.add_interaction(
g_strength=0.15,
op1=transmon.n_operator,
op2=cavity.number_operator
)
# Sweep transmon frequency
EJ_vals = np.linspace(20, 30, 51)
sweep = scq.ParameterSweep(
hilbert_space=system,
paramvals_by_name={'EJ': EJ_vals},
evals_count=10,
subsys_update_list=[0] # Update only transmon
)
sweep.run()
sweep.plot_evals_vs_paramvals()# Transmon coupled to multiple cavity modes
transmon = scq.Transmon(EJ=25.0, EC=0.2, ng=0.0, ncut=30)
cavity1 = scq.Oscillator(E_osc=6.0, truncated_dim=3)
cavity2 = scq.Oscillator(E_osc=8.5, truncated_dim=3)
# Create three-body system
system = scq.HilbertSpace([transmon, cavity1, cavity2])
# Add coupling to both modes
g1, g2 = 0.1, 0.08
system.add_interaction(
g_strength=g1,
op1=transmon.n_operator,
op2=cavity1.creation_operator + cavity1.annihilation_operator
)
system.add_interaction(
g_strength=g2,
op1=transmon.n_operator,
op2=cavity2.creation_operator + cavity2.annihilation_operator
)
# Add cavity-cavity coupling
J_cc = 0.01
system.add_interaction(
g_strength=J_cc,
op1=cavity1.creation_operator,
op2=cavity2.annihilation_operator
)
# Add conjugate term
system.add_interaction(
g_strength=J_cc,
op1=cavity1.annihilation_operator,
op2=cavity2.creation_operator
)
# Analyze three-body spectrum
spectrum = system.eigenvals(evals_count=20)Install with Tessl CLI
npx tessl i tessl/pypi-scqubits