0
# Parameter Sweeps
1
2
Efficient parameter space exploration with built-in caching, parallel processing, and visualization tools. Enables systematic analysis of qubit behavior across parameter ranges with optimized computation and storage.
3
4
## Capabilities
5
6
### Parameter Sweep Execution
7
8
Main class for running parameter sweeps across one or multiple parameters simultaneously with automatic result caching and parallel processing support.
9
10
```python { .api }
11
class ParameterSweep:
12
def __init__(self, hilbert_space: HilbertSpace, paramvals_by_name: dict, evals_count: int = 6,
13
subsys_update_list: list = None, update_hilbert_space = None,
14
num_cpus: int = None):
15
"""
16
Parameter sweep for quantum systems.
17
18
Parameters:
19
- hilbert_space (HilbertSpace): Quantum system to analyze
20
- paramvals_by_name (dict): Parameter names and value arrays to sweep
21
- evals_count (int): Number of eigenvalues to calculate
22
- subsys_update_list (list): Indices of subsystems to update during sweep
23
- update_hilbert_space: Function to update system parameters
24
- num_cpus (int): Number of CPU cores for parallel processing
25
"""
26
27
def run(self) -> None:
28
"""Execute the parameter sweep calculation."""
29
30
def plot_evals_vs_paramvals(self, which: int = -1, subtract_ground: bool = False,
31
param_name: str = None, **kwargs):
32
"""
33
Plot energy levels vs parameter values.
34
35
Parameters:
36
- which (int): Which subsystem to plot (-1 for composite system)
37
- subtract_ground (bool): Subtract ground state energy
38
- param_name (str): Parameter name for x-axis
39
"""
40
41
def transitions(self, initial_state_ind: int, final_state_ind: int) -> np.ndarray:
42
"""
43
Calculate transition frequencies between states.
44
45
Parameters:
46
- initial_state_ind (int): Index of initial state
47
- final_state_ind (int): Index of final state
48
49
Returns:
50
- np.ndarray: Transition frequencies across parameter sweep
51
"""
52
53
def plot_transitions(self, initial_state_ind: int, final_state_ind: int,
54
param_name: str = None, **kwargs):
55
"""Plot transition frequencies vs parameter."""
56
57
def eigenvals(self, param_index: int = None) -> np.ndarray:
58
"""Get eigenvalues at specific parameter point."""
59
60
def eigensys(self, param_index: int = None) -> tuple:
61
"""Get eigensystem at specific parameter point."""
62
63
def bare_specdata(self, subsys_index: int) -> SpectrumData:
64
"""Get bare spectrum data for subsystem."""
65
66
def dressed_specdata(self) -> SpectrumData:
67
"""Get dressed spectrum data for composite system."""
68
```
69
70
### Stored Sweep Data
71
72
Container for saved parameter sweep results with methods for data access and visualization.
73
74
```python { .api }
75
class StoredSweep:
76
def __init__(self, spectrumdata: SpectrumData, hilbert_space: HilbertSpace = None,
77
bare_specdata_list: list = None):
78
"""
79
Container for stored parameter sweep data.
80
81
Parameters:
82
- spectrumdata (SpectrumData): Spectrum data object
83
- hilbert_space (HilbertSpace): Associated quantum system
84
- bare_specdata_list (list): List of bare spectrum data for subsystems
85
"""
86
87
def plot_evals_vs_paramvals(self, which: int = -1, **kwargs):
88
"""Plot stored energy levels vs parameters."""
89
90
def transitions(self, initial_state_ind: int, final_state_ind: int) -> np.ndarray:
91
"""Calculate transitions from stored data."""
92
93
def new_parametersweep(self, update_hilbert_space, paramvals_by_name: dict) -> ParameterSweep:
94
"""Create new parameter sweep based on stored data."""
95
```
96
97
### Spectrum Data Management
98
99
Data structures for storing and managing eigenvalue and eigenvector data from parameter sweeps.
100
101
```python { .api }
102
class SpectrumData:
103
def __init__(self, energy_table: np.ndarray, system_params: dict = None,
104
state_table: np.ndarray = None, matrixelem_table: np.ndarray = None):
105
"""
106
Storage for spectrum calculation results.
107
108
Parameters:
109
- energy_table (np.ndarray): Eigenvalues across parameter sweep
110
- system_params (dict): System parameters
111
- state_table (np.ndarray): Eigenvectors across parameter sweep
112
- matrixelem_table (np.ndarray): Matrix elements across sweep
113
"""
114
115
def subtract_ground(self) -> SpectrumData:
116
"""Return new SpectrumData with ground state energy subtracted."""
117
118
def eigenvals(self, param_index: int = None) -> np.ndarray:
119
"""Get eigenvalues at parameter point."""
120
121
def eigenvecs(self, param_index: int = None) -> np.ndarray:
122
"""Get eigenvectors at parameter point."""
123
124
def matrixelems(self, operator_name: str, param_index: int = None) -> np.ndarray:
125
"""Get matrix elements at parameter point."""
126
```
127
128
## Usage Examples
129
130
### Single Parameter Sweep
131
132
```python
133
import scqubits as scq
134
import numpy as np
135
136
# Create transmon
137
transmon = scq.Transmon(EJ=25.0, EC=0.2, ng=0.0, ncut=30)
138
hilbert_space = scq.HilbertSpace([transmon])
139
140
# Define parameter sweep
141
ng_vals = np.linspace(-2.0, 2.0, 101)
142
sweep = scq.ParameterSweep(
143
hilbert_space=hilbert_space,
144
paramvals_by_name={'ng': ng_vals},
145
evals_count=6
146
)
147
148
# Run calculation
149
sweep.run()
150
151
# Plot results
152
sweep.plot_evals_vs_paramvals(
153
subtract_ground=True,
154
param_name='ng'
155
)
156
157
# Calculate transition frequencies
158
transition_01 = sweep.transitions(0, 1)
159
transition_12 = sweep.transitions(1, 2)
160
161
print("01 transition range:", transition_01.min(), "to", transition_01.max())
162
print("12 transition range:", transition_12.min(), "to", transition_12.max())
163
```
164
165
### Multi-Parameter Sweep
166
167
```python
168
# Two-parameter sweep
169
EJ_vals = np.linspace(20, 30, 26)
170
ng_vals = np.linspace(-1, 1, 51)
171
172
sweep_2d = scq.ParameterSweep(
173
hilbert_space=hilbert_space,
174
paramvals_by_name={
175
'EJ': EJ_vals,
176
'ng': ng_vals
177
},
178
evals_count=4
179
)
180
181
sweep_2d.run()
182
183
# Plot 2D parameter space
184
import matplotlib.pyplot as plt
185
186
# Extract data for plotting
187
energies = sweep_2d.dressed_specdata().energy_table
188
EJ_grid, ng_grid = np.meshgrid(EJ_vals, ng_vals, indexing='ij')
189
190
# Plot ground state energy
191
plt.figure(figsize=(10, 8))
192
plt.contourf(EJ_grid, ng_grid, energies[:, :, 0], levels=50)
193
plt.xlabel('EJ (GHz)')
194
plt.ylabel('ng')
195
plt.title('Ground State Energy')
196
plt.colorbar()
197
plt.show()
198
```
199
200
### Composite System Sweep
201
202
```python
203
# Sweep coupled qubit-cavity system
204
transmon = scq.Transmon(EJ=25.0, EC=0.2, ng=0.0, ncut=25)
205
cavity = scq.Oscillator(E_osc=6.0, truncated_dim=4)
206
207
system = scq.HilbertSpace([transmon, cavity])
208
system.add_interaction(
209
g_strength=0.1,
210
op1=transmon.n_operator,
211
op2=cavity.creation_operator + cavity.annihilation_operator
212
)
213
214
# Sweep transmon frequency
215
EJ_vals = np.linspace(20, 30, 51)
216
sweep = scq.ParameterSweep(
217
hilbert_space=system,
218
paramvals_by_name={'EJ': EJ_vals},
219
evals_count=12,
220
subsys_update_list=[0] # Only update transmon
221
)
222
223
sweep.run()
224
225
# Plot dressed spectrum
226
sweep.plot_evals_vs_paramvals(
227
which=-1, # Composite system
228
subtract_ground=True
229
)
230
231
# Plot bare transmon levels for comparison
232
sweep.plot_evals_vs_paramvals(
233
which=0, # First subsystem (transmon)
234
subtract_ground=True
235
)
236
```
237
238
### Parallel Processing
239
240
```python
241
# Enable parallel processing for large sweeps
242
import scqubits as scq
243
244
# Set global multiprocessing settings
245
scq.settings.NUM_CPUS = 4
246
scq.settings.MULTIPROC = 'multiprocessing'
247
248
# Large parameter sweep
249
flux_vals = np.linspace(0, 1, 201)
250
fluxonium = scq.Fluxonium(EJ=2.0, EC=0.5, EL=0.8, flux=0.0)
251
252
sweep = scq.ParameterSweep(
253
hilbert_space=scq.HilbertSpace([fluxonium]),
254
paramvals_by_name={'flux': flux_vals},
255
evals_count=10,
256
num_cpus=4 # Parallel processing
257
)
258
259
sweep.run()
260
```
261
262
### Saving and Loading Results
263
264
```python
265
# Save sweep results
266
scq.io_utils.write(sweep, 'transmon_sweep.h5')
267
268
# Load saved sweep
269
loaded_sweep = scq.io_utils.read('transmon_sweep.h5')
270
271
# Create StoredSweep for analysis
272
stored_sweep = scq.StoredSweep(
273
spectrumdata=loaded_sweep.dressed_specdata(),
274
hilbert_space=loaded_sweep.hilbert_space
275
)
276
277
# Analyze stored data
278
stored_sweep.plot_evals_vs_paramvals()
279
transitions = stored_sweep.transitions(0, 1)
280
```
281
282
### Custom Update Functions
283
284
```python
285
def update_system(system, param_val):
286
"""Custom function to update system parameters."""
287
# Update both EJ and EC simultaneously
288
EJ_new = param_val
289
EC_new = param_val * 0.01 # Scale EC with EJ
290
291
system.subsystem_list[0].EJ = EJ_new
292
system.subsystem_list[0].EC = EC_new
293
294
# Use custom update function
295
EJ_vals = np.linspace(15, 35, 41)
296
sweep = scq.ParameterSweep(
297
hilbert_space=system,
298
paramvals_by_name={'EJ': EJ_vals},
299
update_hilbert_space=update_system,
300
evals_count=6
301
)
302
303
sweep.run()
304
```