CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-scqubits

Python library for simulating superconducting qubits with energy spectra, plotting, and QuTiP integration

Pending
Overview
Eval results
Files

circuit-analysis.mddocs/

Circuit Analysis

Symbolic circuit analysis tools for custom superconducting circuits, enabling automated quantization and Hamiltonian generation from circuit descriptions. Supports YAML-based circuit specification and flexible node/branch analysis.

Capabilities

Circuit Construction

Main class for building and analyzing custom superconducting circuits from symbolic descriptions.

class Circuit:
    def __init__(self, input_string: str, from_file: bool = False, ext_basis: str = None,
                 initiate_sym_calc: bool = True, truncated_dim: int = None):
        """
        Custom circuit analysis from symbolic description.
        
        Parameters:
        - input_string (str): YAML circuit description or file path
        - from_file (bool): Whether input_string is a file path
        - ext_basis (str): External basis choice for quantization
        - initiate_sym_calc (bool): Whether to immediately perform symbolic calculation
        - truncated_dim (int): Truncated Hilbert space dimension
        """
        
    def hamiltonian(self) -> np.ndarray:
        """Generate circuit Hamiltonian matrix."""
        
    def eigenvals(self, evals_count: int = 6) -> np.ndarray:
        """Calculate circuit eigenvalues."""
        
    def eigensys(self, evals_count: int = 6) -> tuple:
        """Calculate circuit eigenvalues and eigenvectors."""
        
    def plot_evals_vs_paramvals(self, param_name: str, param_vals: np.ndarray,
                               evals_count: int = 6, **kwargs):
        """Plot energy levels vs circuit parameter."""
        
    def wavefunction(self, esys: tuple = None, which: int = 0, 
                    mode: str = 'abs_sqr') -> WaveFunction:
        """Return circuit wavefunction for specified eigenstate."""
        
    def set_discretization(self, var_name: str, grid: Grid1d) -> None:
        """Set discretization grid for continuous circuit variable."""
        
    def configure(self, **kwargs) -> None:
        """Configure circuit parameters."""

class SymbolicCircuit:
    def __init__(self, nodes_dict: dict, branches_dict: dict, initiate: bool = True):
        """
        Symbolic circuit representation from nodes and branches.
        
        Parameters:
        - nodes_dict (dict): Dictionary defining circuit nodes
        - branches_dict (dict): Dictionary defining circuit branches
        - initiate (bool): Whether to immediately build symbolic representation
        """
        
    def configure(self, transformation: str = None, closure_branches: list = None) -> None:
        """Configure symbolic circuit transformation and closure."""
        
    def generate_hamiltonian_symbolic(self) -> sympy.Expr:
        """Generate symbolic Hamiltonian expression."""

Circuit Utilities

Helper functions for circuit construction, parameter management, and example generation.

def truncation_template(system_hierarchy: list, individual_trunc_dim: int = 6, combined_trunc_dim: int = 30) -> list:
    """
    Generate template for defining truncated dimensions for subsystems in hierarchical diagonalization.
    
    Parameters:
    - system_hierarchy (list): Hierarchy of system components
    - individual_trunc_dim (int): Truncation dimension for individual subsystems
    - combined_trunc_dim (int): Truncation dimension for combined systems
    
    Returns:
    - list: Truncation template structure
    """

def assemble_circuit(circuit_list: List[str], couplers: str, rename_parameters: bool = False) -> Tuple[str, List[Dict[int, int]]]:
    """
    Assemble a large circuit from smaller sub-circuits and coupling elements.
    
    Parameters:
    - circuit_list (List[str]): List of sub-circuit YAML strings
    - couplers (str): YAML string characterizing coupler branches
    - rename_parameters (bool): Whether to rename conflicting parameters
    
    Returns:
    - Tuple[str, List[Dict[int, int]]]: Assembled circuit YAML and node mapping
    """

def assemble_transformation_matrix(transformation_name: str, **kwargs) -> np.ndarray:
    """
    Create coordinate transformation matrix.
    
    Parameters:
    - transformation_name (str): Type of transformation
    - **kwargs: Transformation parameters
    
    Returns:
    - np.ndarray: Transformation matrix
    """

def example_circuit(qubit_type: str) -> str:
    """
    Get example circuit YAML description.
    
    Parameters:
    - qubit_type (str): Type of qubit circuit ('transmon', 'fluxonium', etc.)
    
    Returns:
    - str: YAML circuit description
    """

Grid and Discretization

Classes for discretizing continuous circuit variables and managing computational grids.

class Grid1d:
    def __init__(self, min_val: float, max_val: float, pt_count: int):
        """
        One-dimensional discretization grid.
        
        Parameters:
        - min_val (float): Minimum grid value
        - max_val (float): Maximum grid value  
        - pt_count (int): Number of grid points
        """
        
    @property
    def grid_spacing(self) -> float:
        """Grid spacing between adjacent points."""
        
    @property
    def grid_points(self) -> np.ndarray:
        """Array of all grid points."""
        
    def closest_index(self, value: float) -> int:
        """Find grid index closest to given value."""

Usage Examples

Basic Circuit Analysis

import scqubits as scq

# Get example transmon circuit description
transmon_yaml = scq.core.circuit_utils.example_circuit('transmon')
print("Transmon circuit YAML:")
print(transmon_yaml)

# Create circuit from description
circuit = scq.Circuit(transmon_yaml, from_file=False)

# Calculate spectrum
energies = circuit.eigenvals(evals_count=6)
print("Circuit energy levels:", energies)

# Compare to built-in Transmon class
transmon_builtin = scq.Transmon(EJ=25.0, EC=0.2, ng=0.0, ncut=30)
builtin_energies = transmon_builtin.eigenvals(evals_count=6)
print("Built-in Transmon energies:", builtin_energies)

Custom Circuit Design

# Define custom circuit YAML
custom_circuit_yaml = """
branches:
- ["J", "JJ", 1, 2, EJ=25.0, EC=0.2]
- ["C", "C", 1, 0, C=1.0]
- ["L", "L", 2, 0, L=0.1]

nodes:
  1: [0, 1]
  2: [1, 0]

# Parameters for quantization
vars:
  phi1: [0, 2*pi]
  phi2: [0, 2*pi]

# Truncation settings  
truncated_dim: 20
"""

# Create circuit
custom_circuit = scq.Circuit(custom_circuit_yaml, from_file=False)

# Set up discretization grids
phi_grid = scq.Grid1d(min_val=0, max_val=2*np.pi, pt_count=100)
custom_circuit.set_discretization('phi1', phi_grid)
custom_circuit.set_discretization('phi2', phi_grid)

# Calculate spectrum
spectrum = custom_circuit.eigenvals(evals_count=8)
print("Custom circuit spectrum:", spectrum)

Parameter Sweeps with Circuits

# Create fluxonium circuit
fluxonium_yaml = scq.core.circuit_utils.example_circuit('fluxonium')
fluxonium_circuit = scq.Circuit(fluxonium_yaml, from_file=False)

# Parameter sweep over external flux
flux_vals = np.linspace(0, 1, 51)
hilbert_space = scq.HilbertSpace([fluxonium_circuit])

def update_flux(system, flux_val):
    """Update circuit flux parameter."""
    system.subsystem_list[0].configure(flux=flux_val)

sweep = scq.ParameterSweep(
    hilbert_space=hilbert_space,
    paramvals_by_name={'flux': flux_vals},
    update_hilbert_space=update_flux,
    evals_count=6
)

sweep.run()
sweep.plot_evals_vs_paramvals()

Symbolic Circuit Construction

# Define circuit using nodes and branches dictionaries
nodes_dict = {
    1: [1, 0],  # Node 1 at coordinates (1, 0)
    2: [0, 1],  # Node 2 at coordinates (0, 1)
    3: [0, 0]   # Ground node
}

branches_dict = {
    'JJ1': {
        'type': 'JJ',
        'nodes': [1, 3],
        'parameters': {'EJ': 20.0, 'EC': 0.15}
    },
    'JJ2': {
        'type': 'JJ', 
        'nodes': [2, 3],
        'parameters': {'EJ': 18.0, 'EC': 0.12}
    },
    'C12': {
        'type': 'C',
        'nodes': [1, 2],
        'parameters': {'C': 5.0}
    }
}

# Create symbolic circuit
symbolic_circuit = scq.SymbolicCircuit(
    nodes_dict=nodes_dict,
    branches_dict=branches_dict
)

# Generate symbolic Hamiltonian
H_symbolic = symbolic_circuit.generate_hamiltonian_symbolic()
print("Symbolic Hamiltonian:")
print(H_symbolic)

Advanced Circuit Configuration

# Create circuit with custom truncation
circuit_yaml = """
branches:
- ["JJ1", "JJ", 1, 0, EJ=25.0, EC=0.2]
- ["JJ2", "JJ", 2, 0, EJ=20.0, EC=0.18] 
- ["C", "C", 1, 2, C=2.0]

nodes:
  1: [0, 1]
  2: [1, 0]

vars:
  phi1: [-pi, pi]
  phi2: [-pi, pi]
"""

# Create truncation template
truncation = scq.core.circuit_utils.truncation_template()
truncation.update({
    'phi1_truncation': 15,
    'phi2_truncation': 15,
    'interaction_truncation': 10
})

# Create circuit with custom settings
circuit = scq.Circuit(circuit_yaml, from_file=False)
circuit.configure(
    truncated_dim=50,
    ext_basis='harmonic'
)

# Set up grid discretization
phi_grid_fine = scq.Grid1d(min_val=-np.pi, max_val=np.pi, pt_count=150)
circuit.set_discretization('phi1', phi_grid_fine)
circuit.set_discretization('phi2', phi_grid_fine)

# Calculate detailed spectrum
detailed_spectrum = circuit.eigenvals(evals_count=12)
print("Detailed circuit spectrum:", detailed_spectrum)

Circuit Visualization and Analysis

# Create circuit and calculate wavefunctions
circuit = scq.Circuit(transmon_yaml, from_file=False)
evals, evecs = circuit.eigensys(evals_count=4)

# Analyze ground state wavefunction
ground_state_wf = circuit.wavefunction(esys=(evals, evecs), which=0)
ground_state_wf.plot(mode='abs_sqr')

# Analyze first excited state
excited_state_wf = circuit.wavefunction(esys=(evals, evecs), which=1)
excited_state_wf.plot(mode='abs_sqr')

# Calculate matrix elements for circuit operators
# Note: Circuit operators need to be defined based on circuit variables
print("Energy level differences:")
for i in range(1, len(evals)):
    transition = evals[i] - evals[0]
    print(f"0->{i} transition: {transition:.4f} GHz")

Multi-Junction Circuits

# Three-junction flux qubit circuit
flux_qubit_yaml = """
branches:
- ["JJ1", "JJ", 1, 0, EJ=10.0, EC=0.1]
- ["JJ2", "JJ", 2, 0, EJ=10.0, EC=0.1] 
- ["JJ3", "JJ", 1, 2, EJ=8.0, EC=0.08]
- ["L", "L", 1, 2, L=0.5]

nodes:
  1: [0, 1]
  2: [1, 0]

# External flux threading the loop
external_flux: 0.5

vars:
  phi1: [-2*pi, 2*pi]
  phi2: [-2*pi, 2*pi]

truncated_dim: 25
"""

# Create and analyze flux qubit circuit
flux_circuit = scq.Circuit(flux_qubit_yaml, from_file=False)

# Sweep external flux
flux_values = np.linspace(0, 1, 101)

def update_circuit_flux(system, flux_val):
    system.subsystem_list[0].configure(external_flux=flux_val)

flux_sweep = scq.ParameterSweep(
    hilbert_space=scq.HilbertSpace([flux_circuit]),
    paramvals_by_name={'external_flux': flux_values},
    update_hilbert_space=update_circuit_flux,
    evals_count=8
)

flux_sweep.run()
flux_sweep.plot_evals_vs_paramvals()

Install with Tessl CLI

npx tessl i tessl/pypi-scqubits

docs

circuit-analysis.md

composite-systems.md

file-io.md

index.md

noise-analysis.md

parameter-sweeps.md

qubit-models.md

spectrum-analysis.md

units-settings.md

tile.json