Skip to content

Commit b659d58

Browse files
committed
Adding script for running lab frame simulation.
1 parent 3dd83ff commit b659d58

File tree

2 files changed

+365
-0
lines changed

2 files changed

+365
-0
lines changed

cnot3_labframe/cnot3_labframe.jl

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#=
2+
# Script for testing that setting up cnot3 matches the results of juqbox.
3+
# (which I assume to be correct)
4+
=#
5+
6+
using QuantumGateDesign, DelimitedFiles
7+
using LinearAlgebra: Symmetric
8+
9+
N_osc_levels = 10
10+
Tmax = 550.0
11+
nsteps = 1000
12+
13+
subsystem_sizes = (N_osc_levels, 4, 4)
14+
essential_subsystem_sizes = (1, 2, 2)
15+
16+
fa = 4.10595
17+
fb = 4.81526
18+
fs = 7.8447
19+
xa = 2 * 0.1099
20+
xb = 2 * 0.1126
21+
xs = 0.002494^2/xa
22+
xab = 1.0e-6
23+
xas = sqrt(xa*xs)
24+
xbs = sqrt(xb*xs)
25+
26+
transition_freqs = (fs, fb, fa)
27+
rotation_freqs = transition_freqs # Rotating Frame
28+
29+
kerr_coeffs = Symmetric(
30+
[xs xbs xas;
31+
xbs xb xab;
32+
xas xab xa],
33+
:U
34+
)
35+
36+
37+
prob_rot = dispersive_qudits_problem(
38+
subsystem_sizes,
39+
essential_subsystem_sizes,
40+
transition_freqs,
41+
rotation_freqs,
42+
kerr_coeffs,
43+
Tmax,
44+
nsteps,
45+
rot_frame=true,
46+
gmres_abstol=1e-15,
47+
gmres_reltol=1e-15,
48+
)
49+
50+
prob_lab = dispersive_qudits_problem(
51+
subsystem_sizes,
52+
essential_subsystem_sizes,
53+
transition_freqs,
54+
rotation_freqs,
55+
kerr_coeffs,
56+
Tmax,
57+
nsteps,
58+
rot_frame=false,
59+
gmres_abstol=1e-15,
60+
gmres_reltol=1e-15,
61+
)
62+
63+
rot_op_T = compsys_rot_frame_op(rotation_freqs, subsystem_sizes, Tmax)
64+
65+
lab_target = (prob_lab.u0 + im.*prob_lab.v0)*CNOT_gate()
66+
rot_target = rot_op_T*lab_target
67+
68+
seed=0
69+
atol=1e-15
70+
rtol=1e-15
71+
degree = 14
72+
D1 = 15
73+
74+
cnot3ret = QuantumGateDesign.setup_cnot3(
75+
seed=seed,
76+
atol=atol,
77+
rtol=rtol,
78+
D1=D1,
79+
N_osc_levels=N_osc_levels,
80+
Tmax=Tmax
81+
)
82+
83+
Nctrl = 3
84+
Nfreq = 3
85+
Cfreq = zeros(Nctrl,Nfreq)
86+
Cfreq[1:2,2] .= -2.0*pi*xa # carrier freq's for ctrl Hamiltonian 1 & 2
87+
Cfreq[1:2,3] .= -2.0*pi*xb # carrier freq's for ctrl Hamiltonian 1 & 2
88+
Cfreq[3,2] = -2.0*pi*xas # carrier freq 2 for ctrl Hamiltonian #3
89+
Cfreq[3,3] = -2.0*pi*xbs # carrier freq 2 for ctrl Hamiltonian #3
90+
91+
Cfreq_lab_shift = repeat(collect(rotation_freqs), 1, Nfreq) .* 2.0*pi
92+
Cfreq_lab = Cfreq .+ Cfreq_lab_shift
93+
94+
rot_controls = get_controls(degree, D1, Cfreq, Tmax)
95+
lab_controls = [DoubleRealPartControl(control)
96+
for control in get_controls(degree, D1, Cfreq_lab, Tmax)]
97+
98+
# Alternative implementation, which should be slower
99+
lab_controls2 = [LabFrameControl(rot_controls[i], 2.0*pi*rotation_freqs[i])
100+
for i in 1:3]
101+
102+
pcof_csv = readdlm("targetError=1e-7_cnot3OptimizationTest_order=6_degree=14_seed=5_nsteps=5409_atol=1.0e-15_rtol=1.0e-15_D1=16_time=6.0_maxiter=10000_nthreads=4_costType=GeneralizedInfidelity_gateDuration=550.0_nCavityLevels=10_pcof.csv", ',')
103+
pcof = pcof_csv[end,:]
104+
# Dummy run to compile
105+
prob_rot.nsteps = 1
106+
prob_lab.nsteps = 1
107+
history_rot = eval_forward(prob_rot, rot_controls, pcof, order=6)
108+
history_lab = eval_forward(prob_lab, lab_controls, pcof, order=6)
109+
110+
# Actual run
111+
prob_rot.nsteps = 100
112+
prob_lab.nsteps = 100
113+
#@time history_rot = eval_forward(prob_rot, rot_controls, pcof, order=6)
114+
@time history_lab = eval_forward(prob_lab, lab_controls, pcof, order=6)
115+
116+
117+
include("stepsize_copy.jl")
118+
order = 6
119+
max_walltime = 1 # In hours
120+
filename_base = "lab_frame"
121+
nsaves = 10
122+
initial_nsteps = 50_000 # Nyquist limit should be about here
123+
collect_data(prob_lab, lab_controls, pcof, order, max_walltime, filename_base,
124+
nsaves, initial_nsteps)

cnot3_labframe/stepsize_copy.jl

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
#==========================================
2+
# Copy of the data collection functions from the cnot3 stepsize test
3+
==========================================#
4+
using QuantumGateDesign, DelimitedFiles
5+
6+
7+
function collect_data(prob::SchrodingerProb, controls::ControlsType,
8+
pcof::AbstractVector{<: Real}, order::Integer, max_walltime::Real,
9+
filename_base::AbstractString, N_timestep_saves::Integer, initial_nsteps=2
10+
)
11+
prob = copy(prob) # Copy problem, just to make sure there are no mutability issues.
12+
13+
initial_time = time()
14+
max_walltime *= 60*60 # convert walltime from hours to seconds
15+
16+
filename_csv = filename_base * ".csv"
17+
filename_final_states_csv = filename_base * "_finalStates.csv"
18+
19+
header = hcat(
20+
"nsteps", "stepsize", "elapsed_time", "avg_N_gmres_iter",
21+
"N_converged_gmres", "avg_gmres_residual", "max_gmres_residual",
22+
"R_abs_err_L1", "R_abs_err_L2", "R_rel_err_L1", "R_rel_err_L2",
23+
"R_abs_err_Linf",
24+
)
25+
println(stdout, header)
26+
27+
writedlm(filename_csv, rpad.(header, 24), ',')
28+
29+
final_states_vec = Vector{ComplexF64}(undef, length(prob.u0))
30+
final_states_vec .= NaN
31+
gmres_tracker = GMRESTracker()
32+
33+
# Run simulation
34+
prob.nsteps = initial_nsteps
35+
stepsize = prob.tf / prob.nsteps
36+
37+
# Run simulation once just to get compilation out of the way
38+
dummy_history = eval_forward(prob, controls, pcof, order=order)
39+
40+
is_first_step = true
41+
history_2h = nothing
42+
history_h = nothing
43+
elapsed_time = 0.0
44+
45+
# Loop until time runs out (with estimator for when we will go overtime on next simulation)
46+
while (time()-initial_time) < (max_walltime - 2*elapsed_time)
47+
# Run simulation
48+
t1 = time()
49+
history_h = eval_forward(prob, controls, pcof, order=order,
50+
gmres_tracker=gmres_tracker, verbose=true)
51+
t2 = time()
52+
elapsed_time = t2 - t1
53+
54+
# Collect data into a row
55+
if !is_first_step
56+
R = RichardsonExtrapolation(history_h[:,1:2:end,:], history_2h, order)
57+
csv_row = hcat(
58+
prob.nsteps, stepsize, elapsed_time,
59+
avg_N_iterations(gmres_tracker), gmres_tracker.N_converged,
60+
avg_residual(gmres_tracker), R.abs_err_L1, R.abs_err_L2,
61+
R.rel_err_L1, R.rel_err_L2, R.abs_err_Linf,
62+
)
63+
else
64+
csv_row = hcat(
65+
prob.nsteps, stepsize, elapsed_time,
66+
avg_N_iterations(gmres_tracker), gmres_tracker.N_converged,
67+
avg_residual(gmres_tracker), NaN, NaN, NaN, NaN, NaN,
68+
)
69+
is_first_step = false
70+
end
71+
72+
# Log data (CSV)
73+
open(filename_csv, "a+") do io
74+
writedlm(io, rpad.(csv_row, 24), ',')
75+
end
76+
final_states_vec .= reshape(history_h[:,end,:], :)
77+
open(filename_final_states_csv, "a+") do io
78+
writedlm(io, rpad.(transpose(final_states_vec), 53), ',')
79+
end
80+
println(stdout, csv_row) # Print row
81+
82+
# Prepare for next iteration
83+
history_2h = history_h
84+
prob.nsteps *= 2
85+
stepsize = prob.tf / prob.nsteps
86+
end
87+
88+
return readdlm(filename_csv, ',')
89+
end
90+
91+
92+
function collect_data_grad(prob::SchrodingerProb, controls::ControlsType,
93+
pcof::AbstractVector{<: Real}, target::AbstractMatrix{<: Number}, order::Integer, max_walltime::Real,
94+
filename_base::AbstractString, N_timestep_saves::Integer
95+
)
96+
prob = copy(prob) # Copy problem, just to make sure there are no mutability issues.
97+
98+
initial_time = time()
99+
max_walltime *= 60*60 # convert walltime from hours to seconds
100+
101+
filename_csv = filename_base * ".csv"
102+
filename_final_states_csv = filename_base * "_finalStates.csv"
103+
104+
header = hcat(
105+
"nsteps", "stepsize", "elapsed_time", "forward_time", "adjoint_time",
106+
"grad_accum_time", "avg_N_gmres_iter_fwd", "N_converged_gmres_fwd",
107+
"avg_gmres_residual_fwd", "avg_N_gmres_iter_adj", "N_converged_gmres_adj",
108+
"avg_gmres_residual_adj", "R_abs_err_L1", "R_abs_err_L2", "R_rel_err_L1",
109+
"R_rel_err_L2", "R_abs_err_Linf",
110+
)
111+
println(stdout, header)
112+
113+
writedlm(filename_csv, rpad.(header, 24), ',')
114+
115+
final_states_vec = Vector{ComplexF64}(undef, length(prob.u0))
116+
final_states_vec .= NaN
117+
118+
forward_gmres_tracker = GMRESTracker()
119+
adjoint_gmres_tracker = GMRESTracker()
120+
121+
# Run simulation
122+
prob.nsteps = 2
123+
stepsize = prob.tf / prob.nsteps
124+
125+
# Run simulation once just to get compilation out of the way
126+
dummy_history = eval_forward(prob, controls, pcof, order=order)
127+
128+
timer = QuantumGateDesign.DiscreteAdjointTimes()
129+
is_first_step = true
130+
history_2h = nothing
131+
history_h = nothing
132+
elapsed_time = 0.0
133+
N_derivatives = div(order,2)
134+
grad = zeros(get_number_of_control_parameters(controls))
135+
136+
# Loop until time runs out (with estimator for when we will go overtime on next simulation)
137+
while (time()-initial_time) < (max_walltime - 2*elapsed_time)
138+
# Run simulation
139+
history = zeros(prob.real_system_size, 1+N_derivatives, 1+prob.nsteps, prob.N_initial_conditions)
140+
lambda_history = zeros(prob.real_system_size, 1+N_derivatives, 1+prob.nsteps, prob.N_initial_conditions)
141+
adjoint_forcing = zeros(prob.real_system_size, 1+prob.nsteps, prob.N_initial_conditions)
142+
143+
QuantumGateDesign.discrete_adjoint!(
144+
grad, history, lambda_history, adjoint_forcing, prob, controls,
145+
pcof, target, order=order, timer=timer,
146+
forward_gmres_tracker=forward_gmres_tracker,
147+
adjoint_gmres_tracker=adjoint_gmres_tracker,
148+
)
149+
history_h = QuantumGateDesign.real_to_complex(history[:,1,:,:])
150+
151+
# Collect data into a row
152+
if !is_first_step
153+
R = RichardsonExtrapolation(history_h[:,1:2:end,:], history_2h, order)
154+
csv_row = hcat(
155+
prob.nsteps, stepsize, QuantumGateDesign.total_time(timer),
156+
timer.forward, timer.adjoint, timer.grad_accum,
157+
avg_N_iterations(forward_gmres_tracker),
158+
forward_gmres_tracker.N_converged,
159+
avg_residual(forward_gmres_tracker),
160+
avg_N_iterations(adjoint_gmres_tracker),
161+
adjoint_gmres_tracker.N_converged,
162+
avg_residual(adjoint_gmres_tracker), R.abs_err_L1,
163+
R.abs_err_L2, R.rel_err_L1, R.rel_err_L2, R.abs_err_Linf,
164+
)
165+
else
166+
# Rerun to update timing (now that precompilation is out of the way)
167+
QuantumGateDesign.discrete_adjoint!(
168+
grad, history, lambda_history, adjoint_forcing, prob, controls,
169+
pcof, target, order=order, timer=timer,
170+
forward_gmres_tracker=forward_gmres_tracker,
171+
adjoint_gmres_tracker=adjoint_gmres_tracker,
172+
)
173+
174+
csv_row = hcat(
175+
prob.nsteps, stepsize, QuantumGateDesign.total_time(timer),
176+
timer.forward, timer.adjoint, timer.grad_accum,
177+
avg_N_iterations(forward_gmres_tracker),
178+
forward_gmres_tracker.N_converged,
179+
avg_residual(forward_gmres_tracker),
180+
avg_N_iterations(adjoint_gmres_tracker),
181+
adjoint_gmres_tracker.N_converged,
182+
avg_residual(adjoint_gmres_tracker), NaN,
183+
NaN, NaN, NaN, NaN,
184+
)
185+
is_first_step = false
186+
end
187+
188+
# Log data (CSV)
189+
open(filename_csv, "a+") do io
190+
writedlm(io, rpad.(csv_row, 24), ',')
191+
end
192+
final_states_vec .= reshape(history_h[:,end,:], :)
193+
open(filename_final_states_csv, "a+") do io
194+
writedlm(io, rpad.(transpose(final_states_vec), 53), ',')
195+
end
196+
println(stdout, csv_row) # Print row
197+
198+
# Prepare for next iteration
199+
history_2h = history_h
200+
prob.nsteps *= 2
201+
stepsize = prob.tf / prob.nsteps
202+
end
203+
204+
return readdlm(filename_csv, ',')
205+
end
206+
207+
208+
209+
"""
210+
Turn state vector history into a row matrix with the correct number of timesteps
211+
saved, for putting into a csv file.
212+
213+
If the number of timesteps to be saved is greater than the number of timesteps
214+
in the provided history, use NaN in place of the 'missing' timestep saves
215+
"""
216+
function parse_history_for_csv(history::AbstractArray{ComplexF64, 3}, N_timestep_saves::Union{Missing, Integer})
217+
if ismissing(N_timestep_saves)
218+
return copy(reshape(history, 1, :))
219+
end
220+
221+
parsed_history = Array{ComplexF64, 3}(undef, size(history, 1), 1+N_timestep_saves, size(history, 3))
222+
parsed_history .= NaN
223+
224+
nsteps = size(history, 2) - 1
225+
226+
if nsteps >= N_timestep_saves
227+
if (nsteps % N_timestep_saves != 0)
228+
throw(ArgumentError("Number of timesteps to save ($N_timestep_saves) does not divide the number of timesteps ($nsteps)"))
229+
end
230+
stride = div(nsteps, N_timestep_saves)
231+
parsed_history .= history[:,1:stride:end,:]
232+
else
233+
if (N_timestep_saves % nsteps != 0)
234+
throw(ArgumentError("Number of timesteps ($nsteps) does not divide the number of timesteps to save ($N_timestep_saves)"))
235+
end
236+
stride = div(N_timestep_saves, nsteps)
237+
parsed_history[:,1:stride:end,:] .= history
238+
end
239+
240+
return reshape(parsed_history, 1, :)
241+
end

0 commit comments

Comments
 (0)