Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ITensorGaussianMPS] Add time-dependent Green functions #884

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion ITensorGaussianMPS/src/ITensorGaussianMPS.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@ import LinearAlgebra: Givens

export slater_determinant_to_mps,
slater_determinant_to_gmps,
slater_determinant_to_gmera,
hopping_hamiltonian,
slater_determinant_matrix,
slater_determinant_to_gmera
retarded_green_function,
lesser_green_function,
greater_green_function

include("gmps.jl")
include("gmera.jl")
include("dynamics.jl")

end
93 changes: 93 additions & 0 deletions ITensorGaussianMPS/src/dynamics.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@

function _compute_correlator(N::Int, f::Function; kwargs...)
sites = get(kwargs, :sites, 1:N)
site_range = (sites isa AbstractRange) ? sites : collect(sites)
Ns = length(site_range)

C = zeros(ComplexF64, Ns, Ns)
for (ni, i) in enumerate(site_range), (nj, j) in enumerate(site_range)
C[ni, nj] += f(i, j)
end

if sites isa Number
return C[1, 1]
end
return C
end

"""
retarded_green_function(t, ϕ, ϵ; kwargs...)

Compute the retarded single-particle Green function
GR(t)_ij = -i θ(t) <ϕ|{cᵢ(t), c†ⱼ(0)}|ϕ>
at time t where |ϕ> is a Slater determinant determined by
the matrix of orbitals ϕ, with energies ϵ.
"""
function retarded_green_function(t::Number, ϕ, ϵ::Vector{Float64}; kwargs...)
N = length(ϵ)
@assert size(ϕ) == (N, N)
function compute_GR(i, j)
gr = 0.0im
for n in 1:N
gr += -im * ϕ[i, n] * conj(ϕ[j, n]) * exp(-im * ϵ[n] * t)
end
return gr
end
return _compute_correlator(N, compute_GR; kwargs...)
end

"""
greater_green_function(t, ϕ, ϵ; kwargs...)

Compute the greater single-particle Green function
G>(t)_ij = -i <ϕ|cᵢ(t) c†ⱼ(0)|ϕ>
at time t where |ϕ> is a Slater determinant determined by
the matrix of orbitals ϕ, with energies ϵ.

The keyword argument `Npart` can be used to specify the number
of particles (number of occupied orbitals). Otherwise the number
of particles is determined by the number of negative energies in ϵ.
"""
function greater_green_function(t::Number, ϕ, ϵ::Vector{Float64}; kwargs...)
N = length(ϵ)
@assert size(ϕ) == (N, N)
Nneg = count(en -> (en < 0), ϵ)
Npart = get(kwargs, :Npart, Nneg)

function compute_GG(i, j)
gg = 0.0im
for n in (Npart + 1):N
gg += -im * ϕ[i, n] * conj(ϕ[j, n]) * exp(-im * ϵ[n] * t)
end
return gg
end
return _compute_correlator(N, compute_GG; kwargs...)
end

"""
lesser_green_function(t, ϕ, ϵ; kwargs...)

Compute the lesser single-particle Green function
G<(t)_ij = +i <ϕ|c†ᵢ(0) cⱼ(t)|ϕ>
at time t where |ϕ> is a Slater determinant determined by
the matrix of orbitals ϕ, with energies ϵ.

The keyword argument `Npart` can be used to specify the number
of particles (number of occupied orbitals). Otherwise the number
of particles is determined by the number of negative energies in ϵ.
"""
function lesser_green_function(t::Number, ϕ, ϵ::Vector{Float64}; kwargs...)
N = length(ϵ)
@assert size(ϕ) == (N, N)
Nneg = count(en -> (en < 0), ϵ)
Npart = get(kwargs, :Npart, Nneg)

function compute_GL(i, j)
gl = 0.0im
for n in 1:Npart
gl += +im * ϕ[i, n] * conj(ϕ[j, n]) * exp(-im * ϵ[n] * t)
end
return gl
end
return _compute_correlator(N, compute_GL; kwargs...)
end
64 changes: 64 additions & 0 deletions ITensorGaussianMPS/test/dynamics.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using ITensorGaussianMPS
using ITensors
using LinearAlgebra
using Test

function diagonalize_h(N)
hterms = OpSum()
for j in 1:(N - 1)
hterms += -1, "Cdag", j, "C", j + 1
hterms += -1, "Cdag", j + 1, "C", j
end

h = hopping_hamiltonian(hterms)
ϵ, ϕ = eigen(h)
return ϵ, ϕ
end

@testset "Green Function Properties" begin
N = 20
ϵ, ϕ = diagonalize_h(N)

t = 1.0

Gr = retarded_green_function(t, ϕ, ϵ)
Gl = lesser_green_function(t, ϕ, ϵ)
Gg = greater_green_function(t, ϕ, ϵ)

@test Gr ≈ (Gg - Gl)

# Gr is -im at time zero:
@test retarded_green_function(0.0, ϕ, ϵ)[1, 1] ≈ -im

# G< at t=0 is im times the correlation matrix
Npart = div(N, 2)
Gl0 = lesser_green_function(0, ϕ, ϵ; Npart)
ϕ_occ = ϕ[:, 1:Npart]
C = ϕ_occ * ϕ_occ'
@test Gl0 ≈ im * C
end

@testset "Sites Keyword" begin
N = 20
ϵ, ϕ = diagonalize_h(N)

t = 1.0

G = retarded_green_function(t, ϕ, ϵ)

G5_10 = retarded_green_function(t, ϕ, ϵ; sites=5:10)
@test size(G5_10) == (6, 6)
@test G5_10 ≈ G[5:10, 5:10]

g7 = retarded_green_function(t, ϕ, ϵ; sites=7)
@test g7 isa Number

# Non-contiguous case
Gnc = retarded_green_function(t, ϕ, ϵ; sites=[5, 10, 15])
@test size(Gnc) == (3, 3)
@test Gnc[1, 1] ≈ G[5, 5]
@test Gnc[1, 2] ≈ G[5, 10]
@test Gnc[2, 3] ≈ G[10, 15]
end

nothing
1 change: 1 addition & 0 deletions ITensorGaussianMPS/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ using Test
@testset "ITensorGaussianMPS.jl" begin
include("gmps.jl")
include("electron.jl")
include("dynamics.jl")
end