0
# Units and Settings
1
2
Flexible units system supporting multiple frequency scales with global settings for computation optimization, event management, and visualization preferences.
3
4
## Capabilities
5
6
### Units System
7
8
Functions for managing frequency units across the entire scqubits package with automatic conversion and consistent labeling.
9
10
```python { .api }
11
def get_units() -> str:
12
"""
13
Get current system-wide frequency units.
14
15
Returns:
16
- str: Current units ('GHz', 'MHz', 'kHz', or 'Hz')
17
"""
18
19
def set_units(units: str) -> str:
20
"""
21
Set system-wide frequency units.
22
23
Parameters:
24
- units (str): Target units ('GHz', 'MHz', 'kHz', or 'Hz')
25
26
Returns:
27
- str: The units that were set
28
"""
29
30
def show_supported_units() -> None:
31
"""Display all supported frequency units and their conversion factors."""
32
33
def to_standard_units(value: float) -> float:
34
"""
35
Convert value from current units to Hz.
36
37
Parameters:
38
- value (float): Value in current system units
39
40
Returns:
41
- float: Value converted to Hz
42
"""
43
44
def from_standard_units(value: float) -> float:
45
"""
46
Convert value from Hz to current system units.
47
48
Parameters:
49
- value (float): Value in Hz
50
51
Returns:
52
- float: Value in current system units
53
"""
54
55
def get_units_time_label() -> str:
56
"""
57
Get appropriate time unit label based on current frequency units.
58
59
Returns:
60
- str: Time unit label (e.g., 'ns' for GHz, 'μs' for MHz)
61
"""
62
```
63
64
### Global Settings
65
66
Configuration variables controlling package behavior, computation optimization, and feature availability.
67
68
```python { .api }
69
# Computation Settings
70
AUTORUN_SWEEP: bool = True
71
"""Automatically run parameter sweeps when created."""
72
73
NUM_CPUS: int = None
74
"""Number of CPU cores for parallel processing (None = auto-detect)."""
75
76
MULTIPROC: str = 'multiprocessing'
77
"""Multiprocessing library choice ('multiprocessing', 'pathos')."""
78
79
# Event System
80
DISPATCH_ENABLED: bool = True
81
"""Enable/disable central dispatch event system."""
82
83
# File I/O
84
FILE_TYPES: list = ['.h5', '.hdf5', '.csv']
85
"""Supported file formats for data persistence."""
86
87
# Visualization
88
MODE_FUNC_DICT: dict = {
89
'abs_sqr': lambda psi: np.abs(psi)**2,
90
'abs': np.abs,
91
'real': np.real,
92
'imag': np.imag,
93
'phase': np.angle
94
}
95
"""Available modes for wavefunction visualization."""
96
97
# Diagonalization
98
DEFAULT_DIAG_METHOD: str = 'esys_scipy_sparse'
99
"""Default eigenvalue solver method."""
100
```
101
102
### Settings Management
103
104
Functions for configuring and querying global package settings.
105
106
```python { .api }
107
def configure_settings(**kwargs) -> None:
108
"""
109
Configure multiple settings simultaneously.
110
111
Parameters:
112
- **kwargs: Setting name-value pairs to update
113
"""
114
115
def get_setting(setting_name: str):
116
"""
117
Get current value of a setting.
118
119
Parameters:
120
- setting_name (str): Name of setting to query
121
122
Returns:
123
- Current value of the setting
124
"""
125
126
def reset_settings() -> None:
127
"""Reset all settings to their default values."""
128
129
def show_settings() -> None:
130
"""Display current values of all settings."""
131
```
132
133
### Diagonalization Methods
134
135
Available eigenvalue solver methods with performance characteristics and use cases.
136
137
```python { .api }
138
DIAG_METHODS: dict = {
139
'evals_scipy_dense': 'Dense matrix eigenvalues (scipy.linalg.eigh)',
140
'esys_scipy_dense': 'Dense matrix eigensystem (scipy.linalg.eigh)',
141
'evals_scipy_sparse': 'Sparse matrix eigenvalues (scipy.sparse.linalg.eigsh)',
142
'esys_scipy_sparse': 'Sparse matrix eigensystem (scipy.sparse.linalg.eigsh)',
143
'evals_scipy_sparse_SM': 'Sparse eigenvalues - smallest magnitude',
144
'esys_scipy_sparse_SM': 'Sparse eigensystem - smallest magnitude',
145
'evals_qutip': 'QuTiP eigenvalues (qutip.groundstate)',
146
'esys_qutip': 'QuTiP eigensystem (qutip.groundstate)'
147
}
148
"""Dictionary of available diagonalization methods."""
149
150
def set_diag_method(method_name: str) -> None:
151
"""
152
Set default diagonalization method.
153
154
Parameters:
155
- method_name (str): Method name from DIAG_METHODS keys
156
"""
157
```
158
159
## Usage Examples
160
161
### Units Management
162
163
```python
164
import scqubits as scq
165
166
# Check current units
167
current_units = scq.units.get_units()
168
print(f"Current units: {current_units}")
169
170
# Show all supported units
171
scq.units.show_supported_units()
172
173
# Create transmon with GHz units (default)
174
transmon = scq.Transmon(EJ=25.0, EC=0.2, ng=0.0, ncut=30)
175
energies_GHz = transmon.eigenvals(evals_count=4)
176
print("Energies in GHz:", energies_GHz)
177
178
# Switch to MHz units
179
scq.units.set_units('MHz')
180
energies_MHz = transmon.eigenvals(evals_count=4)
181
print("Energies in MHz:", energies_MHz)
182
183
# Verify conversion
184
print("Conversion factor:", energies_MHz[0] / energies_GHz[0])
185
186
# Convert specific values
187
value_in_GHz = 5.0
188
value_in_Hz = scq.units.to_standard_units(value_in_GHz)
189
print(f"{value_in_GHz} GHz = {value_in_Hz} Hz")
190
191
# Switch back to GHz
192
scq.units.set_units('GHz')
193
```
194
195
### Performance Optimization
196
197
```python
198
# Configure parallel processing
199
scq.settings.NUM_CPUS = 4
200
scq.settings.MULTIPROC = 'multiprocessing'
201
202
# Check available CPU cores
203
import multiprocessing
204
print(f"Available CPU cores: {multiprocessing.cpu_count()}")
205
print(f"Using {scq.settings.NUM_CPUS} cores")
206
207
# Large parameter sweep with parallel processing
208
transmon = scq.Transmon(EJ=25.0, EC=0.2, ng=0.0, ncut=30)
209
ng_vals = np.linspace(-2, 2, 201) # Large sweep
210
211
sweep = scq.ParameterSweep(
212
hilbert_space=scq.HilbertSpace([transmon]),
213
paramvals_by_name={'ng': ng_vals},
214
evals_count=6,
215
num_cpus=scq.settings.NUM_CPUS
216
)
217
218
import time
219
start_time = time.time()
220
sweep.run()
221
end_time = time.time()
222
print(f"Sweep completed in {end_time - start_time:.2f} seconds")
223
```
224
225
### Diagonalization Method Selection
226
227
```python
228
# Show available diagonalization methods
229
print("Available diagonalization methods:")
230
for method, description in scq.DIAG_METHODS.items():
231
print(f" {method}: {description}")
232
233
# Test different methods for performance
234
transmon = scq.Transmon(EJ=25.0, EC=0.2, ng=0.0, ncut=50) # Large basis
235
236
methods_to_test = ['esys_scipy_sparse', 'esys_scipy_dense']
237
results = {}
238
239
for method in methods_to_test:
240
# Set diagonalization method
241
scq.set_diag_method(method)
242
243
# Time the calculation
244
start_time = time.time()
245
evals, evecs = transmon.eigensys(evals_count=6)
246
end_time = time.time()
247
248
results[method] = {
249
'time': end_time - start_time,
250
'energies': evals[:3]
251
}
252
253
# Compare results
254
print("\nDiagonalization method comparison:")
255
for method, result in results.items():
256
print(f"{method}:")
257
print(f" Time: {result['time']:.4f} seconds")
258
print(f" Energies: {result['energies']}")
259
```
260
261
### Settings Configuration
262
263
```python
264
# Display current settings
265
print("Current settings:")
266
scq.show_settings()
267
268
# Configure multiple settings at once
269
scq.configure_settings(
270
NUM_CPUS=2,
271
AUTORUN_SWEEP=False,
272
DISPATCH_ENABLED=True
273
)
274
275
# Check specific setting
276
autorun = scq.get_setting('AUTORUN_SWEEP')
277
print(f"AUTORUN_SWEEP is set to: {autorun}")
278
279
# Create parameter sweep (won't auto-run due to AUTORUN_SWEEP=False)
280
sweep = scq.ParameterSweep(
281
hilbert_space=scq.HilbertSpace([transmon]),
282
paramvals_by_name={'ng': np.linspace(-1, 1, 21)},
283
evals_count=4
284
)
285
286
# Manually run sweep since auto-run is disabled
287
print("Running sweep manually...")
288
sweep.run()
289
290
# Reset to defaults
291
scq.reset_settings()
292
print("Settings reset to defaults")
293
```
294
295
### Units in Calculations
296
297
```python
298
# Demonstrate units consistency across calculations
299
scq.units.set_units('GHz')
300
301
# Create system with GHz parameters
302
transmon = scq.Transmon(EJ=25.0, EC=0.2, ng=0.0, ncut=30)
303
cavity = scq.Oscillator(E_osc=6.0, truncated_dim=4)
304
305
system = scq.HilbertSpace([transmon, cavity])
306
system.add_interaction(
307
g_strength=0.1, # 100 MHz coupling in GHz units
308
op1=transmon.n_operator,
309
op2=cavity.creation_operator + cavity.annihilation_operator
310
)
311
312
# Calculate in GHz
313
spectrum_GHz = system.eigenvals(evals_count=8)
314
print("Spectrum in GHz:", spectrum_GHz[:4])
315
316
# Switch to MHz and recalculate
317
scq.units.set_units('MHz')
318
spectrum_MHz = system.eigenvals(evals_count=8)
319
print("Spectrum in MHz:", spectrum_MHz[:4])
320
321
# Verify unit conversion
322
conversion_factor = spectrum_MHz[0] / spectrum_GHz[0]
323
print(f"MHz/GHz ratio: {conversion_factor}")
324
```
325
326
### Time Domain Analysis
327
328
```python
329
# Use appropriate time units based on frequency units
330
scq.units.set_units('GHz')
331
time_label = scq.units.get_units_time_label()
332
print(f"Frequency units: GHz, Time units: {time_label}")
333
334
# Calculate coherence times
335
T1 = 50.0 # microseconds
336
T2 = 25.0 # microseconds
337
338
# Convert to appropriate time units
339
if time_label == 'ns':
340
T1_converted = T1 * 1000 # μs to ns
341
T2_converted = T2 * 1000
342
elif time_label == 'μs':
343
T1_converted = T1
344
T2_converted = T2
345
346
print(f"T1 = {T1_converted} {time_label}")
347
print(f"T2 = {T2_converted} {time_label}")
348
349
# Calculate corresponding frequencies
350
gamma1 = 1 / (2 * np.pi * T1_converted * 1e-9) # Convert to Hz, then to current units
351
gamma2 = 1 / (2 * np.pi * T2_converted * 1e-9)
352
353
gamma1_current = scq.units.from_standard_units(gamma1)
354
gamma2_current = scq.units.from_standard_units(gamma2)
355
356
print(f"Γ1 = {gamma1_current:.6f} {scq.units.get_units()}")
357
print(f"Γ2 = {gamma2_current:.6f} {scq.units.get_units()}")
358
```