0
# Spectrum Analysis
1
2
Comprehensive tools for calculating matrix elements, transition rates, and spectroscopic properties. Provides functions for analyzing quantum transitions, computing selection rules, and generating absorption/emission spectra.
3
4
## Capabilities
5
6
### Matrix Element Calculations
7
8
Functions for computing matrix elements between quantum states, essential for understanding transition strengths and selection rules.
9
10
```python { .api }
11
def matrix_element(state1: Union[np.ndarray, qt.Qobj], operator: Union[np.ndarray, csc_matrix, qt.Qobj],
12
state2: Union[np.ndarray, qt.Qobj]) -> Union[float, complex]:
13
"""
14
Calculate matrix element <state1|operator|state2>.
15
16
Parameters:
17
- state1 (Union[np.ndarray, qt.Qobj]): Bra state vector
18
- operator (Union[np.ndarray, csc_matrix, qt.Qobj]): Operator matrix
19
- state2 (Union[np.ndarray, qt.Qobj]): Ket state vector
20
21
Returns:
22
- Union[float, complex]: Matrix element value
23
"""
24
25
def get_matrixelement_table(operator: Union[np.ndarray, csc_matrix, qt.Qobj],
26
state_table: Union[np.ndarray, qt.Qobj]) -> np.ndarray:
27
"""
28
Generate comprehensive matrix element table.
29
30
Parameters:
31
- operator (Union[np.ndarray, csc_matrix, qt.Qobj]): Operator for matrix elements
32
- state_table (Union[np.ndarray, qt.Qobj]): Table of eigenvectors in scipy eigsh format
33
34
Returns:
35
- np.ndarray: Matrix element table [i,j] = <i|operator|j>
36
"""
37
38
def absorption_spectrum(transitions: dict, initial_state_labels: list,
39
lineshape_func, **kwargs) -> tuple:
40
"""
41
Calculate absorption spectrum from transition data.
42
43
Parameters:
44
- transitions (dict): Dictionary of transition frequencies and strengths
45
- initial_state_labels (list): Labels for initial states
46
- lineshape_func: Function defining spectral lineshape
47
- **kwargs: Additional parameters for lineshape function
48
49
Returns:
50
- tuple: (frequencies, spectrum) arrays
51
"""
52
53
def emission_spectrum(transitions: dict, initial_state_labels: list,
54
lineshape_func, **kwargs) -> tuple:
55
"""
56
Calculate emission spectrum from transition data.
57
58
Parameters:
59
- transitions (dict): Dictionary of transition frequencies and strengths
60
- initial_state_labels (list): Labels for initial states
61
- lineshape_func: Function defining spectral lineshape
62
- **kwargs: Additional parameters for lineshape function
63
64
Returns:
65
- tuple: (frequencies, spectrum) arrays
66
"""
67
```
68
69
### Eigensystem Utilities
70
71
Functions for manipulating and organizing eigenvalue/eigenvector data with consistent ordering and phase conventions.
72
73
```python { .api }
74
def order_eigensystem(evals: np.ndarray, evecs: np.ndarray,
75
previous_evecs: np.ndarray = None) -> tuple:
76
"""
77
Order eigenvalues and eigenvectors consistently.
78
79
Parameters:
80
- evals (np.ndarray): Eigenvalues to order
81
- evecs (np.ndarray): Corresponding eigenvectors
82
- previous_evecs (np.ndarray): Reference eigenvectors for consistent ordering
83
84
Returns:
85
- tuple: (ordered_evals, ordered_evecs)
86
"""
87
88
def standardize_phases(evecs: np.ndarray) -> np.ndarray:
89
"""
90
Standardize phase conventions for eigenvectors.
91
92
Parameters:
93
- evecs (np.ndarray): Eigenvector matrix
94
95
Returns:
96
- np.ndarray: Eigenvectors with standardized phases
97
"""
98
99
def identity_wrap(operator, subsystem_index: int, subsystem_list: list) -> np.ndarray:
100
"""
101
Wrap operator with identity matrices for composite systems.
102
103
Parameters:
104
- operator: Operator matrix to wrap
105
- subsystem_index (int): Index of subsystem for the operator
106
- subsystem_list (list): List of all subsystems
107
108
Returns:
109
- np.ndarray: Wrapped operator for composite Hilbert space
110
"""
111
```
112
113
### Spectroscopic Analysis
114
115
Tools for analyzing quantum transitions and computing spectroscopic properties relevant to experimental measurements.
116
117
```python { .api }
118
def transition_table(system, operator, evals_count: int = None) -> np.ndarray:
119
"""
120
Generate table of all transition matrix elements.
121
122
Parameters:
123
- system: Quantum system object
124
- operator: Transition operator (e.g., charge, flux)
125
- evals_count (int): Number of energy levels to include
126
127
Returns:
128
- np.ndarray: Transition matrix elements [initial, final]
129
"""
130
131
def plot_transitions(system, operator, initial_state: int = 0,
132
final_states: list = None, **kwargs):
133
"""
134
Plot transition strengths as function of energy.
135
136
Parameters:
137
- system: Quantum system object
138
- operator: Transition operator
139
- initial_state (int): Index of initial state
140
- final_states (list): Indices of final states to plot
141
- **kwargs: Plotting parameters
142
"""
143
144
def oscillator_strength(system, operator, initial_state: int,
145
final_state: int) -> float:
146
"""
147
Calculate oscillator strength for transition.
148
149
Parameters:
150
- system: Quantum system object
151
- operator: Transition operator
152
- initial_state (int): Initial state index
153
- final_state (int): Final state index
154
155
Returns:
156
- float: Oscillator strength
157
"""
158
```
159
160
### Lineshape Functions
161
162
Standard lineshape functions for generating realistic spectra with finite linewidths.
163
164
```python { .api }
165
def lorentzian_lineshape(frequency: float, center_freq: float,
166
gamma: float) -> float:
167
"""
168
Lorentzian lineshape function.
169
170
Parameters:
171
- frequency (float): Frequency at which to evaluate lineshape
172
- center_freq (float): Center frequency of transition
173
- gamma (float): FWHM linewidth
174
175
Returns:
176
- float: Lineshape amplitude at given frequency
177
"""
178
179
def gaussian_lineshape(frequency: float, center_freq: float,
180
sigma: float) -> float:
181
"""
182
Gaussian lineshape function.
183
184
Parameters:
185
- frequency (float): Frequency at which to evaluate lineshape
186
- center_freq (float): Center frequency of transition
187
- sigma (float): Standard deviation of Gaussian
188
189
Returns:
190
- float: Lineshape amplitude at given frequency
191
"""
192
```
193
194
## Usage Examples
195
196
### Basic Matrix Element Analysis
197
198
```python
199
import scqubits as scq
200
import numpy as np
201
from scqubits.utils import spectrum_utils
202
203
# Create transmon and calculate eigensystem
204
transmon = scq.Transmon(EJ=25.0, EC=0.2, ng=0.0, ncut=30)
205
evals, evecs = transmon.eigensys(evals_count=6)
206
207
# Calculate charge matrix elements
208
n_matrix = spectrum_utils.get_matrixelement_table(
209
transmon,
210
transmon.n_operator,
211
evecs=evecs
212
)
213
214
print("Charge matrix elements:")
215
print(n_matrix)
216
217
# Calculate specific transition matrix element
218
transition_01 = spectrum_utils.matrix_element(
219
evecs[:, 0], # Ground state
220
transmon.n_operator, # Charge operator
221
evecs[:, 1] # First excited state
222
)
223
print(f"0->1 charge matrix element: {transition_01}")
224
225
# Calculate oscillator strengths
226
osc_strength_01 = spectrum_utils.oscillator_strength(
227
transmon, transmon.n_operator, 0, 1
228
)
229
print(f"0->1 oscillator strength: {osc_strength_01}")
230
```
231
232
### Transition Analysis
233
234
```python
235
# Analyze all transitions from ground state
236
ground_state = 0
237
excited_states = [1, 2, 3, 4, 5]
238
239
print("Transitions from ground state:")
240
for final_state in excited_states:
241
# Transition energy
242
transition_energy = evals[final_state] - evals[ground_state]
243
244
# Matrix element magnitude
245
matrix_elem = abs(n_matrix[ground_state, final_state])
246
247
print(f"0->{final_state}: Energy = {transition_energy:.4f} GHz, "
248
f"|<0|n|{final_state}>| = {matrix_elem:.4f}")
249
```
250
251
### Spectral Analysis with Parameter Sweep
252
253
```python
254
# Calculate transition strengths across parameter sweep
255
ng_vals = np.linspace(-2, 2, 101)
256
hilbert_space = scq.HilbertSpace([transmon])
257
258
sweep = scq.ParameterSweep(
259
hilbert_space=hilbert_space,
260
paramvals_by_name={'ng': ng_vals},
261
evals_count=6
262
)
263
sweep.run()
264
265
# Extract transition frequencies and matrix elements
266
transitions_01 = []
267
matrix_elements_01 = []
268
269
for i, ng in enumerate(ng_vals):
270
# Get eigensystem at this parameter point
271
evals_i, evecs_i = sweep.eigensys(param_index=i)
272
273
# Transition frequency
274
omega_01 = evals_i[1] - evals_i[0]
275
transitions_01.append(omega_01)
276
277
# Matrix element
278
n_matrix_i = spectrum_utils.get_matrixelement_table(
279
transmon, transmon.n_operator, evecs=evecs_i
280
)
281
matrix_elements_01.append(abs(n_matrix_i[0, 1]))
282
283
# Plot results
284
import matplotlib.pyplot as plt
285
286
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))
287
288
ax1.plot(ng_vals, transitions_01)
289
ax1.set_ylabel('01 Transition (GHz)')
290
ax1.set_title('Transition Frequency vs Offset Charge')
291
292
ax2.plot(ng_vals, matrix_elements_01)
293
ax2.set_xlabel('ng')
294
ax2.set_ylabel('|<0|n|1>|')
295
ax2.set_title('Transition Matrix Element vs Offset Charge')
296
297
plt.tight_layout()
298
plt.show()
299
```
300
301
### Composite System Analysis
302
303
```python
304
# Matrix elements in composite systems
305
transmon = scq.Transmon(EJ=25.0, EC=0.2, ng=0.0, ncut=25)
306
cavity = scq.Oscillator(E_osc=6.0, truncated_dim=4)
307
308
system = scq.HilbertSpace([transmon, cavity])
309
system.add_interaction(
310
g_strength=0.1,
311
op1=transmon.n_operator,
312
op2=cavity.creation_operator + cavity.annihilation_operator
313
)
314
315
# Calculate dressed eigensystem
316
dressed_evals, dressed_evecs = system.eigensys(evals_count=12)
317
318
# Wrap transmon charge operator for composite space
319
n_wrapped = spectrum_utils.identity_wrap(
320
transmon.n_operator,
321
subsystem_index=0,
322
subsystem_list=[transmon, cavity]
323
)
324
325
# Calculate dressed matrix elements
326
dressed_n_matrix = spectrum_utils.get_matrixelement_table(
327
system, n_wrapped, evecs=dressed_evecs
328
)
329
330
print("Dressed charge matrix elements (first 6x6 block):")
331
print(dressed_n_matrix[:6, :6])
332
```
333
334
### Spectral Lineshapes
335
336
```python
337
# Generate realistic spectrum with lineshapes
338
from scqubits.utils.spectrum_utils import lorentzian_lineshape
339
340
# Define transitions and their strengths
341
transitions = {
342
'frequencies': [4.8, 4.9, 5.0, 5.1], # GHz
343
'strengths': [0.1, 0.8, 1.0, 0.3] # Relative intensities
344
}
345
346
# Frequency range for spectrum
347
freq_range = np.linspace(4.5, 5.5, 1000)
348
spectrum = np.zeros_like(freq_range)
349
350
# Add each transition with Lorentzian lineshape
351
gamma = 0.01 # 10 MHz linewidth
352
353
for freq, strength in zip(transitions['frequencies'], transitions['strengths']):
354
for i, f in enumerate(freq_range):
355
spectrum[i] += strength * lorentzian_lineshape(f, freq, gamma)
356
357
# Plot spectrum
358
plt.figure(figsize=(10, 6))
359
plt.plot(freq_range, spectrum, 'b-', linewidth=2)
360
plt.xlabel('Frequency (GHz)')
361
plt.ylabel('Absorption (arb. units)')
362
plt.title('Simulated Absorption Spectrum')
363
plt.grid(True, alpha=0.3)
364
plt.show()
365
```
366
367
### Selection Rules Analysis
368
369
```python
370
# Analyze selection rules for different operators
371
operators = {
372
'n': transmon.n_operator,
373
'cos_phi': transmon.cos_phi_operator,
374
'sin_phi': transmon.sin_phi_operator
375
}
376
377
# Calculate matrix elements for each operator
378
for op_name, operator in operators.items():
379
matrix_table = spectrum_utils.get_matrixelement_table(
380
transmon, operator, evecs=evecs
381
)
382
383
print(f"\n{op_name} operator matrix elements:")
384
print("State transitions with |matrix element| > 0.01:")
385
386
for i in range(6):
387
for j in range(6):
388
if i != j and abs(matrix_table[i, j]) > 0.01:
389
print(f" {i}->{j}: {matrix_table[i, j]:.4f}")
390
```