mirror of
https://github.com/vale981/fibre_walk_project_code
synced 2025-03-04 09:21:38 -05:00
first shot at the spectral matching...
This commit is contained in:
parent
98518ce793
commit
17abcf5ce9
6 changed files with 275 additions and 37 deletions
18
flake.lock
generated
18
flake.lock
generated
|
@ -59,11 +59,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1716792620,
|
"lastModified": 1718083092,
|
||||||
"narHash": "sha256-wQmXzee/veETYJv93TkRYsAQkEdt2QYCJeJil5SrJfg=",
|
"narHash": "sha256-EQsPXycAbmby4meQUNLYfFaGOiqz2J9AlwFRV4UiHnY=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "7d7cf1590c05d799745bf456f2b95b798f48d3bb",
|
"rev": "aa1ebdaf49a606e21c06e0f6ed7aece9a41831c3",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -84,11 +84,11 @@
|
||||||
"treefmt-nix": "treefmt-nix"
|
"treefmt-nix": "treefmt-nix"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1716813403,
|
"lastModified": 1717965289,
|
||||||
"narHash": "sha256-9+G8tEOh3QkjSUV2UMC+TpvzKOR8IUFlkJJTMpVQMkc=",
|
"narHash": "sha256-62VsS1MvwcsyYWnxxOD9rX5yqDUvMXH7qE3Kj8HECYE=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "poetry2nix",
|
"repo": "poetry2nix",
|
||||||
"rev": "12599ecaa9ec641c29dc8fd07f8267b23874bf3a",
|
"rev": "304f8235fb0729fd48567af34fcd1b58d18f9b95",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -156,11 +156,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1715940852,
|
"lastModified": 1717278143,
|
||||||
"narHash": "sha256-wJqHMg/K6X3JGAE9YLM0LsuKrKb4XiBeVaoeMNlReZg=",
|
"narHash": "sha256-u10aDdYrpiGOLoxzY/mJ9llST9yO8Q7K/UlROoNxzDw=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "treefmt-nix",
|
"repo": "treefmt-nix",
|
||||||
"rev": "2fba33a182602b9d49f0b2440513e5ee091d838b",
|
"rev": "3eb96ca1ae9edf792a8e0963cc92fddfa5a87706",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
1
scripts/experiments/.#007_generate_fake_analysis_data.py
Symbolic link
1
scripts/experiments/.#007_generate_fake_analysis_data.py
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
hiro@Phillips.106575:1718131872
|
|
@ -16,7 +16,7 @@ path = "../../data/22_05_24/ringdown_try_2"
|
||||||
scan = ScanData.from_dir(path)
|
scan = ScanData.from_dir(path)
|
||||||
|
|
||||||
|
|
||||||
# %% Set Window
|
# %% Extract Rough Peaks
|
||||||
window = tuple(
|
window = tuple(
|
||||||
np.array([0.016244684251065847 + 0.000002, 0.016248626903395593 + 49e-5])
|
np.array([0.016244684251065847 + 0.000002, 0.016248626903395593 + 49e-5])
|
||||||
+ 8e-3
|
+ 8e-3
|
||||||
|
@ -30,5 +30,5 @@ peak_info = find_peaks(scan, ringdown_params, window, prominence=0.008)
|
||||||
peak_info = refine_peaks(peak_info, ringdown_params)
|
peak_info = refine_peaks(peak_info, ringdown_params)
|
||||||
plot_spectrum_and_peak_info(ax_spectrum, peak_info, ringdown_params)
|
plot_spectrum_and_peak_info(ax_spectrum, peak_info, ringdown_params)
|
||||||
|
|
||||||
# extract
|
# extract FSR and hybridization amplitude
|
||||||
extract_Ω_δ(peak_info, ringdown_params)
|
extract_Ω_δ(peak_info, ringdown_params)
|
||||||
|
|
104
scripts/experiments/007_generate_fake_analysis_data.py
Normal file
104
scripts/experiments/007_generate_fake_analysis_data.py
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
from rabifun.system import *
|
||||||
|
from rabifun.plots import *
|
||||||
|
from rabifun.utilities import *
|
||||||
|
from rabifun.analysis import *
|
||||||
|
from ringfit.data import ScanData
|
||||||
|
import functools
|
||||||
|
|
||||||
|
# %% interactive
|
||||||
|
|
||||||
|
|
||||||
|
@functools.lru_cache()
|
||||||
|
def make_params_and_solve(
|
||||||
|
total_lifetimes, eom_off_lifetime, ω_c=0.1 / 2, N=10, g_0=1 / 4
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Make a set of parameters for the system with the current
|
||||||
|
best-known settings.
|
||||||
|
"""
|
||||||
|
|
||||||
|
Ω = 13
|
||||||
|
|
||||||
|
params = Params(
|
||||||
|
η=0.5,
|
||||||
|
Ω=Ω,
|
||||||
|
δ=1 / 4,
|
||||||
|
ω_c=ω_c,
|
||||||
|
g_0=g_0,
|
||||||
|
laser_detuning=0,
|
||||||
|
N=2 * N + 2,
|
||||||
|
N_couplings=N,
|
||||||
|
measurement_detuning=Ω * (3),
|
||||||
|
α=0,
|
||||||
|
rwa=False,
|
||||||
|
flat_energies=False,
|
||||||
|
correct_lamb_shift=0,
|
||||||
|
laser_off_time=0,
|
||||||
|
)
|
||||||
|
|
||||||
|
params.laser_off_time = params.lifetimes(eom_off_lifetime)
|
||||||
|
params.drive_off_time = params.lifetimes(eom_off_lifetime)
|
||||||
|
|
||||||
|
params.drive_override = (
|
||||||
|
np.array([params.Ω, params.Ω * (1 - params.δ), params.δ * 2 * params.Ω]),
|
||||||
|
np.repeat(params.Ω, 3),
|
||||||
|
)
|
||||||
|
|
||||||
|
t = time_axis(params, lifetimes=total_lifetimes, resolution=0.01)
|
||||||
|
solution = solve(t, params)
|
||||||
|
return params, t, solution
|
||||||
|
|
||||||
|
|
||||||
|
def generate_phase_one_data():
|
||||||
|
"""
|
||||||
|
This generates some intensity data for phase one of the
|
||||||
|
calibration protocol, where the aim is to extract the resonator
|
||||||
|
spectrum.
|
||||||
|
"""
|
||||||
|
|
||||||
|
total_lifetimes = 50
|
||||||
|
eom_off_lifetime = total_lifetimes * 2 / 3
|
||||||
|
fluct_size = 0.05
|
||||||
|
|
||||||
|
params, t, solution = make_params_and_solve(
|
||||||
|
total_lifetimes, eom_off_lifetime, N=10, g_0=10
|
||||||
|
)
|
||||||
|
signal = output_signal(t, solution.y, params)
|
||||||
|
|
||||||
|
rng = np.random.default_rng(seed=0)
|
||||||
|
signal += np.mean(abs(signal)) * rng.standard_normal(len(signal)) * fluct_size * 100
|
||||||
|
|
||||||
|
fig = make_figure()
|
||||||
|
ax_realtime, ax_spectrum = fig.subplots(2, 1)
|
||||||
|
|
||||||
|
ax_realtime.plot(t[::500], signal[::500])
|
||||||
|
ax_realtime.axvline(params.laser_off_time, color="black", linestyle="--")
|
||||||
|
|
||||||
|
# now we plot the power spectrum
|
||||||
|
window = (float(params.laser_off_time or 0), float(t[-1]))
|
||||||
|
|
||||||
|
ringdown_params = RingdownParams(
|
||||||
|
fω_shift=params.measurement_detuning,
|
||||||
|
mode_window=(params.N + 2, params.N + 2),
|
||||||
|
fΩ_guess=params.Ω * (1 + rng.standard_normal() * fluct_size),
|
||||||
|
fδ_guess=params.Ω * params.δ * (1 + rng.standard_normal() * fluct_size),
|
||||||
|
η_guess=params.η * (1 + rng.standard_normal() * fluct_size),
|
||||||
|
)
|
||||||
|
|
||||||
|
scan = ScanData(np.ones_like(signal), signal, t)
|
||||||
|
peak_info = find_peaks(scan, ringdown_params, window, prominence=0.1)
|
||||||
|
peak_info = refine_peaks(peak_info, ringdown_params)
|
||||||
|
plot_spectrum_and_peak_info(ax_spectrum, peak_info, ringdown_params)
|
||||||
|
|
||||||
|
Ω, ΔΩ, ladder = extract_Ω_δ(peak_info, ringdown_params, threshold=0.2)
|
||||||
|
|
||||||
|
for index, type, _ in ladder:
|
||||||
|
freq_index = peak_info.peaks[index]
|
||||||
|
ax_spectrum.plot(
|
||||||
|
peak_info.freq[freq_index],
|
||||||
|
peak_info.normalized_power[freq_index],
|
||||||
|
"o" if type == 0 else "*",
|
||||||
|
color="C4" if type == 0 else "C5",
|
||||||
|
label=type,
|
||||||
|
)
|
||||||
|
return Ω, ΔΩ, ladder
|
|
@ -30,8 +30,6 @@ def fourier_transform(
|
||||||
t = t[mask]
|
t = t[mask]
|
||||||
signal = signal[mask] # * scipy.signal.windows.hamming(len(t))
|
signal = signal[mask] # * scipy.signal.windows.hamming(len(t))
|
||||||
|
|
||||||
#
|
|
||||||
|
|
||||||
freq = scipy.fft.rfftfreq(len(t), t[2] - t[1])
|
freq = scipy.fft.rfftfreq(len(t), t[2] - t[1])
|
||||||
fft = scipy.fft.rfft(signal, norm="forward", workers=os.cpu_count())
|
fft = scipy.fft.rfft(signal, norm="forward", workers=os.cpu_count())
|
||||||
|
|
||||||
|
@ -94,7 +92,7 @@ class RingdownParams:
|
||||||
@property
|
@property
|
||||||
def low_cutoff(self) -> float:
|
def low_cutoff(self) -> float:
|
||||||
"""The low cutoff frequency of the ringdown spectrum fft."""
|
"""The low cutoff frequency of the ringdown spectrum fft."""
|
||||||
return self.fω_shift - self.mode_window[0] * self.fΩ_guess
|
return max(self.fω_shift - self.mode_window[0] * self.fΩ_guess, 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def high_cutoff(self) -> float:
|
def high_cutoff(self) -> float:
|
||||||
|
@ -204,7 +202,8 @@ def refine_peaks(peaks: RingdownPeakData, params: RingdownParams):
|
||||||
Δwidths = []
|
Δwidths = []
|
||||||
|
|
||||||
window = params.η_guess * 3
|
window = params.η_guess * 3
|
||||||
for peak_freq in peak_freqs:
|
deleted_peaks = []
|
||||||
|
for i, peak_freq in enumerate(peak_freqs):
|
||||||
mask = (freqs > peak_freq - window) & (freqs < peak_freq + window)
|
mask = (freqs > peak_freq - window) & (freqs < peak_freq + window)
|
||||||
windowed_freqs = freqs[mask]
|
windowed_freqs = freqs[mask]
|
||||||
windowed_power = power[mask]
|
windowed_power = power[mask]
|
||||||
|
@ -215,20 +214,28 @@ def refine_peaks(peaks: RingdownPeakData, params: RingdownParams):
|
||||||
[np.inf, windowed_freqs[-1], np.inf, 1],
|
[np.inf, windowed_freqs[-1], np.inf, 1],
|
||||||
)
|
)
|
||||||
|
|
||||||
popt, pcov = scipy.optimize.curve_fit(
|
try:
|
||||||
lorentzian,
|
popt, pcov = scipy.optimize.curve_fit(
|
||||||
windowed_freqs,
|
lorentzian,
|
||||||
windowed_power,
|
windowed_freqs,
|
||||||
p0=p0,
|
windowed_power,
|
||||||
bounds=bounds,
|
p0=p0,
|
||||||
)
|
bounds=bounds,
|
||||||
perr = np.sqrt(np.diag(pcov))
|
)
|
||||||
|
perr = np.sqrt(np.diag(pcov))
|
||||||
|
|
||||||
new_freqs.append(popt[1])
|
new_freqs.append(popt[1])
|
||||||
Δfreqs.append(perr[1])
|
Δfreqs.append(perr[1])
|
||||||
|
|
||||||
new_widths.append(popt[2])
|
new_widths.append(popt[2])
|
||||||
Δwidths.append(perr[2])
|
Δwidths.append(perr[2])
|
||||||
|
except:
|
||||||
|
deleted_peaks.append(i)
|
||||||
|
|
||||||
|
peaks.peaks = np.delete(peaks.peaks, deleted_peaks)
|
||||||
|
for key, value in peaks.peak_info.items():
|
||||||
|
if isinstance(value, np.ndarray):
|
||||||
|
peaks.peak_info[key] = np.delete(value, deleted_peaks)
|
||||||
|
|
||||||
peaks.peak_freqs = np.array(new_freqs)
|
peaks.peak_freqs = np.array(new_freqs)
|
||||||
peaks.Δpeak_freqs = np.array(Δfreqs)
|
peaks.Δpeak_freqs = np.array(Δfreqs)
|
||||||
|
@ -238,11 +245,15 @@ def refine_peaks(peaks: RingdownPeakData, params: RingdownParams):
|
||||||
return peaks
|
return peaks
|
||||||
|
|
||||||
|
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
|
||||||
def extract_Ω_δ(
|
def extract_Ω_δ(
|
||||||
peaks: RingdownPeakData, params: RingdownParams, threshold: float = 0.1
|
peaks: RingdownPeakData, params: RingdownParams, threshold: float = 0.1
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Extract the FSR and mode splitting from the peaks.
|
Extract the FSR and mode splitting from the peaks. The threshold
|
||||||
|
regulates the maximum allowed deviation from the expected FSR.
|
||||||
|
|
||||||
:param peaks: The peak data.
|
:param peaks: The peak data.
|
||||||
:param params: The ringdown parameters.
|
:param params: The ringdown parameters.
|
||||||
|
@ -251,12 +262,101 @@ def extract_Ω_δ(
|
||||||
if not peaks.is_refined:
|
if not peaks.is_refined:
|
||||||
raise ValueError("Peaks must be refined.")
|
raise ValueError("Peaks must be refined.")
|
||||||
|
|
||||||
|
peak_indices = peaks.peaks
|
||||||
|
peak_freqs = peaks.peak_freqs
|
||||||
|
Δpeak_freqs = (
|
||||||
|
np.zeros_like(peak_freqs) if peaks.Δpeak_freqs is None else peaks.Δpeak_freqs
|
||||||
|
)
|
||||||
|
|
||||||
Ω_guess = params.fΩ_guess
|
Ω_guess = params.fΩ_guess
|
||||||
δ_guess = params.fδ_guess
|
δ_guess = params.fδ_guess
|
||||||
|
|
||||||
all_diff = np.abs(peaks.peak_freqs[:, None] - peaks.peak_freqs[None, :])
|
# first step: we extract the most common frequency spacing
|
||||||
|
all_diff = np.abs(peak_freqs[:, None] - peak_freqs[None, :])
|
||||||
all_diff = np.triu(all_diff)
|
all_diff = np.triu(all_diff)
|
||||||
|
all_ΔΩ = np.abs(Δpeak_freqs[:, None] ** 2 + Δpeak_freqs[None, :] ** 2)
|
||||||
|
|
||||||
bath_mask = (all_diff - Ω_guess) / Ω_guess < threshold
|
bath_mask = (np.abs((all_diff - Ω_guess)) / Ω_guess < threshold) & (all_diff > 0)
|
||||||
|
candidates = all_diff[bath_mask]
|
||||||
|
Δcandidates = all_ΔΩ[bath_mask]
|
||||||
|
|
||||||
return np.mean((all_diff[bath_mask]))
|
Ω = np.mean(candidates)
|
||||||
|
ΔΩ = max(np.sqrt(np.sum(Δcandidates**2)) / len(candidates), np.std(candidates))
|
||||||
|
|
||||||
|
if np.isnan(Ω):
|
||||||
|
raise ValueError("No FSR found")
|
||||||
|
|
||||||
|
# second step: we walk through the peaks and label them as for the
|
||||||
|
total_peaks = len(peak_indices)
|
||||||
|
peak_pool = list(range(total_peaks))
|
||||||
|
|
||||||
|
ladders = []
|
||||||
|
|
||||||
|
current_peak = 0
|
||||||
|
current_ladder = []
|
||||||
|
|
||||||
|
possible_diffs = np.array([Ω, Ω - δ_guess, 2 * δ_guess])
|
||||||
|
|
||||||
|
while len(peak_pool) > 1:
|
||||||
|
if current_peak == len(peak_pool):
|
||||||
|
if current_ladder:
|
||||||
|
ladders.append(current_ladder)
|
||||||
|
current_ladder = []
|
||||||
|
current_peak = peak_pool[0]
|
||||||
|
|
||||||
|
filtered_freqs = peak_freqs[peak_pool]
|
||||||
|
|
||||||
|
diffs = filtered_freqs - filtered_freqs[current_peak]
|
||||||
|
diffs[diffs <= 0] = np.inf
|
||||||
|
|
||||||
|
diffs = (
|
||||||
|
np.abs(diffs[:, None] - possible_diffs[None, :]) / possible_diffs[None, :]
|
||||||
|
)
|
||||||
|
|
||||||
|
min_coords = np.unravel_index(np.argmin(diffs), diffs.shape)
|
||||||
|
min_diff = diffs[min_coords]
|
||||||
|
|
||||||
|
mode_index, step_type = min_coords
|
||||||
|
|
||||||
|
if min_diff > threshold:
|
||||||
|
if current_ladder:
|
||||||
|
ladders.append(current_ladder)
|
||||||
|
current_ladder = []
|
||||||
|
del peak_pool[current_peak]
|
||||||
|
continue
|
||||||
|
|
||||||
|
current_ladder.append((peak_pool[current_peak], step_type, min_diff))
|
||||||
|
del peak_pool[current_peak]
|
||||||
|
current_peak = mode_index - 1 # we have deleted one peak
|
||||||
|
|
||||||
|
if current_ladder:
|
||||||
|
ladders.append(current_ladder)
|
||||||
|
|
||||||
|
# we want at least one bath mode before the A site
|
||||||
|
ladders = list(
|
||||||
|
filter(
|
||||||
|
lambda ladder: sum([1 if x[1] == 1 else 0 for x in ladder]) > 0,
|
||||||
|
ladders,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
invalid = []
|
||||||
|
for lad_index, ladder in enumerate(ladders):
|
||||||
|
length = len(ladder)
|
||||||
|
for i, elem in enumerate(ladder):
|
||||||
|
if elem[1] == 1:
|
||||||
|
if (i + 2) >= length or not (
|
||||||
|
ladder[i + 1][1] == 2 and ladder[i + 2][1] == 1
|
||||||
|
):
|
||||||
|
invalid.append(lad_index)
|
||||||
|
break
|
||||||
|
|
||||||
|
ladders = [ladder for i, ladder in enumerate(ladders) if i not in invalid]
|
||||||
|
costs = [sum([x[2] for x in ladder]) / len(ladder) for ladder in ladders]
|
||||||
|
|
||||||
|
if len(costs) == 0:
|
||||||
|
raise ValueError("No matching modes found.")
|
||||||
|
|
||||||
|
best = ladders[np.argmin(costs)]
|
||||||
|
|
||||||
|
return Ω, ΔΩ, best
|
||||||
|
|
|
@ -67,6 +67,17 @@ class Params:
|
||||||
correct_lamb_shift: float = 1
|
correct_lamb_shift: float = 1
|
||||||
"""Whether to correct for the Lamb shift by tweaking the detuning."""
|
"""Whether to correct for the Lamb shift by tweaking the detuning."""
|
||||||
|
|
||||||
|
drive_override: tuple[np.ndarray, np.ndarray] | None = None
|
||||||
|
"""
|
||||||
|
Override the drive frequencies (first array, linear frequency) and
|
||||||
|
amplitudes (second array, linear frequency units).
|
||||||
|
|
||||||
|
In this case the detunings of the rotating frame will be zeroed
|
||||||
|
and the parameters :any:`α` and :any:`ω_c` will be ignored.
|
||||||
|
|
||||||
|
The drive strength is normalized to :any:`g_0`.
|
||||||
|
"""
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
if self.N_couplings > self.N:
|
if self.N_couplings > self.N:
|
||||||
raise ValueError("N_couplings must be less than or equal to N.")
|
raise ValueError("N_couplings must be less than or equal to N.")
|
||||||
|
@ -74,6 +85,18 @@ class Params:
|
||||||
if self.initial_state and len(self.initial_state) != 2 * self.N + 2:
|
if self.initial_state and len(self.initial_state) != 2 * self.N + 2:
|
||||||
raise ValueError("Initial state must have length 2N + 2.")
|
raise ValueError("Initial state must have length 2N + 2.")
|
||||||
|
|
||||||
|
if self.drive_override is not None:
|
||||||
|
if len(self.drive_override) != 2:
|
||||||
|
raise ValueError("Drive override must be a tuple of two arrays.")
|
||||||
|
|
||||||
|
if len(self.drive_override[0]) != len(self.drive_override[1]):
|
||||||
|
raise ValueError(
|
||||||
|
"Drive frequencies and amplitudes must have the same length."
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.rwa:
|
||||||
|
raise ValueError("Drive override is not compatible with the RWA.")
|
||||||
|
|
||||||
def periods(self, n: float):
|
def periods(self, n: float):
|
||||||
"""
|
"""
|
||||||
Returns the number of periods of the system that correspond to
|
Returns the number of periods of the system that correspond to
|
||||||
|
@ -116,6 +139,13 @@ class RuntimeParams:
|
||||||
drive_frequencies_and_amplitudes(params)
|
drive_frequencies_and_amplitudes(params)
|
||||||
) # linear frequencies!
|
) # linear frequencies!
|
||||||
|
|
||||||
|
if params.drive_override is not None:
|
||||||
|
self.drive_frequencies = params.drive_override[0]
|
||||||
|
self.g = 2 * np.pi * params.drive_override[1]
|
||||||
|
a_shift = 0
|
||||||
|
self.detunings *= 0
|
||||||
|
self.g /= params.g_0 * np.sqrt(np.sum(self.g**2))
|
||||||
|
|
||||||
self.g *= 2 * np.pi
|
self.g *= 2 * np.pi
|
||||||
self.Ωs = Ωs
|
self.Ωs = Ωs
|
||||||
self.ε = (
|
self.ε = (
|
||||||
|
@ -136,9 +166,12 @@ class RuntimeParams:
|
||||||
self.bath_ε = 2 * np.pi * self.detunings - 1j * params.η / 2
|
self.bath_ε = 2 * np.pi * self.detunings - 1j * params.η / 2
|
||||||
self.a_shift = 2 * np.pi * a_shift
|
self.a_shift = 2 * np.pi * a_shift
|
||||||
self.detuned_Ωs = freqs - self.ε.real
|
self.detuned_Ωs = freqs - self.ε.real
|
||||||
|
|
||||||
self.RWA_H = np.zeros((2 * params.N + 2, 2 * params.N + 2), np.complex128)
|
self.RWA_H = np.zeros((2 * params.N + 2, 2 * params.N + 2), np.complex128)
|
||||||
self.RWA_H[1, 2 : 2 + params.N_couplings] = self.g
|
if not params.drive_override:
|
||||||
self.RWA_H[2 : 2 + params.N_couplings, 1] = np.conj(self.g)
|
self.RWA_H[1, 2 : 2 + params.N_couplings] = self.g
|
||||||
|
self.RWA_H[2 : 2 + params.N_couplings, 1] = np.conj(self.g)
|
||||||
|
|
||||||
self.detuning_matrix = self.detuned_Ωs[:, None] - self.detuned_Ωs[None, :]
|
self.detuning_matrix = self.detuned_Ωs[:, None] - self.detuned_Ωs[None, :]
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -245,9 +278,9 @@ def make_righthand_side(runtime_params: RuntimeParams, params: Params):
|
||||||
differential[0:2] += laser[:2] / np.sqrt(2)
|
differential[0:2] += laser[:2] / np.sqrt(2)
|
||||||
differential[2:] += laser[2:]
|
differential[2:] += laser[2:]
|
||||||
|
|
||||||
# if params.rwa:
|
if params.rwa:
|
||||||
# differential[0] = 0
|
differential[0] = 0
|
||||||
# differential[2 + params.N_couplings :] = 0
|
differential[2 + params.N_couplings :] = 0
|
||||||
|
|
||||||
return -1j * differential
|
return -1j * differential
|
||||||
|
|
||||||
|
@ -314,7 +347,7 @@ def output_signal(t: np.ndarray, amplitudes: np.ndarray, params: Params):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
runtime = RuntimeParams(params)
|
runtime = RuntimeParams(params)
|
||||||
rotating = amplitudes * np.exp(-1j * runtime.detuned_Ωs * t)
|
rotating = amplitudes * np.exp(-1j * runtime.detuned_Ωs[:, None] * t)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
np.sum(rotating, axis=0)
|
np.sum(rotating, axis=0)
|
||||||
|
|
Loading…
Add table
Reference in a new issue