Skip to content

Commit dea0bd7

Browse files
Clean low-rank mesolve and add Documentation bibliography (#269)
* change Lattice structure * Change lr_mesolve and add documentation * Fix Documentation errors
1 parent 25bee9f commit dea0bd7

File tree

9 files changed

+447
-313
lines changed

9 files changed

+447
-313
lines changed

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
33
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
44
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
5+
DocumenterCitations = "daee34ce-89f3-4625-b898-19384cb65244"
56
QuantumToolbox = "6c2fb7c5-b903-41d2-bc5e-5a7c320b9fab"

docs/make.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33

44
using QuantumToolbox
55
using Documenter
6+
using DocumenterCitations
67

78
DocMeta.setdocmeta!(QuantumToolbox, :DocTestSetup, :(using QuantumToolbox); recursive = true)
89

910
const DRAFT = false # set `true` to disable cell evaluation
1011

12+
bib = CitationBibliography(joinpath(@__DIR__, "src", "bibliography.bib"), style=:authoryear)
13+
1114
const MathEngine = MathJax3(
1215
Dict(
1316
:loader => Dict("load" => ["[tex]/physics"]),
@@ -58,6 +61,7 @@ const PAGES = [
5861
],
5962
],
6063
"API" => "api.md",
64+
"Bibliography" => "bibliography.md",
6165
# "Change Log" => "changelog.md",
6266
]
6367

@@ -76,6 +80,7 @@ makedocs(;
7680
size_threshold_ignore = ["api.md"],
7781
),
7882
draft = DRAFT,
83+
plugins = [bib],
7984
)
8085

8186
deploydocs(; repo = "github.com/qutip/QuantumToolbox.jl", devbranch = "main")

docs/src/api.md

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -190,17 +190,18 @@ mcsolveProblem
190190
mcsolveEnsembleProblem
191191
ssesolveProblem
192192
ssesolveEnsembleProblem
193-
lr_mesolveProblem
194193
sesolve
195194
mesolve
196195
mcsolve
197196
ssesolve
198197
dfd_mesolve
199-
dsf_mesolve
200-
dsf_mcsolve
201-
lr_mesolve
202198
liouvillian
203199
liouvillian_generalized
200+
```
201+
202+
### [Steady State Solvers](@id doc-API:Steady-State-Solvers)
203+
204+
```@docs
204205
steadystate
205206
steadystate_floquet
206207
SteadyStateDirectSolver
@@ -209,6 +210,21 @@ SteadyStateLinearSolver
209210
SteadyStateODESolver
210211
```
211212

213+
### [Dynamical Shifted Fock method](@id doc-API:Dynamical-Shifted-Fock-method)
214+
215+
```@docs
216+
dsf_mesolve
217+
dsf_mcsolve
218+
```
219+
220+
### [Low-rank time evolution](@id doc-API:Low-rank-time-evolution)
221+
222+
```@docs
223+
TimeEvolutionLRSol
224+
lr_mesolveProblem
225+
lr_mesolve
226+
```
227+
212228
## [Correlations and Spectrum](@id doc-API:Correlations-and-Spectrum)
213229

214230
```@docs
@@ -227,6 +243,14 @@ tracedist
227243
fidelity
228244
```
229245

246+
## [Spin Lattice](@id doc-API:Spin-Lattice)
247+
248+
```@docs
249+
Lattice
250+
SingleSiteOperator
251+
DissipativeIsing
252+
```
253+
230254
## [Miscellaneous](@id doc-API:Miscellaneous)
231255

232256
```@docs
@@ -251,10 +275,4 @@ PhysicalConstants
251275
convert_unit
252276
row_major_reshape
253277
meshgrid
254-
_calculate_expectation!
255-
_adjM_condition_variational
256-
_adjM_affect!
257-
_adjM_condition_ratio
258-
_pinv!
259-
dBdz!
260278
```

docs/src/bibliography.bib

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
@article{gravina2024adaptive,
2+
title = {{Adaptive variational low-rank dynamics for open quantum systems}},
3+
author = {Gravina, Luca and Savona, Vincenzo},
4+
journal = {Phys. Rev. Res.},
5+
volume = {6},
6+
issue = {2},
7+
pages = {023072},
8+
numpages = {18},
9+
year = {2024},
10+
month = {Apr},
11+
publisher = {American Physical Society},
12+
doi = {10.1103/PhysRevResearch.6.023072},
13+
url = {https://link.aps.org/doi/10.1103/PhysRevResearch.6.023072}
14+
}

docs/src/bibliography.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
```@meta
2+
CurrentModule = QuantumToolbox
3+
```
4+
5+
# [Bibliography](@id doc:Bibliography)
6+
7+
```@bibliography
8+
```

docs/src/tutorials/lowrank.md

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# [Low rank master equation](@id doc-tutor:Low-rank-master-equation)
22

3+
In this tutorial, we will show how to solve the master equation using the low-rank method. For a detailed explaination of the method, we recommend to read the article [gravina2024adaptive](@cite).
4+
5+
As a test, we will consider the dissipative Ising model with a transverse field. The Hamiltonian is given by
6+
7+
```math
8+
\hat{H} = \frac{J_x}{2} \sum_{\langle i,j \rangle} \sigma_i^x \sigma_j^x + \frac{J_y}{2} \sum_{\langle i,j \rangle} \sigma_i^y \sigma_j^y + \frac{J_z}{2} \sum_{\langle i,j \rangle} \sigma_i^z \sigma_j^z - \sum_i h_i \sigma_i^z + h_x \sum_i \sigma_i^x + h_y \sum_i \sigma_i^y + h_z \sum_i \sigma_i^z,
9+
```
10+
11+
where the sums are over nearest neighbors, and the collapse operators are given by
12+
13+
```math
14+
c_i = \sqrt{\gamma} \sigma_i^-.
15+
```
16+
317
We start by importing the packages
418

519
```@example lowrank
@@ -21,42 +35,42 @@ Define lr-space dimensions
2135
N_cut = 2 # Number of states of each mode
2236
N_modes = latt.N # Number of modes
2337
N = N_cut^N_modes # Total number of states
24-
M = Nx * Ny + 1 # Number of states in the LR basis
38+
M = latt.N + 1 # Number of states in the LR basis
2539
```
2640

2741
Define lr states. Take as initial state all spins up. All other N states are taken as those with miniman Hamming distance to the initial state.
2842

2943
```@example lowrank
30-
ϕ = Vector{QuantumObject{Vector{ComplexF64},KetQuantumObject}}(undef, M)
31-
ϕ[1] = kron(repeat([basis(2, 0)], N_modes)...)
44+
ϕ = Vector{QuantumObject{Vector{ComplexF64},KetQuantumObject,M-1}}(undef, M)
45+
ϕ[1] = kron(fill(basis(2, 1), N_modes)...)
3246
33-
global i = 1
47+
i = 1
3448
for j in 1:N_modes
3549
global i += 1
36-
i <= M && (ϕ[i] = mb(sp, j, latt) * ϕ[1])
50+
i <= M && (ϕ[i] = SingleSiteOperator(sigmap(), j, latt) * ϕ[1])
3751
end
3852
for k in 1:N_modes-1
3953
for l in k+1:N_modes
4054
global i += 1
41-
i <= M && (ϕ[i] = mb(sp, k, latt) * mb(sp, l, latt) * ϕ[1])
55+
i <= M && (ϕ[i] = SingleSiteOperator(sigmap(), k, latt) * SingleSiteOperator(sigmap(), l, latt) * ϕ[1])
4256
end
4357
end
4458
for i in i+1:M
4559
ϕ[i] = QuantumObject(rand(ComplexF64, size(ϕ[1])[1]), dims = ϕ[1].dims)
4660
normalize!(ϕ[i])
4761
end
62+
nothing # hide
4863
```
4964

5065
Define the initial state
5166

5267
```@example lowrank
53-
z = hcat(broadcast(x -> x.data, ϕ)...)
54-
p0 = 0.0 # Population of the lr states other than the initial state
55-
B = Matrix(Diagonal([1 + 0im; p0 * ones(M - 1)]))
68+
z = hcat(get_data.(ϕ)...)
69+
B = Matrix(Diagonal([1 + 0im; zeros(M - 1)]))
5670
S = z' * z # Overlap matrix
5771
B = B / tr(S * B) # Normalize B
5872
59-
ρ = QuantumObject(z * B * z', dims = ones(Int, N_modes) * N_cut); # Full density matrix
73+
ρ = QuantumObject(z * B * z', dims = ntuple(i->N_cut, Val(N_modes))); # Full density matrix
6074
```
6175

6276
Define the Hamiltonian and collapse operators
@@ -67,26 +81,26 @@ Jx = 0.9
6781
Jy = 1.04
6882
Jz = 1.0
6983
hx = 0.0
84+
hy = 0.0
85+
hz = 0.0
7086
γ = 1
7187
72-
Sx = sum([mb(sx, i, latt) for i in 1:latt.N])
73-
Sy = sum([mb(sy, i, latt) for i in 1:latt.N])
74-
Sz = sum([mb(sz, i, latt) for i in 1:latt.N])
75-
SFxx = sum([mb(sx, i, latt) * mb(sx, j, latt) for i in 1:latt.N for j in 1:latt.N])
88+
Sx = mapreduce(i->SingleSiteOperator(sigmax(), i, latt), +, 1:latt.N)
89+
Sy = mapreduce(i->SingleSiteOperator(sigmay(), i, latt), +, 1:latt.N)
90+
Sz = mapreduce(i->SingleSiteOperator(sigmaz(), i, latt), +, 1:latt.N)
7691
77-
H, c_ops = TFIM(Jx, Jy, Jz, hx, γ, latt; bc = pbc, order = 1)
78-
e_ops = (Sx, Sy, Sz, SFxx)
92+
H, c_ops = DissipativeIsing(Jx, Jy, Jz, hx, hy, hz, γ, latt; boundary_condition = Val(:periodic_bc), order = 1)
93+
e_ops = (Sx, Sy, Sz)
7994
80-
tl = LinRange(0, 10, 100);
95+
tl = range(0, 10, 100)
96+
nothing # hide
8197
```
8298

8399
### Full evolution
84100

85101
```@example lowrank
86-
@time mesol = mesolve(H, ρ, tl, c_ops; e_ops = [e_ops...]);
87-
A = Matrix(mesol.states[end].data)
88-
λ = eigvals(Hermitian(A))
89-
Strue = -sum(λ .* log2.(λ)) / latt.N;
102+
sol_me = mesolve(H, ρ, tl, c_ops; e_ops = [e_ops...]);
103+
Strue = entropy_vn(sol_me.states[end], base=2) / latt.N
90104
```
91105

92106
### Low Rank evolution
@@ -120,26 +134,23 @@ function f_entropy(p, z, B)
120134
121135
mul!(C, z, sqrt(B))
122136
mul!(σ, C', C)
123-
λ = eigvals(Hermitian(σ))
124-
λ = λ[λ.>1e-10]
125-
return -sum(λ .* log2.(λ))
126-
end;
137+
return entropy_vn(Qobj(Hermitian(σ), type=Operator), base=2)
138+
end
127139
```
128140

129141
Define the options for the low-rank evolution
130142

131143
```@example lowrank
132-
opt =
133-
LRMesolveOptions(err_max = 1e-3, p0 = 0.0, atol_inv = 1e-6, adj_condition = "variational", Δt = 0.0);
144+
opt = (err_max = 1e-3, p0 = 0.0, atol_inv = 1e-6, adj_condition = "variational", Δt = 0.0);
134145
135-
@time lrsol = lr_mesolve(H, z, B, tl, c_ops; e_ops = e_ops, f_ops = (f_purity, f_entropy, f_trace), opt = opt);
146+
sol_lr = lr_mesolve(H, z, B, tl, c_ops; e_ops = e_ops, f_ops = (f_purity, f_entropy, f_trace), opt = opt);
136147
```
137148

138149
Plot the results
139150

140151
```@example lowrank
141-
m_me = real(mesol.expect[3, :]) / Nx / Ny
142-
m_lr = real(lrsol.expvals[3, :]) / Nx / Ny
152+
m_me = real(sol_me.expect[3, :]) / Nx / Ny
153+
m_lr = real(sol_lr.expect[3, :]) / Nx / Ny
143154
144155
fig = Figure(size = (500, 350), fontsize = 15)
145156
ax = Axis(fig[1, 1], xlabel = L"\gamma t", ylabel = L"M_{z}", xlabelsize = 20, ylabelsize = 20)
@@ -148,17 +159,17 @@ lines!(ax, tl, m_me, label = "Fock", linewidth = 2, linestyle = :dash)
148159
axislegend(ax, position = :rb)
149160
150161
ax2 = Axis(fig[1, 2], xlabel = L"\gamma t", ylabel = "Value", xlabelsize = 20, ylabelsize = 20)
151-
lines!(ax2, tl, 1 .- real(lrsol.funvals[1, :]), label = L"$1-P$", linewidth = 2)
162+
lines!(ax2, tl, 1 .- real(sol_lr.fexpect[1, :]), label = L"$1-P$", linewidth = 2)
152163
lines!(
153164
ax2,
154165
tl,
155-
1 .- real(lrsol.funvals[3, :]),
166+
1 .- real(sol_lr.fexpect[3, :]),
156167
label = L"$1-\mathrm{Tr}(\rho)$",
157168
linewidth = 2,
158169
linestyle = :dash,
159170
color = :orange,
160171
)
161-
lines!(ax2, tl, real(lrsol.funvals[2, :]) / Nx / Ny, color = :blue, label = L"S", linewidth = 2)
172+
lines!(ax2, tl, real(sol_lr.fexpect[2, :]) / Nx / Ny, color = :blue, label = L"S", linewidth = 2)
162173
hlines!(ax2, [Strue], color = :blue, linestyle = :dash, linewidth = 2, label = L"S^{\,\mathrm{true}}_{\mathrm{ss}}")
163174
axislegend(ax2, position = :rb)
164175

0 commit comments

Comments
 (0)