Skip to content

Commit 94c687b

Browse files
committed
improve API, fix a bug
1 parent e63a872 commit 94c687b

File tree

7 files changed

+51
-31
lines changed

7 files changed

+51
-31
lines changed

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/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)

src/operation.jl

Lines changed: 5 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 .*

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

test/dlr.jl

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ using FastGaussQuadrature, Printf
22

33
rtol(x, y) = maximum(abs.(x - y)) / maximum(abs.(x))
44

5-
SemiCircle(dlr, grid, type) = Sample.SemiCircle(dlr.Euv, dlr.β, dlr.isFermi, grid, type, dlr.symmetry, rtol = dlr.rtol, degree = 24, regularized = true)
5+
# SemiCircle(dlr, grid, type) = Sample.SemiCircle(dlr.Euv, dlr.β, dlr.isFermi, grid, type, dlr.symmetry, rtol = dlr.rtol, degree = 24, regularized = true)
6+
SemiCircle(dlr, grid, type) = Sample.SemiCircle(dlr, type, grid, degree = 24, regularized = true)
67

78
function MultiPole(dlr, grid, type)
89
Euv = dlr.Euv
910
poles = [-Euv, -0.2 * Euv, 0.0, 0.8 * Euv, Euv]
10-
return Sample.MultiPole(dlr.β, dlr.isFermi, grid, type, poles, dlr.symmetry; regularized = true)
11+
# return Sample.MultiPole(dlr.β, dlr.isFermi, grid, type, poles, dlr.symmetry; regularized = true)
12+
return Sample.MultiPole(dlr, type, poles, grid; regularized = true)
1113
end
1214

1315
function compare(case, a, b, eps, requiredratio, para = "")
@@ -62,9 +64,9 @@ end
6264
# Matsubara-frequency Test #
6365
#=========================================================================================#
6466
# #get Matsubara-frequency Green's function
65-
Gndlr = case(dlr, dlr.n, :ωn)
67+
Gndlr = case(dlr, dlr.n, :n)
6668
nSample = dlr10.n
67-
Gnsample = case(dlr, nSample, :ωn)
69+
Gnsample = case(dlr, nSample, :n)
6870

6971
# #Matsubara frequency to dlr
7072
coeffn = matfreq2dlr(dlr, Gndlr)
@@ -158,7 +160,7 @@ end
158160
dlr = DLRGrid(Euv, β, eps, isFermi, symmetry) #construct dlr basis
159161

160162
= SemiCircle(dlr, dlr.τ, )
161-
Gn = SemiCircle(dlr, dlr.n, :ωn)
163+
Gn = SemiCircle(dlr, dlr.n, :n)
162164

163165
n1, n2 = 3, 4
164166
a = rand(n1, n2)

0 commit comments

Comments
 (0)