Skip to content

Commit 5de07e8

Browse files
Improve code quality tests
1 parent f5392ee commit 5de07e8

14 files changed

+330
-140
lines changed

src/QuantumToolbox.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ import DiffEqNoiseProcess: RealWienerProcess!
6060
# other dependencies (in alphabetical order)
6161
import ArrayInterface: allowed_getindex, allowed_setindex!
6262
import Distributed: RemoteChannel
63-
import FFTW: fft, ifft, fftfreq, fftshift
63+
import FFTW: fft, ifft, fftfreq, fftshift, unsafe_destroy_plan
6464
import Graphs: connected_components, DiGraph
6565
import IncompleteLU: ilu
6666
import Pkg

src/correlations.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ function correlation_3op_2t(
5757
kwargs2 = merge((saveat = collect(tlist),), (; kwargs...))
5858
ρt_list = mesolve(L, ψ0, tlist; kwargs2...).states
5959

60-
corr = map((t, ρt) -> mesolve(L, C * ρt * A, τlist .+ t, e_ops = [B]; kwargs...).expect[1, :], tlist, ρt_list)
60+
corr = Matrix{eltype(ψ0)}(undef, length(tlist), length(τlist))
61+
foreach(enumerate(tlist)) do (j, t)
62+
return corr[j, :] .= mesolve(L, C * ρt_list[j] * A, τlist .+ t, e_ops = [B]; kwargs...).expect[1, :]
63+
end
6164

62-
# make the output correlation Matrix align with QuTiP
63-
# 1st dimension corresponds to tlist
64-
# 2nd dimension corresponds to τlist
65-
return reduce(vcat, transpose.(corr))
65+
return corr
6666
end
6767

6868
@doc raw"""

src/spectrum.jl

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -127,47 +127,47 @@ function _spectrum(
127127
_tr = SparseVector(D^2, [1 + n * (D + 1) for n in 0:(D-1)], ones(_CType(L), D)) # same as vec(system_identity_matrix)
128128
_tr_A = transpose(_tr) * spre(A).data
129129

130-
cache = nothing
131130
I_cache = I(D^2)
131+
132+
ω = popfirst!(ωList)
133+
cache = init(LinearProblem(L.data - 1im * ω * I_cache, b), solver.alg, kwargs...)
134+
sol = solve!(cache)
135+
spec[1] = -2 * real(dot(_tr_A, sol.u))
136+
132137
for (idx, ω) in enumerate(ωList)
133-
if idx == 1
134-
cache = init(LinearProblem(L.data - 1im * ω * I_cache, b), solver.alg, kwargs...)
135-
sol = solve!(cache)
136-
else
137-
cache.A = L.data - 1im * ω * I_cache
138-
sol = solve!(cache)
139-
end
138+
cache.A = L.data - 1im * ω * I_cache
139+
sol = solve!(cache)
140140

141141
# trace over the Hilbert space of system (expectation value)
142-
spec[idx] = -2 * real(dot(_tr_A, sol.u))
142+
spec[idx+1] = -2 * real(dot(_tr_A, sol.u))
143143
end
144144

145145
return spec
146146
end
147147

148148
@doc raw"""
149-
spectrum_correlation_fft(tlist, corr; inverse=false)
149+
spectrum_correlation_fft(tlist, corr; inverse=Val(false))
150150
151151
Calculate the power spectrum corresponding to a two-time correlation function using fast Fourier transform (FFT).
152152
153153
# Parameters
154154
- `tlist::AbstractVector`: List of times at which the two-time correlation function is given.
155155
- `corr::AbstractVector`: List of two-time correlations corresponding to the given time point in `tlist`.
156-
- `inverse::Bool`: Whether to use the inverse Fourier transform or not. Default to `false`.
156+
- `inverse::Union{Val,Bool}`: Whether to use the inverse Fourier transform or not. Default to `Val(false)`.
157157
158158
# Returns
159159
- `ωlist`: the list of angular frequencies ``\omega``.
160160
- `Slist`: the list of the power spectrum corresponding to the angular frequencies in `ωlist`.
161161
"""
162-
function spectrum_correlation_fft(tlist::AbstractVector, corr::AbstractVector; inverse::Bool = false)
162+
function spectrum_correlation_fft(tlist::AbstractVector, corr::AbstractVector; inverse::Union{Val,Bool} = Val(false))
163163
N = length(tlist)
164164
dt_list = diff(tlist)
165165
dt = dt_list[1]
166166

167167
all((dt), dt_list) || throw(ArgumentError("tlist must be equally spaced for FFT."))
168168

169169
# power spectrum list
170-
F = inverse ? N * ifft(corr) : fft(corr)
170+
F = getVal(inverse) ? N * ifft(corr) : fft(corr)
171171
Slist = 2 * dt * real(fftshift(F))
172172

173173
# angular frequency list

src/steadystate.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ function _steadystate(
167167
Tn = sparse(rows, cols, vals, N^2, N^2)
168168
L_tmp = L_tmp + Tn
169169

170-
ρss_vec = L_tmp \ v0 # This is still not supported on GPU, yet
170+
fac = lu(L_tmp)
171+
ρss_vec = fac \ v0 # This is still not supported on GPU, yet
171172
ρss = reshape(ρss_vec, N, N)
172173
ρss = (ρss + ρss') / 2 # Hermitianize
173174
return QuantumObject(ρss, Operator, L.dims)

src/time_evolution/mesolve.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ function mesolveProblem(
7676
check_dims(L_evo, ψ0)
7777

7878
T = Base.promote_eltype(L_evo, ψ0)
79+
7980
ρ0 = sparse_to_dense(_CType(T), mat2vec(ket2dm(ψ0).data)) # Convert it to dense vector with complex element type
8081
L = L_evo.data
8182

test/code-quality/code_quality.jl

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
@testset "Code quality" verbose = true begin
2+
@testset "Aqua.jl" begin
3+
Aqua.test_all(QuantumToolbox; ambiguities = false, unbound_args = false)
4+
end
5+
6+
@testset "JET.jl" begin
7+
# JET.test_package(QuantumToolbox; target_defined_modules = true, ignore_missing_comparison = true)
8+
9+
include("workload.jl")
10+
11+
# Here we define some functins to exclude from the JET test
12+
13+
# Related to the `check_error` function inside the `integrator` interface
14+
sci_ml_integrator_functions = (
15+
Base.modulesof!,
16+
Base.show,
17+
Base.show_at_namedtuple,
18+
Base.show_typealias,
19+
Base._show_type,
20+
Base.isvisible,
21+
Base.eltype,
22+
)
23+
24+
# Related to FFTW.jl
25+
fftw_functions = (QuantumToolbox.unsafe_destroy_plan,)
26+
27+
function_filter(@nospecialize f) = f (sci_ml_integrator_functions..., fftw_functions...)
28+
29+
@test_opt function_filter = function_filter run_all_functions()
30+
end
31+
end

test/code-quality/workload.jl

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
function run_all_functions()
2+
# block diagonal form
3+
run_block_diagonal_form()
4+
5+
# correlations and spectrum
6+
run_correlations_and_spectrum()
7+
8+
# dynamical fock dimension
9+
# run_dynamical_fock_dimension() # TODO: fix type instabilities here
10+
11+
# dynamical shifted fock
12+
# run_dynamical_shifted_fock() # TODO: fix type instabilities here
13+
14+
return nothing
15+
end
16+
17+
#=
18+
Block Diagonal Form
19+
=#
20+
function run_block_diagonal_form()
21+
H, c_ops, a = driven_dissipative_kerr()
22+
L = liouvillian(H, c_ops)
23+
24+
bdf = block_diagonal_form(L)
25+
26+
return nothing
27+
end
28+
29+
#=
30+
Correlations and Spectrum
31+
=#
32+
function run_correlations_and_spectrum()
33+
N = 10
34+
H, c_ops, a = driven_dissipative_harmonic_oscillator(nth = 0.01, N = N)
35+
36+
t_l = range(0, 333 * π, length = 1000)
37+
corr1 = correlation_2op_1t(H, nothing, t_l, c_ops, a', a; progress_bar = Val(false))
38+
corr2 = correlation_3op_1t(H, nothing, t_l, c_ops, qeye(a.dims[1]), a', a; progress_bar = Val(false))
39+
ω_l1, spec1 = spectrum_correlation_fft(t_l, corr1)
40+
41+
ω_l2 = range(0, 3, length = 1000)
42+
spec2 = spectrum(H, ω_l2, c_ops, a', a)
43+
# spec3 = spectrum(H, ω_l2, c_ops, a', a; solver = PseudoInverse())
44+
45+
return nothing
46+
end
47+
48+
#=
49+
Dynamical Fock Dimension
50+
=#
51+
function run_dynamical_fock_dimension()
52+
t_l = range(0, 15, length = 100)
53+
54+
# Single mode
55+
F, Δ, κ = 5, 0.25, 1
56+
57+
maxdims = [150]
58+
ψ0 = fock(3, 0)
59+
dfd_params == Δ, F = F, κ = κ)
60+
sol = dfd_mesolve(H_dfd1, ψ0, t_l, c_ops_dfd1, maxdims, dfd_params, e_ops = e_ops_dfd1, progress_bar = Val(false))
61+
62+
# Two modes
63+
F, Δ, κ, J = 1.5, 0.25, 1, 0.05
64+
65+
maxdims = [50, 50]
66+
ψ0 = kron(fock(3, 0), fock(20, 15))
67+
dfd_params == Δ, F = F, κ = κ, J = J)
68+
sol = dfd_mesolve(H_dfd2, ψ0, t_l, c_ops_dfd2, maxdims, dfd_params, e_ops = e_ops_dfd2, progress_bar = Val(false))
69+
70+
return nothing
71+
end
72+
73+
#=
74+
Dynamical Shifted Fock
75+
=#
76+
function run_dynamical_shifted_fock()
77+
# Single mode
78+
F = 3
79+
Δ = 0.25
80+
κ = 1
81+
U = 0.01
82+
α0 = 1.5
83+
84+
tlist = range(0, 25, 300)
85+
86+
N = 5
87+
a = destroy(N)
88+
89+
op_list = [a]
90+
ψ0 = fock(N, 0)
91+
α0_l = [α0]
92+
dsf_params == Δ, F = F, κ = κ, U = U)
93+
94+
sol_dsf_me = dsf_mesolve(
95+
H_dsf,
96+
ψ0,
97+
tlist,
98+
c_ops_dsf,
99+
op_list,
100+
α0_l,
101+
dsf_params,
102+
e_ops = e_ops_dsf,
103+
progress_bar = Val(false),
104+
)
105+
sol_dsf_mc = dsf_mcsolve(
106+
H_dsf,
107+
ψ0,
108+
tlist,
109+
c_ops_dsf,
110+
op_list,
111+
α0_l,
112+
dsf_params,
113+
e_ops = e_ops_dsf,
114+
progress_bar = Val(false),
115+
ntraj = 500,
116+
)
117+
118+
# Two modes
119+
F = 2
120+
Δ = 0.25
121+
κ = 1
122+
U = 0.01
123+
J = 0.5
124+
tlist = range(0, 15, 300)
125+
126+
N = 5
127+
a1 = kron(destroy(N), qeye(N))
128+
a2 = kron(qeye(N), destroy(N))
129+
130+
op_list = [a1, a2]
131+
ψ0 = kron(fock(N, 0), fock(N, 0))
132+
α0_l = [α0, α0]
133+
dsf_params == Δ, F = F, κ = κ, U = U, J = J)
134+
135+
sol_dsf_me = dsf_mesolve(
136+
H_dsf2,
137+
ψ0,
138+
tlist,
139+
c_ops_dsf2,
140+
op_list,
141+
α0_l,
142+
dsf_params,
143+
e_ops = e_ops_dsf2,
144+
progress_bar = Val(false),
145+
)
146+
sol_dsf_mc = dsf_mcsolve(
147+
H_dsf2,
148+
ψ0,
149+
tlist,
150+
c_ops_dsf2,
151+
op_list,
152+
α0_l,
153+
dsf_params,
154+
e_ops = e_ops_dsf2,
155+
progress_bar = Val(false),
156+
ntraj = 500,
157+
)
158+
159+
return nothing
160+
end

test/core-test/block_diagonal_form.jl

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,5 @@
11
@testset "Block Diagonal Form" begin
2-
# Block Diagonal Form
3-
N = 20
4-
Δ = 0
5-
G = 5
6-
tg = 0
7-
θ = atan(tg)
8-
U = sin(θ)
9-
κ2 = cos(θ)
10-
κϕ = 1e-3
11-
nth = 0.0
12-
13-
a = destroy(N)
14-
ad = create(N)
15-
H = -Δ * ad * a + G / 2 * (ad^2 + a^2) + U / 2 * (ad^2 * a^2)
16-
c_ops = [(κ2) * a^2, (κϕ) * ad * a]
2+
H, c_ops, a = driven_dissipative_kerr()
173
L = liouvillian(H, c_ops)
184

195
bdf = block_diagonal_form(L)

test/core-test/code_quality.jl

Lines changed: 0 additions & 9 deletions
This file was deleted.

test/core-test/correlations_and_spectrum.jl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
@testset "Correlations and Spectrum" begin
22
N = 10
3+
H, c_ops, a = driven_dissipative_harmonic_oscillator(nth = 0.01, N = N)
34
Id = qeye(N)
4-
a = destroy(N)
5-
H = a' * a
6-
c_ops = [sqrt(0.1 * (0.01 + 1)) * a, sqrt(0.1 * (0.01)) * a']
75

86
t_l = range(0, 333 * π, length = 1000)
97
corr1 = correlation_2op_1t(H, nothing, t_l, c_ops, a', a; progress_bar = Val(false))

0 commit comments

Comments
 (0)