diff --git a/Project.toml b/Project.toml index e327bda..ca9bf73 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "SmoQySynthAC" uuid = "fe3e30a4-de68-41ff-a057-b00c4bb8fcbc" authors = ["Benjamin Cohen-Stead ", "Steven Johnston "] -version = "0.1.0" +version = "0.1.1" [deps] Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" diff --git a/docs/src/usage.md b/docs/src/usage.md index e2e551c..4b0d657 100644 --- a/docs/src/usage.md +++ b/docs/src/usage.md @@ -17,11 +17,11 @@ CairoMakie.activate!(type = "svg") In this example we will work with the single-particle imaginary time fermion Green's function which is given by ```math -G(\tau) = \int_{-\infty}^\infty K(\omega,\tau,\beta) A(\omega) +G(\tau) = \int_{-\infty}^\infty K_\beta(\omega,\tau) A(\omega) ``` where ``A(\omega)`` is the spectral function and ```math -K(\omega,\tau,\beta) = \frac{e^{-\tau \omega}}{1 + e^{-\beta \omega}} +K_\beta(\omega,\tau) = \frac{e^{-\tau \omega}}{1 + e^{-\beta \omega}} ``` is the kernel function where ``\beta = 1/T`` is the inverse temperature and it is assumed that ``\tau \in [0, \beta)``. @@ -32,13 +32,13 @@ For convenience we will do this using the [`Distributions.jl`](https://github.co We will define a spectral function with a Lorentzian (Cauchy) distribution in centered between two Normal distributions on either side. ````@example usage -# define spectral distribution +# define spectral function distribution spectral_dist = MixtureModel( [Normal(-2.0,0.7), Cauchy(0.0, 0.3), Normal(+2.0,0.7)], [0.2, 0.4, 0.4] ) -# define function to evaluate the spectral funciton +# define method to evaluate spectral function spectral_function = ω -> pdf(spectral_dist, ω) ```` @@ -82,8 +82,13 @@ The next step is to define the inverse temperature ``\beta``, discretization in and corresponding ``\tau`` grid. ````@example usage +# Set inverse temperature. β = 10.0 + +# Set discretization in imaginary time. Δτ = 0.05 + +# Calculate corresponding imaginary time grid. τ = collect(range(start = 0.0, stop = β, step = Δτ)); nothing #hide ```` @@ -92,6 +97,7 @@ Now we can calculate ``G(\tau)`` using the [`spectral_to_imaginary_time_correlat method and appropriate kernel funciton [`kernel_tau_fermi`](@ref). ````@example usage +# Calculate imaginary time Green's function. Gτ = spectral_to_imaginary_time_correlation_function( τ = τ, β = β, @@ -102,6 +108,63 @@ Gτ = spectral_to_imaginary_time_correlation_function( nothing #hide ```` +We can similary calculate the Matsubara Green's function ``G(\text{i}\omega_n)`` +using the function [`spectral_to_matsubara_correlation_function`](@ref) function +with the kernel function [`kernel_mat_fermi`](@ref). + +````@example usage +# Define Matsubara frequency grid in terms of integers n where ωₙ = (2n+1)π/β. +n = collect(-250:250) + +# Calculate Matsubara Green's function. +Gn = spectral_to_matsubara_correlation_function(; + n = n, + β = β, + spectral_function = spectral_function, + kernel_function = kernel_mat_fermi, + tol= 1e-10, +); +nothing #hide +```` + +The resulting real and imaginary parts of ``G(\text{i}\omega_n)`` are plotted below. + +````@example usage +ωn = @. 2π*(n+1)/β + +fig = Figure( + size = (700, 500), + fonts = (; regular= "CMU Serif"), + figure_padding = 10 +) + +ax = Axis(fig[1, 1], + aspect = 7/5, + xlabel = L"\omega_n", + ylabel = L"G_\sigma(\text{i}\omega_n)", + xlabelsize = 30, ylabelsize = 30, + xticklabelsize = 24, yticklabelsize = 24, +) + +xlims!(ax, minimum(ωn), maximum(ωn)) + +lines!( + ωn, real.(Gn), + linewidth = 2, alpha = 2.0, color = :red, linestyle = :solid, label = L"\text{Re}[G_\sigma(\text{i}\omega_n)]" +) + +lines!( + ωn, imag.(Gn), + linewidth = 2, alpha = 1.5, color = :green, linestyle = :solid, label = L"\text{Im}[G_\sigma(\text{i}\omega_n)]" +) + +axislegend( + ax, halign = :left, valign = :top, labelsize = 30 +) + +fig +```` + Having calculated the exact ``G(\tau)`` function, let us now add some noise to it using the [`add_noise`](@ref) method. diff --git a/docs/usage.jl b/docs/usage.jl index 4bc1bbc..d992869 100644 --- a/docs/usage.jl +++ b/docs/usage.jl @@ -11,11 +11,11 @@ CairoMakie.activate!(type = "svg") # In this example we will work with the single-particle imaginary time fermion Green's function # which is given by # ```math -# G(\tau) = \int_{-\infty}^\infty K(\omega,\tau,\beta) A(\omega) +# G(\tau) = \int_{-\infty}^\infty K_\beta(\omega,\tau) A(\omega) # ``` # where ``A(\omega)`` is the spectral function and # ```math -# K(\omega,\tau,\beta) = \frac{e^{-\tau \omega}}{1 + e^{-\beta \omega}} +# K_\beta(\omega,\tau) = \frac{e^{-\tau \omega}}{1 + e^{-\beta \omega}} # ``` # is the kernel function where ``\beta = 1/T`` is the inverse temperature and it is assumed that # ``\tau \in [0, \beta)``. @@ -25,13 +25,13 @@ CairoMakie.activate!(type = "svg") # For convenience we will do this using the [`Distributions.jl`](https://github.com/JuliaStats/Distributions.jl.git) package. # We will define a spectral function with a Lorentzian (Cauchy) distribution in centered between two Normal distributions on either side. -## define spectral distribution +## define spectral function distribution spectral_dist = MixtureModel( [Normal(-2.0,0.7), Cauchy(0.0, 0.3), Normal(+2.0,0.7)], [0.2, 0.4, 0.4] ) -## define function to evaluate the spectral funciton +## define method to evaluate spectral function spectral_function = ω -> pdf(spectral_dist, ω) # Now let us quickly plot our spectral function so we can see what it looks like. @@ -71,13 +71,19 @@ fig # The next step is to define the inverse temperature ``\beta``, discretization in imaginary ``\Delta\tau`` # and corresponding ``\tau`` grid. +## Set inverse temperature. β = 10.0 + +## Set discretization in imaginary time. Δτ = 0.05 + +## Calculate corresponding imaginary time grid. τ = collect(range(start = 0.0, stop = β, step = Δτ)); # Now we can calculate ``G(\tau)`` using the [`spectral_to_imaginary_time_correlation_function`](@ref) # method and appropriate kernel funciton [`kernel_tau_fermi`](@ref). +## Calculate imaginary time Green's function. Gτ = spectral_to_imaginary_time_correlation_function( τ = τ, β = β, @@ -86,6 +92,58 @@ Gτ = spectral_to_imaginary_time_correlation_function( tol = 1e-10 ); +# We can similary calculate the Matsubara Green's function ``G(\text{i}\omega_n)`` +# using the function [`spectral_to_matsubara_correlation_function`](@ref) function +# with the kernel function [`kernel_mat_fermi`](@ref). + +## Define Matsubara frequency grid in terms of integers n where ωₙ = (2n+1)π/β. +n = collect(-250:250) + +## Calculate Matsubara Green's function. +Gn = spectral_to_matsubara_correlation_function(; + n = n, + β = β, + spectral_function = spectral_function, + kernel_function = kernel_mat_fermi, + tol= 1e-10, +); + +# The resulting real and imaginary parts of ``G(\text{i}\omega_n)`` are plotted below. + +ωn = @. 2π*(n+1)/β + +fig = Figure( + size = (700, 500), + fonts = (; regular= "CMU Serif"), + figure_padding = 10 +) + +ax = Axis(fig[1, 1], + aspect = 7/5, + xlabel = L"\omega_n", + ylabel = L"G_\sigma(\text{i}\omega_n)", + xlabelsize = 30, ylabelsize = 30, + xticklabelsize = 24, yticklabelsize = 24, +) + +xlims!(ax, minimum(ωn), maximum(ωn)) + +lines!( + ωn, real.(Gn), + linewidth = 2, alpha = 2.0, color = :red, linestyle = :solid, label = L"\text{Re}[G_\sigma(\text{i}\omega_n)]" +) + +lines!( + ωn, imag.(Gn), + linewidth = 2, alpha = 1.5, color = :green, linestyle = :solid, label = L"\text{Im}[G_\sigma(\text{i}\omega_n)]" +) + +axislegend( + ax, halign = :left, valign = :top, labelsize = 30 +) + +fig + # Having calculated the exact ``G(\tau)`` function, let us now add some noise to it using the # [`add_noise`](@ref) method. diff --git a/src/kernel_functions.jl b/src/kernel_functions.jl index 417c513..8eee059 100644 --- a/src/kernel_functions.jl +++ b/src/kernel_functions.jl @@ -39,7 +39,7 @@ kernel_tau_sym_bose(ω::T, τ::T, β::T) where {T<:AbstractFloat} = (-β*ω > 10 The fermionic matsubara frequency kernel ```math -K_\beta(\omega, {\rm i}\omega_n) = \frac{1}{{\rm i}\omega_n - \omega}, +K_\beta(\omega, \omega_n) = \frac{1}{{\rm i}\omega_n - \omega}, ``` where ``\omega_n = (2n+1)\pi/\beta`` for fermions with ``n \in \mathbb{Z}``. """ @@ -51,7 +51,7 @@ kernel_mat_fermi(ω::T, n::Int, β::T) where {T<:AbstractFloat} = kernel_mat(ω The bosonic matsubara frequency kernel ```math -K_\beta(\omega, {\rm i}\omega_n) = \frac{1}{{\rm i}\omega_n - \omega}, +K_\beta(\omega, \omega_n) = \frac{1}{{\rm i}\omega_n - \omega}, ``` where ``\omega_n = 2n\pi/\beta`` for bosons with ``n \in \mathbb{Z}``. """ diff --git a/src/spectral_to_correlation_function.jl b/src/spectral_to_correlation_function.jl index 5ab0842..3edf52b 100644 --- a/src/spectral_to_correlation_function.jl +++ b/src/spectral_to_correlation_function.jl @@ -52,12 +52,12 @@ end tol::T = 1e-10, ) where {T<:AbstractFloat} -Calculate and return the imaginary-time correlation function +Calculate and return the Matsubara correlation function ```math -C(\tau) = \int_{-\infty}^{\infty} d\omega \ K(\omega, \omega_n, \beta) \ A(\omega). +C({\rm i} \omega_n) = \int_{-\infty}^{\infty} d\omega \ K_\beta(\omega, \omega_n) \ A(\omega). ``` -on a grid of ``\tau`` (`τ`) values, given a spectral function ``A(\omega)`` (`spectral_function`) -and kernel function ``K(\omega,\tau,\beta)`` (`kernel_function`). This integral is evaluated within +for a vector of ``n \in \mathbb{Z}`` values, given a spectral function ``A(\omega)`` (`spectral_function`) +and kernel function ``K(\omega,\omega_n,\beta)`` (`kernel_function`). This integral is evaluated within a specified tolerance `tol`. Note that the kernel function should be called as `kernel_function(ω, n, β)` where `n` @@ -66,10 +66,10 @@ or ``\omega_n = 2n\pi/\beta`` depending on whether the kernel function is fermio ## Arguments -- `τ::AbstractVector{T}`: Vector of imaginary time such that `τ[end] = β` equal the inverse temperature. +- `n::AbstractVector{Int}`: Vector of integers specifying Matsubara frequencies for which ``C({\rm i}\omega_n) will be evaluated. - `spectral_function::Function`: The spectral function ``A(\omega)`` that takes a single argument. -- `kernel_function::Function`: The kernel function ``K(\omega,\tau,\beta)`` that takes three arguments as shown. -- `tol::T = 1e-10`: Specified precision with which ``C(\tau)`` is evaluated. +- `kernel_function::Function`: The kernel function ``K(\omega,\omega_n,\beta)`` that takes three arguments as shown. +- `tol::T = 1e-10`: Specified precision with which ``C({\rm i}\omega_n)`` is evaluated. """ function spectral_to_matsubara_correlation_function(; # KEYWORD ARGUMENTS