Discrete Lehmann Representation#
Theory#
We explain how to transform expansion coefficients in IR to the discrete Lehmann representation (DLR) [1]. We model the spectral function as
where sampling frequencies
where the matrix
[1] J. Kaye, K. Chen, O. Parcollet, Phys. Rev. B 105, 235115 (2022).
[2] H. Shinaoka et al., arXiv:2106.12685v2.
We consider fermions and the semi circular DOS
The corresponding Green’s function is given by
The Green’s function is expanded in IR as
Below, we demonstrate how to transform
using SparseIR
using Plots
gr() # USE GR backend
using LaTeXStrings
Implementation#
Create basis object#
wmax = 1.0
lambda_ = 1e+4
beta = lambda_/wmax
basis = FiniteTempBasis(Fermionic(), beta, wmax, 1e-15)
print(length(basis))
104
Setup model#
rho(omega) = sqrt(1-omega^2)/sqrt(0.5*π)
omega = LinRange(-wmax, wmax, 1000)
plot(omega, rho.(omega), xlabel=latexstring("\\omega"), ylabel=latexstring("\\rho(\\omega)"))
rhol = overlap(basis.v, rho)
ls = collect(1:length(basis))
plot(ls[1:2:end], abs.(rhol)[1:2:end], marker=:cross, yaxis=:log, ylims=(1e-5,1))
gl = - basis.s .* rhol
plot(ls[1:2:end], abs.(gl)[1:2:end], marker=:cross, ylims=(1e-5,10), yaxis=:log)
Create a DLR object and perform transformation#
dlr = DiscreteLehmannRepresentation(basis)
# To DLR
g_dlr = SparseIR.from_IR(dlr, gl)
plot(dlr.poles, g_dlr, marker=:cross)
# Transform back to IR from DLR
gl_reconst = SparseIR.to_IR(dlr, g_dlr)
plot(
[abs.(gl), abs.(gl_reconst), abs.(gl-gl_reconst)],
label=["Exact" "Reconstructed from DLR" "error"],
marker=[:cross :x :circle], line=(nothing,nothing,nothing), yaxis=:log,
ylims=(1e-18,10)
)
┌ Warning: Invalid negative or zero value 0.0 found at series index 4 for log10 based yscale
└ @ Plots ~/.julia/packages/Plots/rz1WP/src/utils.jl:106
┌ Warning: Invalid negative or zero value 0.0 found at series index 4 for log10 based yscale
└ @ Plots ~/.julia/packages/Plots/rz1WP/src/utils.jl:106
┌ Warning: Invalid negative or zero value 0.0 found at series index 4 for log10 based yscale
└ @ Plots ~/.julia/packages/Plots/rz1WP/src/utils.jl:106
Evaluation on Matsubara frequencies#
#v = 2 .* collect(-1000:10:1000) .+ 1
v = FermionicFreq.(2 .* collect(-1000:10:1000) .+ 1)
iv = SparseIR.valueim.(v, beta)
newaxis = [CartesianIndex()]
transmat = 1 ./ (iv[:,newaxis] .- dlr.poles[newaxis,:])
giv = transmat * g_dlr
smpl = MatsubaraSampling(basis; sampling_points=v)
giv_exact = evaluate(smpl, gl)
plot(
imag.(iv), [imag.(giv_exact), imag.(giv)], marker=[:cross :x], line=(nothing,nothing),
xlabel=latexstring("\\nu"),
ylabel=latexstring("G(\\mathrm{i}\\omega_n)")
)
┌ Warning: Sampling matrix is poorly conditioned (cond = 4.001560882675462e15).
└ @ SparseIR ~/.julia/packages/SparseIR/KrYmQ/src/sampling.jl:81