Skip to content

Commit cb2239e

Browse files
authored
Merge pull request #16 from numericalEFT/dev
Dev
2 parents cbd5e42 + 384cbfc commit cb2239e

File tree

11 files changed

+511
-444
lines changed

11 files changed

+511
-444
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "Lehmann"
22
uuid = "95bf888a-8996-4655-9f35-1c0506bdfefe"
33
authors = ["Kun Chen", "Tao Wang", "Xiansheng Cai"]
4-
version = "0.2.0"
4+
version = "0.2.1"
55

66
[deps]
77
DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab"

README.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ This package has been registered. So, simply type `import Pkg; Pkg.add("Lehmann"
3333
In the following [demo](example/demo.jl), we will show how to compress a Green's function of ~10000 data point into ~20 DLR coefficients, and perform fast interpolation and fourier transform up to the accuracy ~1e-10.
3434

3535
```julia
36+
using Lehmann
3637
β = 100.0 # inverse temperature
3738
Euv = 1.0 # ultraviolt energy cutoff of the Green's function
3839
rtol = 1e-8 # accuracy of the representation
@@ -41,9 +42,6 @@ symmetry = :none # :ph if particle-hole symmetric, :pha is antisymmetric, :none
4142

4243
diff(a, b) = maximum(abs.(a - b)) # return the maximum deviation between a and b
4344

44-
# Use semicircle spectral density to generate the sample Green's function
45-
sample(grid, type) = Sample.SemiCircle(Euv, β, isFermi, grid, type, symmetry)
46-
4745
dlr = DLRGrid(Euv, β, rtol, isFermi, symmetry) #initialize the DLR parameters and basis
4846
# A set of most representative grid points are generated:
4947
# dlr.ω gives the real-frequency grids
@@ -53,9 +51,9 @@ dlr = DLRGrid(Euv, β, rtol, isFermi, symmetry) #initialize the DLR parameters a
5351
println("Prepare the Green's function sample ...")
5452
Nτ, Nωn = 10000, 10000 # many τ and n points are needed because Gτ is quite singular near the boundary
5553
τgrid = collect(LinRange(0.0, β, Nτ)) # create a τ grid
56-
= sample(τgrid, )
54+
= Sample.SemiCircle(dlr, , τgrid) # Use semicircle spectral density to generate the sample Green's function in τ
5755
ngrid = collect(-Nωn:Nωn) # create a set of Matsubara-frequency points
58-
Gn = sample(ngrid, :ωn)
56+
Gn = Sample.SemiCircle(dlr, :n, ngrid) # Use semicircle spectral density to generate the sample Green's function in ωn
5957

6058
println("Compress Green's function into ~20 coefficients ...")
6159
spectral_from_Gτ = tau2dlr(dlr, Gτ, τgrid)
@@ -64,9 +62,9 @@ spectral_from_Gω = matfreq2dlr(dlr, Gn, ngrid)
6462

6563
println("Prepare the target Green's functions to benchmark with ...")
6664
τ = collect(LinRange(0.0, β, Nτ * 2)) # create a dense τ grid to interpolate
67-
Gτ_target = sample, )
65+
Gτ_target = Sample.SemiCircle(dlr, :τ, τ)
6866
n = collect(-2Nωn:2Nωn) # create a set of Matsubara-frequency points
69-
Gn_target = sample(n, :ωn)
67+
Gn_target = Sample.SemiCircle(dlr, :n, n)
7068

7169
println("Interpolation benchmark ...")
7270
Gτ_interp = dlr2tau(dlr, spectral_from_Gτ, τ)

example/Untitled.ipynb

Lines changed: 446 additions & 407 deletions
Large diffs are not rendered by default.

example/demo.jl

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ symmetry = :none # :ph if particle-hole symmetric, :pha is antisymmetric, :none
77

88
diff(a, b) = maximum(abs.(a - b)) # return the maximum deviation between a and b
99

10-
# Use semicircle spectral density to generate the sample Green's function
11-
sample(grid, type) = Sample.SemiCircle(Euv, β, isFermi, grid, type, symmetry)
12-
1310
dlr = DLRGrid(Euv, β, rtol, isFermi, symmetry) #initialize the DLR parameters and basis
1411
# A set of most representative grid points are generated:
1512
# dlr.ω gives the real-frequency grids
@@ -19,9 +16,9 @@ dlr = DLRGrid(Euv, β, rtol, isFermi, symmetry) #initialize the DLR parameters a
1916
println("Prepare the Green's function sample ...")
2017
Nτ, Nωn = 10000, 10000 # many τ and n points are needed because Gτ is quite singular near the boundary
2118
τgrid = collect(LinRange(0.0, β, Nτ)) # create a τ grid
22-
= sample(τgrid, )
19+
= Sample.SemiCircle(dlr, , τgrid) # Use semicircle spectral density to generate the sample Green's function in τ
2320
ngrid = collect(-Nωn:Nωn) # create a set of Matsubara-frequency points
24-
Gn = sample(ngrid, :ωn)
21+
Gn = Sample.SemiCircle(dlr, :n, ngrid) # Use semicircle spectral density to generate the sample Green's function in ωn
2522

2623
println("Compress Green's function into ~20 coefficients ...")
2724
spectral_from_Gτ = tau2dlr(dlr, Gτ, τgrid)
@@ -30,9 +27,9 @@ spectral_from_Gω = matfreq2dlr(dlr, Gn, ngrid)
3027

3128
println("Prepare the target Green's functions to benchmark with ...")
3229
τ = collect(LinRange(0.0, β, Nτ * 2)) # create a dense τ grid to interpolate
33-
Gτ_target = sample, )
30+
Gτ_target = Sample.SemiCircle(dlr, :τ, τ)
3431
n = collect(-2Nωn:2Nωn) # create a set of Matsubara-frequency points
35-
Gn_target = sample(n, :ωn)
32+
Gn_target = Sample.SemiCircle(dlr, :n, n)
3633

3734
println("Interpolation benchmark ...")
3835
Gτ_interp = dlr2tau(dlr, spectral_from_Gτ, τ)

example/demo1.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ d = DLRGrid(Euv = 1.0, β = 1000.0, rtol = 1e-14, isFermi = false) # Initialize
66
tau_k = d.τ # DLR imaginary time points
77

88
println("Prepare the Green's function sample ...")
9-
G_k = Sample.SemiCircle(d.Euv, d.β, d.isFermi, tau_k, ) # Evaluate known G at tau_k
9+
G_k = Sample.SemiCircle(d, , tau_k) # Evaluate known G at tau_k
1010
G_x = tau2dlr(d, G_k) # DLR coeffs from G_k
1111

1212
println("Interpolate imaginary-time Green's function ...")
1313
tau_i = collect(LinRange(0, d.β, 40)) # Equidistant tau grid
1414
G_i = dlr2tau(d, G_x, tau_i) # Evaluate DLR at tau_i
1515

16-
G_s = Sample.SemiCircle(d.Euv, d.β, d.isFermi, tau_i, ) # Evaluate known G at tau_k
16+
G_s = Sample.SemiCircle(d, , tau_i) # Evaluate known G at tau_k
1717

1818
diff(a, b) = maximum(abs.(a - b)) # return the maximum deviation between a and b
1919
println("Maximum difference: ", diff(G_i, G_s))

example/demo2.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ d = DLRGrid(Euv = 1.0, β = 1000.0, isFermi = false) # Initialize DLR object
1010
tau_i = collect(LinRange(0, d.β, 100))
1111

1212
println("Prepare the Green's function sample ...")
13-
G_i = Sample.SemiCircle(d.Euv, d.β, d.isFermi, tau_i, ) # Evaluate known G at tau_k
13+
G_i = Sample.SemiCircle(d, , tau_i) # Evaluate known G at tau_k
1414
# G_i = true_G_tau(tau_i, beta)
1515

1616
G_i_noisy = G_i .+ eta .* (rand(length(G_i)) .- 0.5)

example/demo3.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ function syk_sigma_dlr(d, G_x, J = 1.0)
4747
return Sigma_x
4848
end
4949

50-
function solve_syk_with_fixpoint_iter(d, mu, tol = d.rtol; mix = 0.3, maxiter = 5, G_x = zeros(ComplexF64, length(d)))
50+
function solve_syk_with_fixpoint_iter(d, mu, tol = d.rtol; mix = 0.1, maxiter = 1000, G_x = zeros(ComplexF64, length(d)))
5151

5252
for iter in 1:maxiter
5353

@@ -62,7 +62,7 @@ function solve_syk_with_fixpoint_iter(d, mu, tol = d.rtol; mix = 0.3, maxiter =
6262
G_q_new = -1 ./ (d.ωn * 1im .- mu .+ tau2matfreq(d, Sigma_x))
6363
+1 ./ (-d.ωn * 1im .- mu .+ tau2matfreq(d, Sigma_x)) # Solve Dyson
6464

65-
G_x_new = (matfreq2tau(d, G_q_new))
65+
G_x_new = matfreq2tau(d, G_q_new)
6666

6767
println("imag", maximum(abs.(imag.(G_x_new))))
6868

@@ -77,7 +77,7 @@ function solve_syk_with_fixpoint_iter(d, mu, tol = d.rtol; mix = 0.3, maxiter =
7777
end
7878

7979
d = DLRGrid(Euv = 5.0, β = 1000.0, isFermi = true, rtol = 1e-10, symmetry = :ph) # Initialize DLR object
80-
G_q = solve_syk_with_fixpoint_iter(d, 0.0)
80+
G_q = solve_syk_with_fixpoint_iter(d, 0.00)
8181
# G_q = solve_syk_with_fixpoint_iter(d, 0.15, G_x = G_q)
8282
# G_q = solve_syk_with_fixpoint_iter(d, 0.12, G_x = G_q)
8383
# G_q = solve_syk_with_fixpoint_iter(d, 0.11, G_x = G_q)

src/operation.jl

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,16 @@ function _weightedLeastSqureFit(Gτ, error, kernel)
5252
C =
5353
else
5454
@assert size(error) == size(Gτ)
55-
for i = 1:size(error)[1]
56-
error[i, :] /= sum(error[i, :]) / length(error[i, :])
55+
w = 1.0 ./ (error .+ 1e-16)
56+
57+
for i = 1:size(w)[1]
58+
w[i, :] /= sum(w[i, :]) / length(w[i, :])
5759
end
5860

5961
# W = Diagonal(weight)
6062
# B = transpose(kernel) * W * kernel
6163
# C = transpose(kernel) * W * Gτ
62-
w = 1.0 ./ error
64+
# w = 1.0 ./ (error .+ 1e-16)
6365
B = w .* kernel
6466
# B = Diagonal(w) * kernel
6567
C = w .*
@@ -99,6 +101,11 @@ function tau2dlr(dlrGrid::DLRGrid, green, τGrid = dlrGrid.τ; error = nothing,
99101
error, psize = _tensor2matrix(error, axis)
100102
end
101103
coeff = _weightedLeastSqureFit(g, error, kernel)
104+
105+
if all(abs.(coeff) .< 1e16) == false
106+
@warn("Some of the DLR coefficients are larger than 1e16. The quality of DLR fitting could be bad.")
107+
end
108+
102109
return _matrix2tensor(coeff, partialsize, axis)
103110
end
104111

@@ -159,6 +166,9 @@ function matfreq2dlr(dlrGrid::DLRGrid, green, nGrid = dlrGrid.n; error = nothing
159166
error, psize = _tensor2matrix(error, axis)
160167
end
161168
coeff = _weightedLeastSqureFit(g, error, kernel)
169+
if all(abs.(coeff) .< 1e16) == false
170+
@warn("Some of the DLR coefficients are larger than 1e16. The quality of DLR fitting could be bad.")
171+
end
162172
return _matrix2tensor(coeff, partialsize, axis)
163173
end
164174

src/sample/sample.jl

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,18 @@ using FastGaussQuadrature
33
using ..Spectral
44
"""
55
SemiCircle(Euv, β, isFermi::Bool, Grid, type::Symbol, symmetry::Symbol = :none; rtol = nothing, degree = 24, regularized::Bool = true)
6+
SemiCircle(dlr, type::Symbol, Grid = dlrGrid(dlr, type); degree = 24, regularized::Bool = true)
67
78
Generate Green's function from a semicircle spectral density.
89
Return the function on Grid and the systematic error.
910
1011
#Arguments
12+
- `dlr`: dlrGrid struct
1113
- `Euv` : ultraviolet energy cutoff
1214
- `β` : inverse temperature
1315
- `isFermi`: is fermionic or bosonic
1416
- `Grid`: grid to evalute on
15-
- `type`: imaginary-time with :τ, or Matsubara-frequency with :ωn
17+
- `type`: imaginary-time with :τ, or Matsubara-frequency with :n
1618
- `symmetry`: particle-hole symmetric :ph, particle-hole antisymmetric :pha, or :none
1719
- `rtol`: accuracy to achieve
1820
- `degree`: polynomial degree for integral
@@ -23,10 +25,10 @@ function SemiCircle(Euv, β, isFermi::Bool, Grid, type::Symbol, symmetry::Symbol
2325
# S(ω) = sqrt(1 - (ω / Euv)^2) / Euv # semicircle -1<ω<1
2426
if type ==
2527
IsMatFreq = false
26-
elseif type == :ωn
28+
elseif type == :n
2729
IsMatFreq = true
2830
else
29-
error("not implemented!")
31+
error("$type is not implemented!")
3032
end
3133

3234
##### Panels endpoints for composite quadrature rule ###
@@ -48,6 +50,20 @@ function SemiCircle(Euv, β, isFermi::Bool, Grid, type::Symbol, symmetry::Symbol
4850
end
4951
return g1
5052
end
53+
function SemiCircle(dlr, type::Symbol, Grid = dlrGrid(dlr, type); degree = 24, regularized::Bool = true)
54+
return SemiCircle(dlr.Euv, dlr.β, dlr.isFermi, Grid, type, dlr.symmetry; rtol = dlr.rtol, degree = degree, regularized = regularized)
55+
end
56+
57+
function dlrGrid(dlr, type::Symbol)
58+
if type ==
59+
return dlr.τ
60+
elseif type == :n
61+
return dlr.n
62+
else
63+
error("$type not implemented!")
64+
end
65+
end
66+
5167

5268
# function getG(::Val{true}, Grid)
5369
# return zeros(ComplexF64, length(Grid))
@@ -100,16 +116,18 @@ end
100116

101117
"""
102118
MultiPole(β, isFermi::Bool, symmetry::Symbol, Grid, type::Symbol, poles, regularized::Bool = true)
119+
MultiPole(dlr, type::Symbol, poles, Grid = dlrGrid(dlr, type); regularized::Bool = true)
103120
104121
Generate Green's function from a spectral density with delta peaks specified by the argument ``poles``.
105122
Return the function on Grid and the systematic error.
106123
107124
#Arguments
125+
- `dlr`: dlrGrid struct
108126
- `β` : inverse temperature
109127
- `isFermi`: is fermionic or bosonic
110128
- `symmetry`: particle-hole symmetric :ph, particle-hole antisymmetric :pha, or :none
111129
- `Grid`: grid to evalute on
112-
- `type`: imaginary-time with :τ, or Matsubara-frequency with :ωn
130+
- `type`: imaginary-time with :τ, or Matsubara-frequency with :n
113131
- `poles`: a list of frequencies for the delta functions
114132
- `regularized`: use regularized bosonic kernel if symmetry = :none
115133
"""
@@ -119,10 +137,10 @@ function MultiPole(β, isFermi::Bool, Grid, type::Symbol, poles, symmetry::Symbo
119137
# poles = [0.0]
120138
if type ==
121139
IsMatFreq = false
122-
elseif type == :ωn
140+
elseif type == :n
123141
IsMatFreq = true
124142
else
125-
error("not implemented!")
143+
error("$type is not implemented!")
126144
end
127145

128146
g = IsMatFreq ? zeros(ComplexF64, length(Grid)) : zeros(Float64, length(Grid))
@@ -143,5 +161,8 @@ function MultiPole(β, isFermi::Bool, Grid, type::Symbol, poles, symmetry::Symbo
143161
end
144162
return g
145163
end
164+
function MultiPole(dlr, type::Symbol, poles, Grid = dlrGrid(dlr, type); regularized::Bool = true)
165+
return MultiPole(dlr.β, dlr.isFermi, Grid, type, poles, dlr.symmetry; regularized = regularized)
166+
end
146167

147168
end

src/spectral.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Compute the imaginary-time kernel of different type.
3131
return isFermi ? kernelFermiT_PHA(τ, ω, β) : kernelBoseT_PHA(τ, ω, β)
3232
else
3333
@error "Symmetry $symmetry is not implemented!"
34-
return 0.0
34+
return T(0)
3535
end
3636
end
3737
"""
@@ -259,7 +259,7 @@ Compute the imaginary-time kernel of different type. Assume ``k_B T/\\hbar=1``
259259
return isFermi ? kernelFermiΩ_PHA(n, ω, β) : kernelBoseΩ_PHA(n, ω, β)
260260
else
261261
@error "Symmetry $symmetry is not implemented!"
262-
return 0.0
262+
return T(0)
263263
end
264264
end
265265

0 commit comments

Comments
 (0)