From 5b5e1b52e04d7b43475f6b3fa5ae41fa682aae03 Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Wed, 24 Apr 2024 13:21:47 +0000 Subject: [PATCH] build based on ab427e2 --- dev/.documenter-siteinfo.json | 2 +- dev/api/index.html | 70 +- dev/assets/documenter.js | 923 +++++++++++++--------- dev/assets/notebooks/square_hubbard.ipynb | 26 +- dev/assets/scripts/square_hubbard.jl | 22 +- dev/assets/themes/documenter-dark.css | 2 +- dev/examples/square_hubbard/index.html | 74 +- dev/index.html | 2 +- dev/objects.inv | Bin 0 -> 1161 bytes dev/search_index.js | 2 +- 10 files changed, 654 insertions(+), 469 deletions(-) create mode 100644 dev/objects.inv diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 0594878..fff1845 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.1","generation_timestamp":"2024-02-23T14:52:49","documenter_version":"1.2.1"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.2","generation_timestamp":"2024-04-24T13:21:44","documenter_version":"1.4.0"}} \ No newline at end of file diff --git a/dev/api/index.html b/dev/api/index.html index 72e328a..e24ae5f 100644 --- a/dev/api/index.html +++ b/dev/api/index.html @@ -1,31 +1,31 @@ -API · JDQMCFramework.jl

API

Propagator Types

JDQMCFramework.AbstractPropagatorType
abstract type AbstractPropagator{T<:Continuous, E<:Continuous} end

Abstract type to represent imaginary time propagator matrices $B$. All specific propagators types inherit from this abstract type. In the above T is data type of the matrix elements of the exponentiated kintetic energy matrix $e^{-\Delta\tau K_l}$ appearing in $B_l$, and E is data type of the matrix elements appearing in the diagonal exponentiated potential energy matrix $e^{-\Delta\tau V_l}$.

source
JDQMCFramework.AbstractExactPropagatorType
abstract type AbstractExactPropagator{T,E} <: AbstractPropagator{T,E} end

Abstract type to represent imaginary time propagator matrices $B$ defined with an exactly exponentiated hopping matrix $K$.

source
JDQMCFramework.AbstractChkbrdPropagatorType
abstract type AbstractChkbrdPropagator{T,E} <: AbstractPropagator{T,E} end

Abstract type to represent imaginary time propagator matrices $B$ defined with the exponentiated hopping matrix $K$ represented by the checkerboard approximation.

source
JDQMCFramework.SymExactPropagatorType
SymExactPropagator{T, E} <: AbstractExactPropagator{T,E}

Represents imaginary time propagator matrix as using the symmetric form

\[B_l = e^{-\Delta\tau K_l/2} e^{-\Delta\tau V_l} e^{-\Delta\tau K_l/2},\]

where $K_l$ is the strictly off-diagonal hopping matrix and $V_l$ is the diagonal total on-site energy matrix.

Fields

  • expmΔτV::Vector{E}: A vector representing the diagonal exponeniated on-site energy matrix $e^{-\Delta\tau V_l}.$
  • expmΔτKo2::Matrix{T}: The exponentiated hopping matrix $e^{-\Delta\tau K_l/2}.$
  • exppΔτKo2::Matrix{T}: Inverse of the exponentiated hopping matrix $e^{+\Delta\tau K_l/2}.$
source
JDQMCFramework.AsymExactPropagatorType
AsymExactPropagator{T, E} <: AbstractExactPropagator{T,E}

Represents imaginary time propagator matrix as using the symmetric form

\[B_l = e^{-\Delta\tau V_l} e^{-\Delta\tau K_l},\]

where $K_l$ is the strictly off-diagonal hopping matrix and $V_l$ is the diagonal total on-site energy matrix.

Fields

  • expmΔτV::Vector{E}: A vector representing the diagonal exponeniated on-site energy matrix $e^{-\Delta\tau V_l}.$
  • expmΔτK::Matrix{T}: The exponentiated hopping matrix $e^{-\Delta\tau K_l}.$
  • exppΔτK::Matrix{T}: Inverse of the exponentiated hopping matrix $e^{+\Delta\tau K_l}.$
source
JDQMCFramework.SymChkbrdPropagatorType
SymChkbrdPropagator{T, E} <: AbstractChkbrdPropagator{T,E}

Represents imaginary time propagator matrix as using the symmetric form

\[B_l = e^{-\Delta\tau K_l/2} e^{-\Delta\tau V_l} [e^{-\Delta\tau K_l/2}]^\dagger,\]

where $K_l$ is the strictly off-diagonal hopping matrix and $V_l$ is the diagonal total on-site energy matrix. The exponentiated hopping matrix $e^{-\Delta\tau K/2}$ is represented by the checkerboard approximation.

Fields

  • expmΔτV::Vector{E}: A vector representing the diagonal exponeniated on-site energy matrix $e^{-\Delta\tau V_l}.$
  • expmΔτKo2::CheckerboardMatrix{T}: The exponentiated hopping matrix $e^{-\Delta\tau K_l/2}$ represented by the checkerboard approximation.
source
JDQMCFramework.AsymChkbrdPropagatorType
AsymChkbrdPropagator{T, E} <: AbstractChkbrdPropagator{T,E}

Represents imaginary time propagator matrix as using the symmetric form

\[B_l = e^{-\Delta\tau V_l} e^{-\Delta\tau K_l},\]

where $K_l$ is the strictly off-diagonal hopping matrix and $V_l$ is the diagonal total on-site energy matrix. The exponentiated hopping matrix $e^{-\Delta\tau K}$ is represented by the checkerboard approximation.

Fields

  • expmΔτV::Vector{E}: The vector representing the diagonal exponeniated on-site energy matrix $e^{-\Delta\tau V_l}.$
  • expmΔτK::CheckerboardMatrix{T}: The exponentiated hopping matrix $e^{-\Delta\tau K_l}$ represented by the checkerboard approximation.
source
JDQMCFramework.SymPropagatorsType
SymPropagators

A union of the all the symmetric propagators types to help test whether a propagator type is symmetric. Assuming typeof{B} <: AbstractPropagator returns true, if typeof(B) <: SymPropagators returns true, then B represents a symmetric propagator, otherwise it represents an asymmetric propagator.

source

FermionGreensCalculator Type

JDQMCFramework.FermionGreensCalculatorType
FermionGreensCalculator{T<:Continuous, E<:AbstractFloat}

A type to facilitate calculating the single-particle fermion Green's function matrix.

Fields

  • forward::Bool: If true then iterate over imaginary time slices from $l=1$ to $l=L_\tau$, if false then iterate over imaginary time slices from $l=L_\tau$ to $l=1$.
  • l::Int: The current imaginary time slice $\tau = l \cdot \Delta\tau$.
  • n_stab::Int: Frequency with which numerical stabilization is performed, i.e. every $n_s$ imaginary time slices the equal-time Green's function is recomputed from scratch.
  • N_stab::Int: Number of numerical stabilization intervals, $N_s = \left\lceil L_\tau / n_s \right\rceil.$
  • N::Int: Orbitals in system.
  • β::E: The inverse temperature $\beta=1/T,$ where $T$ is temperature.
  • Δτ::E: Discretization in imaginary time.
  • Lτ::Int: Length of imaginary time axis, $L_\tau = \beta / \Delta\tau.$
  • B_bar::Vector{Matrix{T}}: A multidimensional array where the matrix B_bar[:,:,n] represents $\bar{B}_n.$
  • F::Vector{LDR{T,E}}: A vector of $N_s$ LDR factorizations to represent the matrices $B(0,\tau)$ and $B(\tau,\beta)$.
  • G′::Matrix{T}: Matrix used for calculating the error corrected by numerical stabilization of the equal time Green's function.
  • ldr_ws::LDRWorkspace{T}: Workspace for performing LDR factorization while avoiding dynamic memory allocations.
source
JDQMCFramework.FermionGreensCalculatorMethod
FermionGreensCalculator(
+API · JDQMCFramework.jl

API

Propagator Types

JDQMCFramework.AbstractPropagatorType
abstract type AbstractPropagator{T<:Continuous, E<:Continuous} end

Abstract type to represent imaginary time propagator matrices $B$. All specific propagators types inherit from this abstract type. In the above T is data type of the matrix elements of the exponentiated kintetic energy matrix $e^{-\Delta\tau K_l}$ appearing in $B_l$, and E is data type of the matrix elements appearing in the diagonal exponentiated potential energy matrix $e^{-\Delta\tau V_l}$.

source
JDQMCFramework.AbstractExactPropagatorType
abstract type AbstractExactPropagator{T,E} <: AbstractPropagator{T,E} end

Abstract type to represent imaginary time propagator matrices $B$ defined with an exactly exponentiated hopping matrix $K$.

source
JDQMCFramework.AbstractChkbrdPropagatorType
abstract type AbstractChkbrdPropagator{T,E} <: AbstractPropagator{T,E} end

Abstract type to represent imaginary time propagator matrices $B$ defined with the exponentiated hopping matrix $K$ represented by the checkerboard approximation.

source
JDQMCFramework.SymExactPropagatorType
SymExactPropagator{T, E} <: AbstractExactPropagator{T,E}

Represents imaginary time propagator matrix as using the symmetric form

\[B_l = e^{-\Delta\tau K_l/2} e^{-\Delta\tau V_l} e^{-\Delta\tau K_l/2},\]

where $K_l$ is the strictly off-diagonal hopping matrix and $V_l$ is the diagonal total on-site energy matrix.

Fields

  • expmΔτV::Vector{E}: A vector representing the diagonal exponeniated on-site energy matrix $e^{-\Delta\tau V_l}.$
  • expmΔτKo2::Matrix{T}: The exponentiated hopping matrix $e^{-\Delta\tau K_l/2}.$
  • exppΔτKo2::Matrix{T}: Inverse of the exponentiated hopping matrix $e^{+\Delta\tau K_l/2}.$
source
JDQMCFramework.AsymExactPropagatorType
AsymExactPropagator{T, E} <: AbstractExactPropagator{T,E}

Represents imaginary time propagator matrix as using the symmetric form

\[B_l = e^{-\Delta\tau V_l} e^{-\Delta\tau K_l},\]

where $K_l$ is the strictly off-diagonal hopping matrix and $V_l$ is the diagonal total on-site energy matrix.

Fields

  • expmΔτV::Vector{E}: A vector representing the diagonal exponeniated on-site energy matrix $e^{-\Delta\tau V_l}.$
  • expmΔτK::Matrix{T}: The exponentiated hopping matrix $e^{-\Delta\tau K_l}.$
  • exppΔτK::Matrix{T}: Inverse of the exponentiated hopping matrix $e^{+\Delta\tau K_l}.$
source
JDQMCFramework.SymChkbrdPropagatorType
SymChkbrdPropagator{T, E} <: AbstractChkbrdPropagator{T,E}

Represents imaginary time propagator matrix as using the symmetric form

\[B_l = e^{-\Delta\tau K_l/2} e^{-\Delta\tau V_l} [e^{-\Delta\tau K_l/2}]^\dagger,\]

where $K_l$ is the strictly off-diagonal hopping matrix and $V_l$ is the diagonal total on-site energy matrix. The exponentiated hopping matrix $e^{-\Delta\tau K/2}$ is represented by the checkerboard approximation.

Fields

  • expmΔτV::Vector{E}: A vector representing the diagonal exponeniated on-site energy matrix $e^{-\Delta\tau V_l}.$
  • expmΔτKo2::CheckerboardMatrix{T}: The exponentiated hopping matrix $e^{-\Delta\tau K_l/2}$ represented by the checkerboard approximation.
source
JDQMCFramework.AsymChkbrdPropagatorType
AsymChkbrdPropagator{T, E} <: AbstractChkbrdPropagator{T,E}

Represents imaginary time propagator matrix as using the symmetric form

\[B_l = e^{-\Delta\tau V_l} e^{-\Delta\tau K_l},\]

where $K_l$ is the strictly off-diagonal hopping matrix and $V_l$ is the diagonal total on-site energy matrix. The exponentiated hopping matrix $e^{-\Delta\tau K}$ is represented by the checkerboard approximation.

Fields

  • expmΔτV::Vector{E}: The vector representing the diagonal exponeniated on-site energy matrix $e^{-\Delta\tau V_l}.$
  • expmΔτK::CheckerboardMatrix{T}: The exponentiated hopping matrix $e^{-\Delta\tau K_l}$ represented by the checkerboard approximation.
source
JDQMCFramework.SymPropagatorsType
SymPropagators

A union of the all the symmetric propagators types to help test whether a propagator type is symmetric. Assuming typeof{B} <: AbstractPropagator returns true, if typeof(B) <: SymPropagators returns true, then B represents a symmetric propagator, otherwise it represents an asymmetric propagator.

source

FermionGreensCalculator Type

JDQMCFramework.FermionGreensCalculatorType
FermionGreensCalculator{T<:Continuous, E<:AbstractFloat}

A type to facilitate calculating the single-particle fermion Green's function matrix.

Fields

  • forward::Bool: If true then iterate over imaginary time slices from $l=1$ to $l=L_\tau$, if false then iterate over imaginary time slices from $l=L_\tau$ to $l=1$.
  • l::Int: The current imaginary time slice $\tau = l \cdot \Delta\tau$.
  • n_stab::Int: Frequency with which numerical stabilization is performed, i.e. every $n_s$ imaginary time slices the equal-time Green's function is recomputed from scratch.
  • N_stab::Int: Number of numerical stabilization intervals, $N_s = \left\lceil L_\tau / n_s \right\rceil.$
  • N::Int: Orbitals in system.
  • β::E: The inverse temperature $\beta=1/T,$ where $T$ is temperature.
  • Δτ::E: Discretization in imaginary time.
  • Lτ::Int: Length of imaginary time axis, $L_\tau = \beta / \Delta\tau.$
  • B_bar::Vector{Matrix{T}}: A multidimensional array where the matrix B_bar[:,:,n] represents $\bar{B}_n.$
  • F::Vector{LDR{T,E}}: A vector of $N_s$ LDR factorizations to represent the matrices $B(0,\tau)$ and $B(\tau,\beta)$.
  • G′::Matrix{T}: Matrix used for calculating the error corrected by numerical stabilization of the equal time Green's function.
  • ldr_ws::LDRWorkspace{T}: Workspace for performing LDR factorization while avoiding dynamic memory allocations.
source

DQMC Building Block Routines

DQMC Building Block Routines

JDQMCFramework.calculate_equaltime_greens!Function
calculate_equaltime_greens!(
     G::AbstractMatrix{T},
     fgc::FermionGreensCalculator{T,E}
-)::Tuple{E,T} where {T,E}

Calculate the equal-time Greens function $G(0,0) = G(\beta,\beta) = [I + B(\beta,0)]^{-1}$ using a numerically stable procedure. This method also returns $\log(\vert \det G \vert)$ and $\textrm{sign}(\det G).$ Note that this routine requires fgc.l == 1 or fgc.l == fgc.Lτ.

source
calculate_equaltime_greens!(
+)::Tuple{E,T} where {T,E}

Calculate the equal-time Greens function $G(0,0) = G(\beta,\beta) = [I + B(\beta,0)]^{-1}$ using a numerically stable procedure. This method also returns $\log(\vert \det G \vert)$ and $\textrm{sign}(\det G).$ Note that this routine requires fgc.l == 1 or fgc.l == fgc.Lτ.

source
calculate_equaltime_greens!(
     G::AbstractMatrix{T},
     fgc::FermionGreensCalculator{T,E},
     B::AbstractVector{P}
-)::Tuple{E,T} where {T, E, P<:AbstractPropagator{T}}

Calculate the equal-time Greens function $G(0,0) = G(\beta,\beta) = [I + B(\beta,0)]^{-1}$ using a numerically stable procedure. Also re-calculate the $\bar{B}_n$ matrices and the LDR matrix factorizations representing either $B(\tau,0)$ or $B(\beta,\tau)$ stored in fgc.F. This routine is useful for implementing global updates where every propagator matrix $B_l$ has been modified, and the equal-time Green's function needs to be re-calculated from scratch. This method also returns $\log(\vert \det G \vert)$ and $\textrm{sign}(\det G).$ Note that this routine requires fgc.l == 1 or fgc.l == fgc.Lτ.

source
JDQMCFramework.propagate_equaltime_greens!Function
propagate_equaltime_greens!(
+)::Tuple{E,T} where {T, E, P<:AbstractPropagator{T}}

Calculate the equal-time Greens function $G(0,0) = G(\beta,\beta) = [I + B(\beta,0)]^{-1}$ using a numerically stable procedure. Also re-calculate the $\bar{B}_n$ matrices and the LDR matrix factorizations representing either $B(\tau,0)$ or $B(\beta,\tau)$ stored in fgc.F. This routine is useful for implementing global updates where every propagator matrix $B_l$ has been modified, and the equal-time Green's function needs to be re-calculated from scratch. This method also returns $\log(\vert \det G \vert)$ and $\textrm{sign}(\det G).$ Note that this routine requires fgc.l == 1 or fgc.l == fgc.Lτ.

source
JDQMCFramework.propagate_equaltime_greens!Function
propagate_equaltime_greens!(
     G::AbstractMatrix{T},
     fgc::FermionGreensCalculator{T,E},
     B::AbstractVector{P}
-) where {T, E, P<:AbstractPropagator{T}}

Propagate the equal-time Green's function matrix G from the previous imaginary time slice to the current imaginary time slice fgc.l. If iterating over imaginary time in the forward direction (fgc.forward = true) the relationship

\[G(\tau+\Delta\tau,\tau+\Delta\tau) = B_{l+1} \cdot G(\tau,\tau) \cdot B_{l+1}^{-1}\]

is used, and if iterating over imaginary time in the reverse direction (fgc.forward = false) the relationship

\[G(\tau-\Delta\tau,\tau-\Delta\tau)= B_{l}^{-1} \cdot G(\tau,\tau) \cdot B_{l}\]

is used instead, where the $B_l$ propagator is given by B[l].

source
JDQMCFramework.stabilize_equaltime_greens!Function
stabilize_equaltime_greens!(
+) where {T, E, P<:AbstractPropagator{T}}

Propagate the equal-time Green's function matrix G from the previous imaginary time slice to the current imaginary time slice fgc.l. If iterating over imaginary time in the forward direction (fgc.forward = true) the relationship

\[G(\tau+\Delta\tau,\tau+\Delta\tau) = B_{l+1} \cdot G(\tau,\tau) \cdot B_{l+1}^{-1}\]

is used, and if iterating over imaginary time in the reverse direction (fgc.forward = false) the relationship

\[G(\tau-\Delta\tau,\tau-\Delta\tau)= B_{l}^{-1} \cdot G(\tau,\tau) \cdot B_{l}\]

is used instead, where the $B_l$ propagator is given by B[l].

source
JDQMCFramework.stabilize_equaltime_greens!Function
stabilize_equaltime_greens!(
     G::AbstractMatrix{T},
     logdetG::E, sgndetG::T,
     fgc::FermionGreensCalculator{T,E},
     B::AbstractVector{P};
     # KEYWORD ARGUMENTS
     update_B̄::Bool=true
-)::Tuple{E,T,E,E} where {T, E, P<:AbstractPropagator{T}}

Stabilize the equal-time Green's function as iterating through imaginary time $\tau = \Delta\tau \cdot l.$ For a given imaginary time slice fgc.l, this routine should be called after all changes to the $B_l$ propagator have been made. When iterating through imaginary time in the forwards direction (fgc.forward = true), this function re-computes

\[G(\tau,\tau) = [I + B(\tau,0)B(\beta,\tau)]^{-1}\]

when at imaginary time slice fgc.l every fgc.n_stab imaginary time slice. When iterating through imaginary time in the reverse direction (fgc.forward = false), this function instead re-computes

\[G(\tau-\Delta\tau,\tau-\Delta\tau) = [I + B(\tau-\Delta\tau,0)B(\beta,\tau-\Delta\tau)]^{-1}\]

for fgc.l.

This method returns four values. The first two values returned are $\log(\vert \det G(\tau,\tau) \vert)$ and $\textrm{sign}(\det G(\tau,\tau))$. The latter two are the maximum error in a Green's function corrected by numerical stabilization $\vert \delta G \vert$, and the error in the phase of the determinant corrected by numerical stabilization $\delta\theta,$ relative to naive propagation of the Green's function matrix in imaginary time occuring instead. If no stabilization was performed, than $\vert \delta G \vert = 0$ and $\delta \theta = 0.$

This method also computes the LDR matrix factorizations representing $B(\tau, 0)$ or $B(\beta, \tau-\Delta\tau)$ when iterating through imaginary time $\tau = \Delta\tau \cdot l$ in the forward and reverse directions respectively. If update_B̄ = true, then the $\bar{B}_n$ matrices are re-calculated as needed, but if update_B̄ = false, then they are left unchanged.

source
JDQMCFramework.initialize_unequaltime_greens!Function
initialize_unequaltime_greens!(
+)::Tuple{E,T,E,E} where {T, E, P<:AbstractPropagator{T}}

Stabilize the equal-time Green's function as iterating through imaginary time $\tau = \Delta\tau \cdot l.$ For a given imaginary time slice fgc.l, this routine should be called after all changes to the $B_l$ propagator have been made. When iterating through imaginary time in the forwards direction (fgc.forward = true), this function re-computes

\[G(\tau,\tau) = [I + B(\tau,0)B(\beta,\tau)]^{-1}\]

when at imaginary time slice fgc.l every fgc.n_stab imaginary time slice. When iterating through imaginary time in the reverse direction (fgc.forward = false), this function instead re-computes

\[G(\tau-\Delta\tau,\tau-\Delta\tau) = [I + B(\tau-\Delta\tau,0)B(\beta,\tau-\Delta\tau)]^{-1}\]

for fgc.l.

This method returns four values. The first two values returned are $\log(\vert \det G(\tau,\tau) \vert)$ and $\textrm{sign}(\det G(\tau,\tau))$. The latter two are the maximum error in a Green's function corrected by numerical stabilization $\vert \delta G \vert$, and the error in the phase of the determinant corrected by numerical stabilization $\delta\theta,$ relative to naive propagation of the Green's function matrix in imaginary time occuring instead. If no stabilization was performed, than $\vert \delta G \vert = 0$ and $\delta \theta = 0.$

This method also computes the LDR matrix factorizations representing $B(\tau, 0)$ or $B(\beta, \tau-\Delta\tau)$ when iterating through imaginary time $\tau = \Delta\tau \cdot l$ in the forward and reverse directions respectively. If update_B̄ = true, then the $\bar{B}_n$ matrices are re-calculated as needed, but if update_B̄ = false, then they are left unchanged.

source
JDQMCFramework.initialize_unequaltime_greens!Function
initialize_unequaltime_greens!(
     Gτ0::AbstractMatrix{T},
     G0τ::AbstractMatrix{T},
     Gττ::AbstractMatrix{T},
     G00::AbstractMatrix{T}
-) where {T<:Number}

Initialize the Green's function matrices $G(\tau,0),$ $G(0,\tau),$ and $G(\tau,\tau)$ for $\tau = 0$ based on the matrix $G(0,0).$

source
JDQMCFramework.propagate_unequaltime_greens!Function
propagate_unequaltime_greens!(
     Gτ0::AbstractMatrix{T},
     G0τ::AbstractMatrix{T},
     Gττ::AbstractMatrix{T},
@@ -39,7 +39,7 @@
 G(\tau,0)    = & B_{l+1}^{-1} \cdot G(\tau+\Delta\tau, 0) \\
 G(0,\tau)    = & G(0, \tau + \Delta\tau) \cdot B_{l+1} \\
 G(\tau,\tau) = & B_{l+1}^{-1} \cdot G(\tau+\Delta\tau, \tau+\Delta\tau) \cdot B_{l+1}
-\end{align}\]

are used instead, where the $B_l$ propagator is given by B[l].

source
JDQMCFramework.stabilize_unequaltime_greens!Function
stabilize_unequaltime_greens!(
     Gτ0::AbstractMatrix{T},
     G0τ::AbstractMatrix{T},
     Gττ::AbstractMatrix{T},
@@ -56,26 +56,26 @@
 G(\tau-\Delta\tau,0)               = & [B^{-1}(\tau-\Delta\tau,0) + B(\beta,\tau-\Delta\tau)]^{-1} \\
 G(0,\tau-\Delta\tau)               = & [B^{-1}(\beta,\tau-\Delta\tau) + B(\tau-\Delta\tau,0)]^{-1} \\
 G(\tau-\Delta\tau,\tau-\Delta\tau) = & [I + B(\tau-\Delta\tau,0)B(\beta,\tau-\Delta\tau)]^{-1}
-\begin{align*}\]

for fgc.l.

This method returns four values. The first two values returned are $\log(\vert \det G(\tau,\tau) \vert)$ and $\textrm{sign}(\det G(\tau,\tau))$. The latter two are the maximum error in a Green's function corrected by numerical stabilization $\vert \delta G \vert$, and the error in the phase of the determinant corrected by numerical stabilization $\delta\theta,$ relative to naive propagation of the Green's function matrix in imaginary time occuring instead. If no stabilization was performed, than $\vert \delta G \vert = 0$ and $\delta \theta = 0.$

This method also computes the LDR matrix factorizations representing $B(\tau, 0)$ or $B(\beta, \tau-\Delta\tau)$ when iterating through imaginary time $\tau = \Delta\tau \cdot l$ in the forward and reverse directions respectively. If update_B̄ = true, then the $\bar{B}_n$ matrices are re-calculated as needed, but if update_B̄ = false, then they are left unchanged.

source
JDQMCFramework.local_update_det_ratioFunction
local_update_det_ratio(
+\begin{align*}\]

for fgc.l.

This method returns four values. The first two values returned are $\log(\vert \det G(\tau,\tau) \vert)$ and $\textrm{sign}(\det G(\tau,\tau))$. The latter two are the maximum error in a Green's function corrected by numerical stabilization $\vert \delta G \vert$, and the error in the phase of the determinant corrected by numerical stabilization $\delta\theta,$ relative to naive propagation of the Green's function matrix in imaginary time occuring instead. If no stabilization was performed, than $\vert \delta G \vert = 0$ and $\delta \theta = 0.$

This method also computes the LDR matrix factorizations representing $B(\tau, 0)$ or $B(\beta, \tau-\Delta\tau)$ when iterating through imaginary time $\tau = \Delta\tau \cdot l$ in the forward and reverse directions respectively. If update_B̄ = true, then the $\bar{B}_n$ matrices are re-calculated as needed, but if update_B̄ = false, then they are left unchanged.

source
JDQMCFramework.local_update_det_ratioFunction
local_update_det_ratio(
     G::AbstractMatrix{T},
     B::AbstractPropagator{T},
     V′::T, i::Int, Δτ::E
-)::Tuple{T,T} where {T,E}

Calculate the determinant ratio $R_{l,i}$ associated with a local update to the equal-time Green's function $G(\tau,\tau).$ Also returns $\Delta_{l,i},$ which is defined below.

Arguments

  • G::AbstractMatrix{T}: Equal-time Green's function matrix $G(\tau,\tau).$
  • B::AbstractPropagator{T,E}: Represents the propagator matrix $B_l,$ where $\tau = \Delta\tau \cdot l.$
  • V′::T: The new value for the $V^{\prime}_{l,i,i}$ matrix element in the diagonal on-site energy matrix $V_l.$
  • i::Int: Diagonal matrix element index in $V_l$ being updated.
  • Δτ::E: Discretization in imaginary time $\Delta\tau.$

Algorithm

The propagator matrix $B_l$ above is given by

\[B_l = \Lambda_l \cdot \Gamma_l(\Delta\tau),\]

where, assuming the we are working in the orbital basis, $\Gamma_l(\Delta\tau) = e^{-\Delta\tau K_l}$ represents the exponentiated hopping matrix $K_l$, and $\Lambda_l = e^{-\Delta\tau V_l}$ represents the exponentiated diagonal on-site energy matrix $V_l.$

Given a proposed update to the $(i,i)$ matrix element of the diagonal on-site energy matrix $V_l$, ($V_{l,i,i} \rightarrow V^\prime_{l,i,i}),$ the corresponding determinant ratio associated with this proposed udpate is given by

\[R_{l,i} = \frac{\det G(\tau,\tau)}{\det G^\prime(\tau,\tau)} = 1+\Delta_{i,i}(\tau,i)\left(1-G_{i,i}(\tau,\tau)\right),\]

where

\[\Delta_{l,i} = \frac{\Lambda^\prime_{l,i,i}}{\Lambda_{l,i,i}} - 1 = e^{-\Delta\tau (V^\prime_{l,i,i} - V_{l,i,i})} - 1.\]

This routine returns the scalar quantities $R_{l,i}$ and $\Delta_{l,i}.$

Note that if the propagator matrix is instead represented using the symmetric form

\[B_l = \Gamma_l(\Delta\tau/2) \cdot \Lambda_l \cdot \Gamma^\dagger_l(\Delta\tau/2),\]

then the matrix G needs to instead represent the transformed equal-time Green's function matrix

\[\tilde{G}(\tau,\tau) = \Gamma_l^{-1}(\Delta\tau/2) \cdot G(\tau,\tau) \cdot \Gamma_l(\Delta\tau/2).\]

source
JDQMCFramework.local_update_greens!Function
local_update_greens!(
+)::Tuple{T,T} where {T,E}

Calculate the determinant ratio $R_{l,i}$ associated with a local update to the equal-time Green's function $G(\tau,\tau).$ Also returns $\Delta_{l,i},$ which is defined below.

Arguments

  • G::AbstractMatrix{T}: Equal-time Green's function matrix $G(\tau,\tau).$
  • B::AbstractPropagator{T,E}: Represents the propagator matrix $B_l,$ where $\tau = \Delta\tau \cdot l.$
  • V′::T: The new value for the $V^{\prime}_{l,i,i}$ matrix element in the diagonal on-site energy matrix $V_l.$
  • i::Int: Diagonal matrix element index in $V_l$ being updated.
  • Δτ::E: Discretization in imaginary time $\Delta\tau.$

Algorithm

The propagator matrix $B_l$ above is given by

\[B_l = \Lambda_l \cdot \Gamma_l(\Delta\tau),\]

where, assuming the we are working in the orbital basis, $\Gamma_l(\Delta\tau) = e^{-\Delta\tau K_l}$ represents the exponentiated hopping matrix $K_l$, and $\Lambda_l = e^{-\Delta\tau V_l}$ represents the exponentiated diagonal on-site energy matrix $V_l.$

Given a proposed update to the $(i,i)$ matrix element of the diagonal on-site energy matrix $V_l$, ($V_{l,i,i} \rightarrow V^\prime_{l,i,i}),$ the corresponding determinant ratio associated with this proposed udpate is given by

\[R_{l,i} = \frac{\det G(\tau,\tau)}{\det G^\prime(\tau,\tau)} = 1+\Delta_{i,i}(\tau,i)\left(1-G_{i,i}(\tau,\tau)\right),\]

where

\[\Delta_{l,i} = \frac{\Lambda^\prime_{l,i,i}}{\Lambda_{l,i,i}} - 1 = e^{-\Delta\tau (V^\prime_{l,i,i} - V_{l,i,i})} - 1.\]

This routine returns the scalar quantities $R_{l,i}$ and $\Delta_{l,i}.$

Note that if the propagator matrix is instead represented using the symmetric form

\[B_l = \Gamma_l(\Delta\tau/2) \cdot \Lambda_l \cdot \Gamma^\dagger_l(\Delta\tau/2),\]

then the matrix G needs to instead represent the transformed equal-time Green's function matrix

\[\tilde{G}(\tau,\tau) = \Gamma_l^{-1}(\Delta\tau/2) \cdot G(\tau,\tau) \cdot \Gamma_l(\Delta\tau/2).\]

source
JDQMCFramework.local_update_greens!Function
local_update_greens!(
     G::AbstractMatrix{T}, logdetG::E, sgndetG::T,
     B::AbstractPropagator{T},
     R::T, Δ::T, i::Int,
     u::AbstractVector{T}, v::AbstractVector{T}
-)::Tuple{E,T} where {T, E<:AbstractFloat}

Update the equal-time Green's function matrix G resulting from a local update in-place.

Arguments

  • G::AbstractMatrix{T}: Equal-time Green's function matrix $G(\tau,\tau)$ that will be updated in-place.
  • logdetG::E: The log of the absolute value of the initial Green's function matrix, $\log( \vert \det G(\tau,\tau) \vert ).$
  • sgndetG::T: The sign/phase of the determinant of the initial Green's function matrix, $\textrm{sign}( \det G(\tau,\tau) ).$
  • B::AbstractPropagator{T,E}: Propagator that needs to be updated to reflect accepted local update.
  • R::T: The determinant ratio $R_{l,i} = \frac{\det G(\tau,\tau)}{\det G^\prime(\tau,\tau)}.$
  • Δ::T: Change in the exponentiated on-site energy matrix, $\Delta_{l,i} = e^{-\Delta\tau (V^\prime_{l,(i,i)} - V_{l,(i,i)})} - 1.$
  • i::Int: Matrix element of diagonal on-site energy matrix $V_l$ that is being updated.
  • u::AbstractVector{T}: Vector of length size(G,1) that is used to avoid dynamic memory allocations.
  • v::AbstractVector{T}: Vector of length size(G,2) that is used to avoid dynamic memory allocations.

Algorithm

The equal-time Green's function matrix is updated using the relationship

\[G_{j,k}^{\prime}\left(\tau,\tau\right)=G_{j,k}\left(\tau,\tau\right)-\frac{1}{R_{l,i}}G_{j,i}\left(\tau,\tau\right)\Delta_{l,i}\left(\delta_{i,k}-G_{i,k}\left(\tau,\tau\right)\right).\]

The $B_l$ progpagator B is also udpated. Additionally, this method returns $\log( \vert \det G^\prime(\tau,\tau) \vert )$ and $\textrm{sign}( \det G^\prime(\tau,\tau) ).$

An important note is that if the propagator matrices are represented in a symmetric form, then G′ and G need to correspond to the transformed eqaul-time Green's function matrices $\tilde{G}^\prime(\tau,\tau)$ and $\tilde{G}(\tau,\tau).$ Refer to the local_update_det_ratio docstring for more information.

source
JDQMCFramework.partially_wrap_greens_forward!Function
partially_wrap_greens_forward!(
+)::Tuple{E,T} where {T, E<:AbstractFloat}

Update the equal-time Green's function matrix G resulting from a local update in-place.

Arguments

  • G::AbstractMatrix{T}: Equal-time Green's function matrix $G(\tau,\tau)$ that will be updated in-place.
  • logdetG::E: The log of the absolute value of the initial Green's function matrix, $\log( \vert \det G(\tau,\tau) \vert ).$
  • sgndetG::T: The sign/phase of the determinant of the initial Green's function matrix, $\textrm{sign}( \det G(\tau,\tau) ).$
  • B::AbstractPropagator{T,E}: Propagator that needs to be updated to reflect accepted local update.
  • R::T: The determinant ratio $R_{l,i} = \frac{\det G(\tau,\tau)}{\det G^\prime(\tau,\tau)}.$
  • Δ::T: Change in the exponentiated on-site energy matrix, $\Delta_{l,i} = e^{-\Delta\tau (V^\prime_{l,(i,i)} - V_{l,(i,i)})} - 1.$
  • i::Int: Matrix element of diagonal on-site energy matrix $V_l$ that is being updated.
  • u::AbstractVector{T}: Vector of length size(G,1) that is used to avoid dynamic memory allocations.
  • v::AbstractVector{T}: Vector of length size(G,2) that is used to avoid dynamic memory allocations.

Algorithm

The equal-time Green's function matrix is updated using the relationship

\[G_{j,k}^{\prime}\left(\tau,\tau\right)=G_{j,k}\left(\tau,\tau\right)-\frac{1}{R_{l,i}}G_{j,i}\left(\tau,\tau\right)\Delta_{l,i}\left(\delta_{i,k}-G_{i,k}\left(\tau,\tau\right)\right).\]

The $B_l$ progpagator B is also udpated. Additionally, this method returns $\log( \vert \det G^\prime(\tau,\tau) \vert )$ and $\textrm{sign}( \det G^\prime(\tau,\tau) ).$

An important note is that if the propagator matrices are represented in a symmetric form, then G′ and G need to correspond to the transformed eqaul-time Green's function matrices $\tilde{G}^\prime(\tau,\tau)$ and $\tilde{G}(\tau,\tau).$ Refer to the local_update_det_ratio docstring for more information.

source
JDQMCFramework.partially_wrap_greens_forward!Function
partially_wrap_greens_forward!(
     G::Matrix{T},
     B::P,
     M::Matrix{T} = similar(G)
-) where {T, E, P<:AbstractPropagator{T,E}}

If the propagator B is represented in the symmetric form

\[B_l = \Gamma_l(\Delta\tau/2) \cdot \Lambda_l(\Delta\tau) \cdot \Gamma_l^\dagger(\Delta\tau/2)\]

with $\tau = l \cdot \Delta\tau,$ where $\Gamma(\Delta\tau/2) = e^{-\Delta\tau K_l/2}$ and $\Lambda(\Delta\tau) = e^{-\Delta\tau V_l}$, then apply the transformation

\[\tilde{G}(\tau,\tau) = \Gamma^{-1}_l(\Delta\tau/2) \cdot G(\tau,\tau) \cdot \Gamma_l(\Delta\tau/2)\]

to the equal-time Green's function matrix G in-place.

source
JDQMCFramework.partially_wrap_greens_reverse!Function
partially_wrap_greens_reverse!(
+) where {T, E, P<:AbstractPropagator{T,E}}

If the propagator B is represented in the symmetric form

\[B_l = \Gamma_l(\Delta\tau/2) \cdot \Lambda_l(\Delta\tau) \cdot \Gamma_l^\dagger(\Delta\tau/2)\]

with $\tau = l \cdot \Delta\tau,$ where $\Gamma(\Delta\tau/2) = e^{-\Delta\tau K_l/2}$ and $\Lambda(\Delta\tau) = e^{-\Delta\tau V_l}$, then apply the transformation

\[\tilde{G}(\tau,\tau) = \Gamma^{-1}_l(\Delta\tau/2) \cdot G(\tau,\tau) \cdot \Gamma_l(\Delta\tau/2)\]

to the equal-time Green's function matrix G in-place.

source
JDQMCFramework.partially_wrap_greens_reverse!Function
partially_wrap_greens_reverse!(
     G::Matrix{T},
     B::P,
     M::Matrix{T} = similar(G)
-) where {T, E, P<:AbstractPropagator{T,E}}

If the propagator B is represented in the symmetric form

\[B_l = \Gamma_l(\Delta\tau/2) \cdot \Lambda_l(\Delta\tau) \cdot \Gamma_l^\dagger(\Delta\tau/2)\]

with $\tau = l \cdot \Delta\tau,$ where $\Gamma(\Delta\tau/2) = e^{-\Delta\tau K_l/2}$ and $\Lambda(\Delta\tau) = e^{-\Delta\tau V_l}$, then apply the transformation

\[G(\tau,\tau) = \Gamma_l(\Delta\tau/2) \cdot \tilde{G}(\tau,\tau) \cdot \Gamma_l^{-1}(\Delta\tau/2)\]

to the equal-time Green's function matrix G in-place.

source

Overloaded Functions

Base.iterateFunction
iterate(iter::FermionGreensCalculator)
+) where {T, E, P<:AbstractPropagator{T,E}}

If the propagator B is represented in the symmetric form

\[B_l = \Gamma_l(\Delta\tau/2) \cdot \Lambda_l(\Delta\tau) \cdot \Gamma_l^\dagger(\Delta\tau/2)\]

with $\tau = l \cdot \Delta\tau,$ where $\Gamma(\Delta\tau/2) = e^{-\Delta\tau K_l/2}$ and $\Lambda(\Delta\tau) = e^{-\Delta\tau V_l}$, then apply the transformation

\[G(\tau,\tau) = \Gamma_l(\Delta\tau/2) \cdot \tilde{G}(\tau,\tau) \cdot \Gamma_l^{-1}(\Delta\tau/2)\]

to the equal-time Green's function matrix G in-place.

source

Overloaded Functions

Base.iterateFunction
iterate(iter::FermionGreensCalculator)
 
-iterate(iter::FermionGreensCalculator, state)

Iterate over imaginary time slices, alternating between iterating in the forward direction from $l=1$ to $l=L_\tau$ and in the reverse direction from $l=L_\tau$ to $l=1$. The iter.forward boolean field in the FermionGreensCalculator type determines whether the imaginary time slices are iterated over in forward or reverse order. The iter.forward field is updated as needed automatically and should not be adjusted manually.

source
Base.eltypeFunction
eltype(B::AbstractPropagator{T,E}) where {T,E}

Return the matrix element type of the propagator T.

source
eltype(fgc::FermionGreensCalculator{T,E}) where {T,E}

Return matrix element type T associated with an instance of FermionGreensCalculator.

source
Base.resize!Function
resize!(
+iterate(iter::FermionGreensCalculator, state)

Iterate over imaginary time slices, alternating between iterating in the forward direction from $l=1$ to $l=L_\tau$ and in the reverse direction from $l=L_\tau$ to $l=1$. The iter.forward boolean field in the FermionGreensCalculator type determines whether the imaginary time slices are iterated over in forward or reverse order. The iter.forward field is updated as needed automatically and should not be adjusted manually.

source
Base.eltypeFunction
eltype(B::AbstractPropagator{T,E}) where {T,E}

Return the matrix element type of the propagator T.

source
eltype(fgc::FermionGreensCalculator{T,E}) where {T,E}

Return matrix element type T associated with an instance of FermionGreensCalculator.

source
Base.resize!Function
resize!(
     fgc::FermionGreensCalculator{T,E},
     G::Matrix{T}, logdetG::E, sgndetG::T,
     B::Vector{P}, n_stab::Int
@@ -83,32 +83,32 @@
 
 resize!(
     fgc::FermionGreensCalculator{T,E}, n_stab::Int
-) where {T,E}

Update fgc to reflect a new stabilizaiton frequency n_stab. If G, logdetG, sgndetG and B are also passed then the equal-time Green's function G is re-calculated and the corresponding updated values for (logdetG, sgndetG) are returned.

source
Base.sizeFunction
size(B::AbstractPropagator)
+) where {T,E}

Update fgc to reflect a new stabilizaiton frequency n_stab. If G, logdetG, sgndetG and B are also passed then the equal-time Green's function G is re-calculated and the corresponding updated values for (logdetG, sgndetG) are returned.

source
Base.sizeFunction
size(B::AbstractPropagator)
 
-size(B::AbstractPropagator, dim)

Return the size of a propagator.

source
Base.copyto!Function
copyto!(B′::SymExactPropagator{T,E}, B::SymExactPropagator{T,E}) where {T,E}
+size(B::AbstractPropagator, dim)

Return the size of a propagator.

source
Base.copyto!Function
copyto!(B′::SymExactPropagator{T,E}, B::SymExactPropagator{T,E}) where {T,E}
 
 copyto!(B′::AsymExactPropagator{T,E}, B::AsymExactPropagator{T,E}) where {T,E}
 
 copyto!(B′::SymChkbrdPropagator{T,E}, B::SymChkbrdPropagator{T,E}) where {T,E}
 
-copyto!(B′::AsymChkbrdPropagator{T,E}, B::AsymChkbrdPropagator{T,E}) where {T,E}

Copy the propagator B to B′.

source
copyto!(
+copyto!(B′::AsymChkbrdPropagator{T,E}, B::AsymChkbrdPropagator{T,E}) where {T,E}

Copy the propagator B to B′.

source
copyto!(
     fgc_out::FermionGreensCalculator{T,E},
     fgc_in::FermionGreensCalculator{T,E}
-) where {T,E}

Copy the contents of fgc_in to fgc_out. If fgc_out.n_stab != fgc_in.n_stab is true, then fgc_out will be resized using resize! to match fgc_in.

source
LinearAlgebra.mul!Function
mul!(A::AbstractMatrix{T}, B::SymExactPropagator{T}, C::AbstractMatrix{T};
+) where {T,E}

Copy the contents of fgc_in to fgc_out. If fgc_out.n_stab != fgc_in.n_stab is true, then fgc_out will be resized using resize! to match fgc_in.

source
LinearAlgebra.mul!Function
mul!(A::AbstractMatrix{T}, B::SymExactPropagator{T}, C::AbstractMatrix{T};
      M::AbstractMatrix{T}=similar(A)) where {T}
 
 mul!(A::AbstractMatrix{T}, B::AsymExactPropagator{T}, C::AbstractMatrix{T};
      M::AbstractMatrix{T}=similar(A)) where {T}
 
 mul!(A::AbstractMatrix{T}, B::AbstractChkbrdPropagator{T}, C::AbstractMatrix{T};
-     M=nothing) where {T}

Calculate the product $A := B \cdot C$, where $B$ is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then $A = B^\dagger \cdot C$ is evaluated instead.

source
mul!(A::AbstractMatrix{T}, C::AbstractMatrix{T}, B::SymExactPropagator{T};
+     M=nothing) where {T}

Calculate the product $A := B \cdot C$, where $B$ is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then $A = B^\dagger \cdot C$ is evaluated instead.

source
mul!(A::AbstractMatrix{T}, C::AbstractMatrix{T}, B::SymExactPropagator{T};
      M::AbstractMatrix{T} = similar(A)) where {T}
 
 mul!(A::AbstractMatrix{T}, C::AbstractMatrix{T}, B::AsymExactPropagator{T};
      M::AbstractMatrix{T} = similar(A)) where {T}
 
 mul!(A::AbstractMatrix{T}, C::AbstractMatrix{T}, B::AbstractChkbrdPropagator{T};
-     M=nothing) where {T}

Calculate the matrix product $A := C \cdot B$, where $B$ is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then $A = C \cdot B^\dagger$ is evaluated instead.

source
LinearAlgebra.lmul!Function
lmul!(B::SymExactPropagator{T}, A::AbstractMatrix{T};
+     M=nothing) where {T}

Calculate the matrix product $A := C \cdot B$, where $B$ is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then $A = C \cdot B^\dagger$ is evaluated instead.

source
LinearAlgebra.lmul!Function
lmul!(B::SymExactPropagator{T}, A::AbstractMatrix{T};
       M::AbstractMatrix{T} = similar(A)) where {T}
 
 lmul!(B::AsymExactPropagator{T}, A::AbstractMatrix{T};
@@ -118,7 +118,7 @@
       M::AbstractMatrix{T} = similar(A)) where {T}
 
 lmul!(B::AsymChkbrdPropagator{T}, A::AbstractMatrix{T};
-      M = nothing) where {T}

Calculate the matrix product $A := B \cdot A$, where $B$ is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, when $A := B^\dagger \cdot A$ is evaluated instead.

source
LinearAlgebra.rmul!Function
rmul!(A::AbstractMatrix{T}, B::SymExactPropagator{T};
+      M = nothing) where {T}

Calculate the matrix product $A := B \cdot A$, where $B$ is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, when $A := B^\dagger \cdot A$ is evaluated instead.

source
LinearAlgebra.rmul!Function
rmul!(A::AbstractMatrix{T}, B::SymExactPropagator{T};
       M::AbstractMatrix{T} = similar(A)) where {T}
 
 rmul!(A::AbstractMatrix{T}, B::AsymExactPropagator{T};
@@ -128,11 +128,11 @@
       M = nothing) where {T}
 
 rmul!(A::AbstractMatrix{T}, B::AsymChkbrdPropagator{T};
-      M = nothing) where {T}

Calculate the matrix product $A := A \cdot B$, where $B$ is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then $A := A \cdot B^\dagger$ is evaluated instead.

source
LinearAlgebra.ldiv!Function
ldiv!(A::AbstractMatrix{T}, B::AbstractExactPropagator{T}, C::AbstractMatrix{T};
+      M = nothing) where {T}

Calculate the matrix product $A := A \cdot B$, where $B$ is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then $A := A \cdot B^\dagger$ is evaluated instead.

source
LinearAlgebra.ldiv!Function
ldiv!(A::AbstractMatrix{T}, B::AbstractExactPropagator{T}, C::AbstractMatrix{T};
       M::AbstractMatrix{T} = similar(A)) where {T}
 
 ldiv!(A::AbstractMatrix{T}, B::AbstractChkbrdPropagator{T}, C::AbstractMatrix{T};
-      M = nothing) where {T}

Calculate the matrix product $A := B^{-1} \cdot C$, where $B$ is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then $A = [B^\dagger]^{-1} \cdot C$ is evaluated instead.

source
ldiv!(B::SymExactPropagator{T}, A::AbstractMatrix{T};
+      M = nothing) where {T}

Calculate the matrix product $A := B^{-1} \cdot C$, where $B$ is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then $A = [B^\dagger]^{-1} \cdot C$ is evaluated instead.

source
ldiv!(B::SymExactPropagator{T}, A::AbstractMatrix{T};
       M::AbstractMatrix{T} = similar(A)) where {T}
 
 ldiv!(B::AsymExactPropagator{T}, A::AbstractMatrix{T};
@@ -142,11 +142,11 @@
       M = nothing) where {T}
 
 ldiv!(B::AsymChkbrdPropagator{T}, A::AbstractMatrix{T};
-      M = nothing) where {T}

Calculate the matrix product $A := B^{-1} \cdot A$, where $B$ is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then $A := [B^\dagger]^{-1} \cdot A$ is evaluated instead.

source
LinearAlgebra.rdiv!Function
rldiv!(A::AbstractMatrix{T}, C::AbstractMatrix{T}, B::AbstractExactPropagator{T};
+      M = nothing) where {T}

Calculate the matrix product $A := B^{-1} \cdot A$, where $B$ is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then $A := [B^\dagger]^{-1} \cdot A$ is evaluated instead.

source
LinearAlgebra.rdiv!Function
rldiv!(A::AbstractMatrix{T}, C::AbstractMatrix{T}, B::AbstractExactPropagator{T};
       M::AbstractMatrix{T} = similar(A)) where {T}
 
 rdiv!(A::AbstractMatrix{T}, C::AbstractMatrix{T}, B::AbstractChkbrdPropagator{T};
-      M = nothing) where {T}

Calculate the matrix product $A := C \cdot B^{-1}$, where $B$ is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B is asymmetric and B.adjointed = true, then $A = C \cdot [B^\dagger]^{-1}$ is evaluated instead.

source
rdiv!(A::AbstractMatrix{T}, B::SymExactPropagator{T};
+      M = nothing) where {T}

Calculate the matrix product $A := C \cdot B^{-1}$, where $B$ is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B is asymmetric and B.adjointed = true, then $A = C \cdot [B^\dagger]^{-1}$ is evaluated instead.

source
rdiv!(A::AbstractMatrix{T}, B::SymExactPropagator{T};
       M::AbstractMatrix{T} = similar(A)) where {T}
 
 rdiv!(A::AbstractMatrix{T}, B::AsymExactPropagator{T};
@@ -156,38 +156,38 @@
       M = nothing) where {T}
 
 rdiv!(A::AbstractMatrix{T}, B::AsymChkbrdPropagator{T};
-      M = nothing) where {T}

Calculate the matrix product $A := A \cdot B^{-1}$, where $B$ is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then $A := A \cdot [B^\dagger]^{-1}$ is evaluated instead.

source

Utility Functions

JDQMCFramework.eval_length_imaginary_axisFunction
eval_length_imaginary_axis(
+      M = nothing) where {T}

Calculate the matrix product $A := A \cdot B^{-1}$, where $B$ is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then $A := A \cdot [B^\dagger]^{-1}$ is evaluated instead.

source

Utility Functions

JDQMCFramework.eval_length_imaginary_axisFunction
eval_length_imaginary_axis(
     β::T,
     Δτ::T
-)::Int where {T<:AbstractFloat}

Given an inverse temperature β and discretization in imaginary time Δτ, return the length of the imaginary time axis .

source
JDQMCFramework.exp!Function
exp!(
+)::Int where {T<:AbstractFloat}

Given an inverse temperature β and discretization in imaginary time Δτ, return the length of the imaginary time axis .

source
JDQMCFramework.exp!Function
exp!(
     expαH::AbstractMatrix{T},
     H::AbstractMatrix{T},
     α::E;
     # KEYWORD ARGUMENTS
     workspace::HermitianEigenWs{T,Matrix{T},R} = HermitianEigenWs(H),
     tol::R = 1e-6
-) where {T<:Number, E<:Number, R<:AbstractFloat}

Given a Hermitian matrix H, calculate the matrix exponentials $e^{\alpha H}.$ Note that H is left modified by this method. The workspace field is of type HermitianEigenWs, which is exported from the FastLapackInterface.jl package, is used to avoid dynamic memory allocations.

source
exp!(
+) where {T<:Number, E<:Number, R<:AbstractFloat}

Given a Hermitian matrix H, calculate the matrix exponentials $e^{\alpha H}.$ Note that H is left modified by this method. The workspace field is of type HermitianEigenWs, which is exported from the FastLapackInterface.jl package, is used to avoid dynamic memory allocations.

source
exp!(
     exppαH::AbstractMatrix{T},
     expmαH::AbstractMatrix{T},
     H::AbstractMatrix{T}, α::E;
     # KEYWORD ARGUMENTS
     workspace::HermitianEigenWs{T,Matrix{T},R} = HermitianEigenWs(H),
     tol::R = 1e-6
-) where {T<:Number, E<:Number, R<:AbstractFloat}

Given a Hermitian matrix H, calculate the matrix exponentials $e^{+\alpha H}$ and $e^{-\alpha H}$, which are written to exppαH and expmαH respectively. Note that H is left modified by this method. The workspace field is of type HermitianEigenWs, which is exported from the FastLapackInterface.jl package, is used to avoid dynamic memory allocations.

source
JDQMCFramework.build_hopping_matrix!Function
build_hopping_matrix!(
+) where {T<:Number, E<:Number, R<:AbstractFloat}

Given a Hermitian matrix H, calculate the matrix exponentials $e^{+\alpha H}$ and $e^{-\alpha H}$, which are written to exppαH and expmαH respectively. Note that H is left modified by this method. The workspace field is of type HermitianEigenWs, which is exported from the FastLapackInterface.jl package, is used to avoid dynamic memory allocations.

source
JDQMCFramework.build_hopping_matrix!Function
build_hopping_matrix!(
     K::AbstractMatrix{T},
     neighbor_table::Matrix{Int},
     t::AbstractVector{T}
-) where {T<:Continuous}

Construct a hopping matrix K using neighbor_table along with the corresponding hopping amplitudes t. Each column of neighbor_table stores a pair of neighboring orbitals in the lattice, such that size(neighbor_table,1) = 2.

source

Developer API

JDQMCFramework.ContinuousType
Continuous = Union{AbstractFloat,Complex{<:AbstractFloat}}

An abstract type to represent continuous real and complex numbers.

source
JDQMCFramework.update_factorizations!Function
update_factorizations!(
+) where {T<:Continuous}

Construct a hopping matrix K using neighbor_table along with the corresponding hopping amplitudes t. Each column of neighbor_table stores a pair of neighboring orbitals in the lattice, such that size(neighbor_table,1) = 2.

source

Developer API

JDQMCFramework.ContinuousType
Continuous = Union{AbstractFloat,Complex{<:AbstractFloat}}

An abstract type to represent continuous real and complex numbers.

source
JDQMCFramework.update_factorizations!Function
update_factorizations!(
     fgc::FermionGreensCalculator{T,E},
     B::AbstractVector{P}
-) where {T, E, P<:AbstractPropagator{T}}

If current imaginary time slice fgc.l corresponds to the boundary of a stabilization interval, calculate a LDR factorization to represent $B(0, \tau)$ or $B(\tau-\Delta\tau, \beta)$ if iterating over imaginary time in the forward (fgc.forward = true) or reverse (fgc.forward = false) directions respectively. This method should be called after all changes to the current time slice propagator matrix $B_l$ have been made This method will also recompute $\bar{B}_n$ as needed.

source
update_factorizations!(
+) where {T, E, P<:AbstractPropagator{T}}

If current imaginary time slice fgc.l corresponds to the boundary of a stabilization interval, calculate a LDR factorization to represent $B(0, \tau)$ or $B(\tau-\Delta\tau, \beta)$ if iterating over imaginary time in the forward (fgc.forward = true) or reverse (fgc.forward = false) directions respectively. This method should be called after all changes to the current time slice propagator matrix $B_l$ have been made This method will also recompute $\bar{B}_n$ as needed.

source
update_factorizations!(
     fgc::FermionGreensCalculator{T,E}
-) where {T, E}

If current imaginary time slice fgc.l corresponds to the boundary of a stabilization interval, calculate a LDR factorization to represent $B(\tau, 0)$ or $B(\beta, \tau-\Delta\tau)$ if iterating over imaginary time in the forward (fgc.forward = true) or reverse (fgc.forward = false) directions respectively. This method should be called after all changes to the current time slice propagator matrix $B_l$ have been made, and any required updates to a $\bar{B}_n$ matrix have been performed using the JDQMCFramework.update_B̄! routine.

source
JDQMCFramework.update_B̄!Function
update_B̄!(
+) where {T, E}

If current imaginary time slice fgc.l corresponds to the boundary of a stabilization interval, calculate a LDR factorization to represent $B(\tau, 0)$ or $B(\beta, \tau-\Delta\tau)$ if iterating over imaginary time in the forward (fgc.forward = true) or reverse (fgc.forward = false) directions respectively. This method should be called after all changes to the current time slice propagator matrix $B_l$ have been made, and any required updates to a $\bar{B}_n$ matrix have been performed using the JDQMCFramework.update_B̄! routine.

source
JDQMCFramework.update_B̄!Function
update_B̄!(
     fgc::FermionGreensCalculator{T,E},
     B::AbstractVector{P}
-) where {T,E,P<:AbstractPropagator{T}}

Recalculate $\bar{B}_n$ if the current timeslice fgc.l corresponds to the boundary of a stabilization interval, accounting for whether imaginary time is being iterated over in the forward (fgc.forward = true) or reverse (fgc.forward = false) direction.

source
JDQMCFramework.calculate_B̄!Function
calculate_B̄!(
+) where {T,E,P<:AbstractPropagator{T}}

Recalculate $\bar{B}_n$ if the current timeslice fgc.l corresponds to the boundary of a stabilization interval, accounting for whether imaginary time is being iterated over in the forward (fgc.forward = true) or reverse (fgc.forward = false) direction.

source
JDQMCFramework.calculate_B̄!Function
calculate_B̄!(
     fgc::FermionGreensCalculator{T,E},
     B::AbstractVector{P}, n::Int
-) where {T,E,P<:AbstractPropagator{T}}

Given B, a vector of all the propagator matrices $B_l$, calculate the matrix product

\[\bar{B}_{\sigma,n}=\prod_{l=(n-1)\cdot n_{s}+1}^{\min(n\cdot n_{s},L_{\tau})}B_{\sigma,l},\]

with the result getting written to fgc.B_bar[n].

source
JDQMCFramework.stabilization_intervalFunction
stabilization_interval(
+) where {T,E,P<:AbstractPropagator{T}}

Given B, a vector of all the propagator matrices $B_l$, calculate the matrix product

\[\bar{B}_{\sigma,n}=\prod_{l=(n-1)\cdot n_{s}+1}^{\min(n\cdot n_{s},L_{\tau})}B_{\sigma,l},\]

with the result getting written to fgc.B_bar[n].

source
JDQMCFramework.stabilization_intervalFunction
stabilization_interval(
     fgc::FermionGreensCalculator
-)::Tuple{Int,Int}

Given the current imaginary time slice fgc.l, return the corresponding stabilization interval n = ceil(Int, fgc.l/fgc.n_stab), and the relative location within that stabilization interval l′ = mod1(fgc.l, fgc.n_stab), such that l′∈[1,n_stab].

source
+)::Tuple{Int,Int}

Given the current imaginary time slice fgc.l, return the corresponding stabilization interval n = ceil(Int, fgc.l/fgc.n_stab), and the relative location within that stabilization interval l′ = mod1(fgc.l, fgc.n_stab), such that l′∈[1,n_stab].

source
diff --git a/dev/assets/documenter.js b/dev/assets/documenter.js index f531160..c6562b5 100644 --- a/dev/assets/documenter.js +++ b/dev/assets/documenter.js @@ -4,7 +4,6 @@ requirejs.config({ 'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/julia.min', 'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/headroom.min', 'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min', - 'minisearch': 'https://cdn.jsdelivr.net/npm/minisearch@6.1.0/dist/umd/index.min', 'katex-auto-render': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.8/contrib/auto-render.min', 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min', 'headroom-jquery': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/jQuery.headroom.min', @@ -103,9 +102,10 @@ $(document).on("click", ".docstring header", function () { }); }); -$(document).on("click", ".docs-article-toggle-button", function () { +$(document).on("click", ".docs-article-toggle-button", function (event) { let articleToggleTitle = "Expand docstring"; let navArticleToggleTitle = "Expand all docstrings"; + let animationSpeed = event.noToggleAnimation ? 0 : 400; debounce(() => { if (isExpanded) { @@ -116,7 +116,7 @@ $(document).on("click", ".docs-article-toggle-button", function () { isExpanded = false; - $(".docstring section").slideUp(); + $(".docstring section").slideUp(animationSpeed); } else { $(this).removeClass("fa-chevron-down").addClass("fa-chevron-up"); $(".docstring-article-toggle-button") @@ -127,7 +127,7 @@ $(document).on("click", ".docs-article-toggle-button", function () { articleToggleTitle = "Collapse docstring"; navArticleToggleTitle = "Collapse all docstrings"; - $(".docstring section").slideDown(); + $(".docstring section").slideDown(animationSpeed); } $(this).prop("title", navArticleToggleTitle); @@ -224,224 +224,465 @@ $(document).ready(function () { }) //////////////////////////////////////////////////////////////////////////////// -require(['jquery', 'minisearch'], function($, minisearch) { - -// In general, most search related things will have "search" as a prefix. -// To get an in-depth about the thought process you can refer: https://hetarth02.hashnode.dev/series/gsoc +require(['jquery'], function($) { -let results = []; -let timer = undefined; +$(document).ready(function () { + let meta = $("div[data-docstringscollapsed]").data(); -let data = documenterSearchIndex["docs"].map((x, key) => { - x["id"] = key; // minisearch requires a unique for each object - return x; + if (meta?.docstringscollapsed) { + $("#documenter-article-toggle-button").trigger({ + type: "click", + noToggleAnimation: true, + }); + } }); -// list below is the lunr 2.1.3 list minus the intersect with names(Base) -// (all, any, get, in, is, only, which) and (do, else, for, let, where, while, with) -// ideally we'd just filter the original list but it's not available as a variable -const stopWords = new Set([ - "a", - "able", - "about", - "across", - "after", - "almost", - "also", - "am", - "among", - "an", - "and", - "are", - "as", - "at", - "be", - "because", - "been", - "but", - "by", - "can", - "cannot", - "could", - "dear", - "did", - "does", - "either", - "ever", - "every", - "from", - "got", - "had", - "has", - "have", - "he", - "her", - "hers", - "him", - "his", - "how", - "however", - "i", - "if", - "into", - "it", - "its", - "just", - "least", - "like", - "likely", - "may", - "me", - "might", - "most", - "must", - "my", - "neither", - "no", - "nor", - "not", - "of", - "off", - "often", - "on", - "or", - "other", - "our", - "own", - "rather", - "said", - "say", - "says", - "she", - "should", - "since", - "so", - "some", - "than", - "that", - "the", - "their", - "them", - "then", - "there", - "these", - "they", - "this", - "tis", - "to", - "too", - "twas", - "us", - "wants", - "was", - "we", - "were", - "what", - "when", - "who", - "whom", - "why", - "will", - "would", - "yet", - "you", - "your", -]); - -let index = new minisearch({ - fields: ["title", "text"], // fields to index for full-text search - storeFields: ["location", "title", "text", "category", "page"], // fields to return with search results - processTerm: (term) => { - let word = stopWords.has(term) ? null : term; - if (word) { - // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names - word = word - .replace(/^[^a-zA-Z0-9@!]+/, "") - .replace(/[^a-zA-Z0-9@!]+$/, ""); - } +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { - return word ?? null; - }, - // add . as a separator, because otherwise "title": "Documenter.Anchors.add!", would not find anything if searching for "add!", only for the entire qualification - tokenize: (string) => string.split(/[\s\-\.]+/), - // options which will be applied during the search - searchOptions: { - boost: { title: 100 }, - fuzzy: 2, +/* +To get an in-depth about the thought process you can refer: https://hetarth02.hashnode.dev/series/gsoc + +PSEUDOCODE: + +Searching happens automatically as the user types or adjusts the selected filters. +To preserve responsiveness, as much as possible of the slow parts of the search are done +in a web worker. Searching and result generation are done in the worker, and filtering and +DOM updates are done in the main thread. The filters are in the main thread as they should +be very quick to apply. This lets filters be changed without re-searching with minisearch +(which is possible even if filtering is on the worker thread) and also lets filters be +changed _while_ the worker is searching and without message passing (neither of which are +possible if filtering is on the worker thread) + +SEARCH WORKER: + +Import minisearch + +Build index + +On message from main thread + run search + find the first 200 unique results from each category, and compute their divs for display + note that this is necessary and sufficient information for the main thread to find the + first 200 unique results from any given filter set + post results to main thread + +MAIN: + +Launch worker + +Declare nonconstant globals (worker_is_running, last_search_text, unfiltered_results) + +On text update + if worker is not running, launch_search() + +launch_search + set worker_is_running to true, set last_search_text to the search text + post the search query to worker + +on message from worker + if last_search_text is not the same as the text in the search field, + the latest search result is not reflective of the latest search query, so update again + launch_search() + otherwise + set worker_is_running to false + + regardless, display the new search results to the user + save the unfiltered_results as a global + update_search() + +on filter click + adjust the filter selection + update_search() + +update_search + apply search filters by looping through the unfiltered_results and finding the first 200 + unique results that match the filters + + Update the DOM +*/ + +/////// SEARCH WORKER /////// + +function worker_function(documenterSearchIndex, documenterBaseURL, filters) { + importScripts( + "https://cdn.jsdelivr.net/npm/minisearch@6.1.0/dist/umd/index.min.js" + ); + + let data = documenterSearchIndex.map((x, key) => { + x["id"] = key; // minisearch requires a unique for each object + return x; + }); + + // list below is the lunr 2.1.3 list minus the intersect with names(Base) + // (all, any, get, in, is, only, which) and (do, else, for, let, where, while, with) + // ideally we'd just filter the original list but it's not available as a variable + const stopWords = new Set([ + "a", + "able", + "about", + "across", + "after", + "almost", + "also", + "am", + "among", + "an", + "and", + "are", + "as", + "at", + "be", + "because", + "been", + "but", + "by", + "can", + "cannot", + "could", + "dear", + "did", + "does", + "either", + "ever", + "every", + "from", + "got", + "had", + "has", + "have", + "he", + "her", + "hers", + "him", + "his", + "how", + "however", + "i", + "if", + "into", + "it", + "its", + "just", + "least", + "like", + "likely", + "may", + "me", + "might", + "most", + "must", + "my", + "neither", + "no", + "nor", + "not", + "of", + "off", + "often", + "on", + "or", + "other", + "our", + "own", + "rather", + "said", + "say", + "says", + "she", + "should", + "since", + "so", + "some", + "than", + "that", + "the", + "their", + "them", + "then", + "there", + "these", + "they", + "this", + "tis", + "to", + "too", + "twas", + "us", + "wants", + "was", + "we", + "were", + "what", + "when", + "who", + "whom", + "why", + "will", + "would", + "yet", + "you", + "your", + ]); + + let index = new MiniSearch({ + fields: ["title", "text"], // fields to index for full-text search + storeFields: ["location", "title", "text", "category", "page"], // fields to return with results processTerm: (term) => { let word = stopWords.has(term) ? null : term; if (word) { + // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names word = word .replace(/^[^a-zA-Z0-9@!]+/, "") .replace(/[^a-zA-Z0-9@!]+$/, ""); + + word = word.toLowerCase(); } return word ?? null; }, + // add . as a separator, because otherwise "title": "Documenter.Anchors.add!", would not + // find anything if searching for "add!", only for the entire qualification tokenize: (string) => string.split(/[\s\-\.]+/), - }, -}); + // options which will be applied during the search + searchOptions: { + prefix: true, + boost: { title: 100 }, + fuzzy: 2, + }, + }); -index.addAll(data); + index.addAll(data); + + /** + * Used to map characters to HTML entities. + * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts + */ + const htmlEscapes = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'", + }; + + /** + * Used to match HTML entities and HTML characters. + * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts + */ + const reUnescapedHtml = /[&<>"']/g; + const reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** + * Escape function from lodash + * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts + */ + function escape(string) { + return string && reHasUnescapedHtml.test(string) + ? string.replace(reUnescapedHtml, (chr) => htmlEscapes[chr]) + : string || ""; + } -let filters = [...new Set(data.map((x) => x.category))]; -var modal_filters = make_modal_body_filters(filters); -var filter_results = []; + /** + * Make the result component given a minisearch result data object and the value + * of the search input as queryString. To view the result object structure, refer: + * https://lucaong.github.io/minisearch/modules/_minisearch_.html#searchresult + * + * @param {object} result + * @param {string} querystring + * @returns string + */ + function make_search_result(result, querystring) { + let search_divider = `
`; + let display_link = + result.location.slice(Math.max(0), Math.min(50, result.location.length)) + + (result.location.length > 30 ? "..." : ""); // To cut-off the link because it messes with the overflow of the whole div + + if (result.page !== "") { + display_link += ` (${result.page})`; + } -$(document).on("keyup", ".documenter-search-input", function (event) { - // Adding a debounce to prevent disruptions from super-speed typing! - debounce(() => update_search(filter_results), 300); + let textindex = new RegExp(`${querystring}`, "i").exec(result.text); + let text = + textindex !== null + ? result.text.slice( + Math.max(textindex.index - 100, 0), + Math.min( + textindex.index + querystring.length + 100, + result.text.length + ) + ) + : ""; // cut-off text before and after from the match + + text = text.length ? escape(text) : ""; + + let display_result = text.length + ? "..." + + text.replace( + new RegExp(`${escape(querystring)}`, "i"), // For first occurrence + '$&' + ) + + "..." + : ""; // highlights the match + + let in_code = false; + if (!["page", "section"].includes(result.category.toLowerCase())) { + in_code = true; + } + + // We encode the full url to escape some special characters which can lead to broken links + let result_div = ` + +
+
${escape(result.title)}
+
${result.category}
+
+

+ ${display_result} +

+
+ ${display_link} +
+
+ ${search_divider} + `; + + return result_div; + } + + self.onmessage = function (e) { + let query = e.data; + let results = index.search(query, { + filter: (result) => { + // Only return relevant results + return result.score >= 1; + }, + }); + + // Pre-filter to deduplicate and limit to 200 per category to the extent + // possible without knowing what the filters are. + let filtered_results = []; + let counts = {}; + for (let filter of filters) { + counts[filter] = 0; + } + let present = {}; + + for (let result of results) { + cat = result.category; + cnt = counts[cat]; + if (cnt < 200) { + id = cat + "---" + result.location; + if (present[id]) { + continue; + } + present[id] = true; + filtered_results.push({ + location: result.location, + category: cat, + div: make_search_result(result, query), + }); + } + } + + postMessage(filtered_results); + }; +} + +// `worker = Threads.@spawn worker_function(documenterSearchIndex)`, but in JavaScript! +const filters = [ + ...new Set(documenterSearchIndex["docs"].map((x) => x.category)), +]; +const worker_str = + "(" + + worker_function.toString() + + ")(" + + JSON.stringify(documenterSearchIndex["docs"]) + + "," + + JSON.stringify(documenterBaseURL) + + "," + + JSON.stringify(filters) + + ")"; +const worker_blob = new Blob([worker_str], { type: "text/javascript" }); +const worker = new Worker(URL.createObjectURL(worker_blob)); + +/////// SEARCH MAIN /////// + +// Whether the worker is currently handling a search. This is a boolean +// as the worker only ever handles 1 or 0 searches at a time. +var worker_is_running = false; + +// The last search text that was sent to the worker. This is used to determine +// if the worker should be launched again when it reports back results. +var last_search_text = ""; + +// The results of the last search. This, in combination with the state of the filters +// in the DOM, is used compute the results to display on calls to update_search. +var unfiltered_results = []; + +// Which filter is currently selected +var selected_filter = ""; + +$(document).on("input", ".documenter-search-input", function (event) { + if (!worker_is_running) { + launch_search(); + } }); +function launch_search() { + worker_is_running = true; + last_search_text = $(".documenter-search-input").val(); + worker.postMessage(last_search_text); +} + +worker.onmessage = function (e) { + if (last_search_text !== $(".documenter-search-input").val()) { + launch_search(); + } else { + worker_is_running = false; + } + + unfiltered_results = e.data; + update_search(); +}; + $(document).on("click", ".search-filter", function () { if ($(this).hasClass("search-filter-selected")) { - $(this).removeClass("search-filter-selected"); + selected_filter = ""; } else { - $(this).addClass("search-filter-selected"); + selected_filter = $(this).text().toLowerCase(); } - // Adding a debounce to prevent disruptions from crazy clicking! - debounce(() => get_filters(), 300); + // This updates search results and toggles classes for UI: + update_search(); }); -/** - * A debounce function, takes a function and an optional timeout in milliseconds - * - * @function callback - * @param {number} timeout - */ -function debounce(callback, timeout = 300) { - clearTimeout(timer); - timer = setTimeout(callback, timeout); -} - /** * Make/Update the search component - * - * @param {string[]} selected_filters */ -function update_search(selected_filters = []) { - let initial_search_body = ` -
Type something to get started!
- `; - +function update_search() { let querystring = $(".documenter-search-input").val(); if (querystring.trim()) { - results = index.search(querystring, { - filter: (result) => { - // Filtering results - if (selected_filters.length === 0) { - return result.score >= 1; - } else { - return ( - result.score >= 1 && selected_filters.includes(result.category) - ); - } - }, - }); + if (selected_filter == "") { + results = unfiltered_results; + } else { + results = unfiltered_results.filter((result) => { + return selected_filter == result.category.toLowerCase(); + }); + } let search_result_container = ``; + let modal_filters = make_modal_body_filters(); let search_divider = `
`; if (results.length) { @@ -449,19 +690,23 @@ function update_search(selected_filters = []) { let count = 0; let search_results = ""; - results.forEach(function (result) { - if (result.location) { - // Checking for duplication of results for the same page - if (!links.includes(result.location)) { - search_results += make_search_result(result, querystring); - count++; - } - + for (var i = 0, n = results.length; i < n && count < 200; ++i) { + let result = results[i]; + if (result.location && !links.includes(result.location)) { + search_results += result.div; + count++; links.push(result.location); } - }); + } - let result_count = `
${count} result(s)
`; + if (count == 1) { + count_str = "1 result"; + } else if (count == 200) { + count_str = "200+ results"; + } else { + count_str = count + " results"; + } + let result_count = `
${count_str}
`; search_result_container = `
@@ -490,125 +735,37 @@ function update_search(selected_filters = []) { $(".search-modal-card-body").html(search_result_container); } else { - filter_results = []; - modal_filters = make_modal_body_filters(filters, filter_results); - if (!$(".search-modal-card-body").hasClass("is-justify-content-center")) { $(".search-modal-card-body").addClass("is-justify-content-center"); } - $(".search-modal-card-body").html(initial_search_body); + $(".search-modal-card-body").html(` +
Type something to get started!
+ `); } } /** * Make the modal filter html * - * @param {string[]} filters - * @param {string[]} selected_filters * @returns string */ -function make_modal_body_filters(filters, selected_filters = []) { - let str = ``; - - filters.forEach((val) => { - if (selected_filters.includes(val)) { - str += `${val}`; - } else { - str += `${val}`; - } - }); +function make_modal_body_filters() { + let str = filters + .map((val) => { + if (selected_filter == val.toLowerCase()) { + return `${val}`; + } else { + return `${val}`; + } + }) + .join(""); - let filter_html = ` + return `
Filters: ${str} -
- `; - - return filter_html; -} - -/** - * Make the result component given a minisearch result data object and the value of the search input as queryString. - * To view the result object structure, refer: https://lucaong.github.io/minisearch/modules/_minisearch_.html#searchresult - * - * @param {object} result - * @param {string} querystring - * @returns string - */ -function make_search_result(result, querystring) { - let search_divider = `
`; - let display_link = - result.location.slice(Math.max(0), Math.min(50, result.location.length)) + - (result.location.length > 30 ? "..." : ""); // To cut-off the link because it messes with the overflow of the whole div - - if (result.page !== "") { - display_link += ` (${result.page})`; - } - - let textindex = new RegExp(`\\b${querystring}\\b`, "i").exec(result.text); - let text = - textindex !== null - ? result.text.slice( - Math.max(textindex.index - 100, 0), - Math.min( - textindex.index + querystring.length + 100, - result.text.length - ) - ) - : ""; // cut-off text before and after from the match - - let display_result = text.length - ? "..." + - text.replace( - new RegExp(`\\b${querystring}\\b`, "i"), // For first occurrence - '$&' - ) + - "..." - : ""; // highlights the match - - let in_code = false; - if (!["page", "section"].includes(result.category.toLowerCase())) { - in_code = true; - } - - // We encode the full url to escape some special characters which can lead to broken links - let result_div = ` - -
-
${result.title}
-
${result.category}
-
-

- ${display_result} -

-
- ${display_link} -
-
- ${search_divider} - `; - - return result_div; -} - -/** - * Get selected filters, remake the filter html and lastly update the search modal - */ -function get_filters() { - let ele = $(".search-filters .search-filter-selected").get(); - filter_results = ele.map((x) => $(x).text().toLowerCase()); - modal_filters = make_modal_body_filters(filters, filter_results); - update_search(filter_results); +
`; } }) @@ -635,103 +792,107 @@ $(document).ready(function () { //////////////////////////////////////////////////////////////////////////////// require(['jquery'], function($) { -let search_modal_header = ` - -`; - -let initial_search_body = ` -
Type something to get started!
-`; - -let search_modal_footer = ` -
- - Ctrl + - / to search - - esc to close -
-`; - -$(document.body).append( - ` -
+println("Extended s-wave pair susceptibility, P_d = ", Pd_avg, " +/- ", Pd_std)
Extended s-wave pair susceptibility, P_d = 0.29735528609973727 +/- 0.024746553139607472
diff --git a/dev/index.html b/dev/index.html index 3f7cf50..8dd2478 100644 --- a/dev/index.html +++ b/dev/index.html @@ -131,4 +131,4 @@ # Keep up and down spin Green's functions synchronized as iterating over imaginary time. iterate(fgc_dn, fgc_up.forward) -end +end diff --git a/dev/objects.inv b/dev/objects.inv new file mode 100644 index 0000000000000000000000000000000000000000..e137c01c52c45a3a6c5aa40e03c4da6298f95d6a GIT binary patch literal 1161 zcmV;41a|u)AX9K?X>NERX>N99Zgg*Qc_4OWa&u{KZXhxWBOp+6Z)#;@bUGkPL{Uvc zMsi_oWp{6KYc6VR3L_v^WpZ%ZEX>4U6X>%ZBZ*6dLWpi_7WFU2OX>MmAdTeQ8E(&;@tykS{+cp%w*Hdt41#Cc> zG-=UxMs8xoUNf|t+c>)wDC@*#Lx~ziC3XVe?eX?dJ)$L9jwp|D2LzGK^PT@cil;Fw zNv`8TEN6tC5b{wb;IWLi5Ao+QIiFm5uw+RlAV1FkE|`LFQA80_aU0tMIVRIWOU0QW zCj)Y2Xyg;qn$LiIti*hlF$i+;<#Rx;cv1+axlFx3??4I3VuYVieJ8}++zgi>z|DnZI`3Lwn`CT69jQqk!u1FQ5N22wJ3 zrMq-ka1rx#PKQFyZs}K9Xr6-IRui9^ffxo-GkA5B>B)d@qD-qO(<;i;M41}3+bHj9 z>PzB_t$6><`STPUod4g;gRx=>+)H(P^i5b&GGsZQ(d(Sep+hw^Vrbr2s)PxiCzPcz zy?`5@a!XZ|IjfNbk)(z6utrSeyH-q;%-FoC1$+9oAd~;x!^W}#sdoW)AY=xL_F)=? zY0t|v*G$+FYQ%lQ3SsJ8%pp?jNX7i_C-O}UZmOCmmDDcGKRrSACwVBcm}v-a*sRR! zgHf7W1-dX=RrEF5b&98t(*jHMak73zHgBWmZQ8t@N4Zw0=r1Uh8Su#bU8efo+x42< zF8~Yiae6lRqevo9NIV14gAyB^~tDnGVPq~y0;@{wDU0Tmb8-m+Bl6*BlAswt-Nu*W-&)QLD*0x8;XDW zp&O3IzF+Zwr`UMDCCpJeb#s}y7=y5l zP7_HGMruzS3}hy=m6le~ExOf@sN7uPLS`8b(J*0J@uiE6Ha@F@j47-$Ay(nNVp$c^ zP~oIhIXIXvmCGnam_4=mDsicEx7p&riFXDp|7sAs*Q|xDRW=H8{$LMq zi*60T)hZb+pIh5?Lp+~zR>ca!;lKa5INoCLgTVjrw$F>L8M)1l-Fk4Vn!ciOS&luJ z$0@G4wRLfBH)09--_~0X&Mb{;=~TzZRk<^=V$h)~@0*T0K9DJX zRTZ+ZHgmW8518TQ=>L%cc1RTaxve4G_P}9D+sD7}%ffLs*XZ_Oeo~KaUpk`s(lP6* bTvm>CQhR7VWkR0fO%$(}eaznh(#rtB(d#p+ literal 0 HcmV?d00001 diff --git a/dev/search_index.js b/dev/search_index.js index 3a2bf39..35db10f 100644 --- a/dev/search_index.js +++ b/dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"api/#API","page":"API","title":"API","text":"","category":"section"},{"location":"api/#Propagator-Types","page":"API","title":"Propagator Types","text":"","category":"section"},{"location":"api/","page":"API","title":"API","text":"AbstractPropagator\nAbstractExactPropagator\nAbstractChkbrdPropagator\nSymExactPropagator\nAsymExactPropagator\nSymChkbrdPropagator\nAsymChkbrdPropagator\nSymPropagators","category":"page"},{"location":"api/","page":"API","title":"API","text":"AbstractPropagator\nAbstractExactPropagator\nAbstractChkbrdPropagator\nSymExactPropagator\nAsymExactPropagator\nSymChkbrdPropagator\nAsymChkbrdPropagator\nSymPropagators","category":"page"},{"location":"api/#JDQMCFramework.AbstractPropagator","page":"API","title":"JDQMCFramework.AbstractPropagator","text":"abstract type AbstractPropagator{T<:Continuous, E<:Continuous} end\n\nAbstract type to represent imaginary time propagator matrices B. All specific propagators types inherit from this abstract type. In the above T is data type of the matrix elements of the exponentiated kintetic energy matrix e^-Deltatau K_l appearing in B_l, and E is data type of the matrix elements appearing in the diagonal exponentiated potential energy matrix e^-Deltatau V_l.\n\n\n\n\n\n","category":"type"},{"location":"api/#JDQMCFramework.AbstractExactPropagator","page":"API","title":"JDQMCFramework.AbstractExactPropagator","text":"abstract type AbstractExactPropagator{T,E} <: AbstractPropagator{T,E} end\n\nAbstract type to represent imaginary time propagator matrices B defined with an exactly exponentiated hopping matrix K.\n\n\n\n\n\n","category":"type"},{"location":"api/#JDQMCFramework.AbstractChkbrdPropagator","page":"API","title":"JDQMCFramework.AbstractChkbrdPropagator","text":"abstract type AbstractChkbrdPropagator{T,E} <: AbstractPropagator{T,E} end\n\nAbstract type to represent imaginary time propagator matrices B defined with the exponentiated hopping matrix K represented by the checkerboard approximation.\n\n\n\n\n\n","category":"type"},{"location":"api/#JDQMCFramework.SymExactPropagator","page":"API","title":"JDQMCFramework.SymExactPropagator","text":"SymExactPropagator{T, E} <: AbstractExactPropagator{T,E}\n\nRepresents imaginary time propagator matrix as using the symmetric form\n\nB_l = e^-Deltatau K_l2 e^-Deltatau V_l e^-Deltatau K_l2\n\nwhere K_l is the strictly off-diagonal hopping matrix and V_l is the diagonal total on-site energy matrix.\n\nFields\n\nexpmΔτV::Vector{E}: A vector representing the diagonal exponeniated on-site energy matrix e^-Deltatau V_l\nexpmΔτKo2::Matrix{T}: The exponentiated hopping matrix e^-Deltatau K_l2\nexppΔτKo2::Matrix{T}: Inverse of the exponentiated hopping matrix e^+Deltatau K_l2\n\n\n\n\n\n","category":"type"},{"location":"api/#JDQMCFramework.AsymExactPropagator","page":"API","title":"JDQMCFramework.AsymExactPropagator","text":"AsymExactPropagator{T, E} <: AbstractExactPropagator{T,E}\n\nRepresents imaginary time propagator matrix as using the symmetric form\n\nB_l = e^-Deltatau V_l e^-Deltatau K_l\n\nwhere K_l is the strictly off-diagonal hopping matrix and V_l is the diagonal total on-site energy matrix.\n\nFields\n\nexpmΔτV::Vector{E}: A vector representing the diagonal exponeniated on-site energy matrix e^-Deltatau V_l\nexpmΔτK::Matrix{T}: The exponentiated hopping matrix e^-Deltatau K_l\nexppΔτK::Matrix{T}: Inverse of the exponentiated hopping matrix e^+Deltatau K_l\n\n\n\n\n\n","category":"type"},{"location":"api/#JDQMCFramework.SymChkbrdPropagator","page":"API","title":"JDQMCFramework.SymChkbrdPropagator","text":"SymChkbrdPropagator{T, E} <: AbstractChkbrdPropagator{T,E}\n\nRepresents imaginary time propagator matrix as using the symmetric form\n\nB_l = e^-Deltatau K_l2 e^-Deltatau V_l e^-Deltatau K_l2^dagger\n\nwhere K_l is the strictly off-diagonal hopping matrix and V_l is the diagonal total on-site energy matrix. The exponentiated hopping matrix e^-Deltatau K2 is represented by the checkerboard approximation.\n\nFields\n\nexpmΔτV::Vector{E}: A vector representing the diagonal exponeniated on-site energy matrix e^-Deltatau V_l\nexpmΔτKo2::CheckerboardMatrix{T}: The exponentiated hopping matrix e^-Deltatau K_l2 represented by the checkerboard approximation.\n\n\n\n\n\n","category":"type"},{"location":"api/#JDQMCFramework.AsymChkbrdPropagator","page":"API","title":"JDQMCFramework.AsymChkbrdPropagator","text":"AsymChkbrdPropagator{T, E} <: AbstractChkbrdPropagator{T,E}\n\nRepresents imaginary time propagator matrix as using the symmetric form\n\nB_l = e^-Deltatau V_l e^-Deltatau K_l\n\nwhere K_l is the strictly off-diagonal hopping matrix and V_l is the diagonal total on-site energy matrix. The exponentiated hopping matrix e^-Deltatau K is represented by the checkerboard approximation.\n\nFields\n\nexpmΔτV::Vector{E}: The vector representing the diagonal exponeniated on-site energy matrix e^-Deltatau V_l\nexpmΔτK::CheckerboardMatrix{T}: The exponentiated hopping matrix e^-Deltatau K_l represented by the checkerboard approximation.\n\n\n\n\n\n","category":"type"},{"location":"api/#JDQMCFramework.SymPropagators","page":"API","title":"JDQMCFramework.SymPropagators","text":"SymPropagators\n\nA union of the all the symmetric propagators types to help test whether a propagator type is symmetric. Assuming typeof{B} <: AbstractPropagator returns true, if typeof(B) <: SymPropagators returns true, then B represents a symmetric propagator, otherwise it represents an asymmetric propagator.\n\n\n\n\n\n","category":"type"},{"location":"api/#FermionGreensCalculator-Type","page":"API","title":"FermionGreensCalculator Type","text":"","category":"section"},{"location":"api/","page":"API","title":"API","text":"FermionGreensCalculator","category":"page"},{"location":"api/","page":"API","title":"API","text":"FermionGreensCalculator\nFermionGreensCalculator(::AbstractVector{P}, ::E, ::E, ::Int) where {T<:Number, E<:AbstractFloat, P<:AbstractPropagator{T}}\nFermionGreensCalculator(::FermionGreensCalculator{T,E}) where {T,E}","category":"page"},{"location":"api/#JDQMCFramework.FermionGreensCalculator","page":"API","title":"JDQMCFramework.FermionGreensCalculator","text":"FermionGreensCalculator{T<:Continuous, E<:AbstractFloat}\n\nA type to facilitate calculating the single-particle fermion Green's function matrix.\n\nFields\n\nforward::Bool: If true then iterate over imaginary time slices from l=1 to l=L_tau, if false then iterate over imaginary time slices from l=L_tau to l=1.\nl::Int: The current imaginary time slice tau = l cdot Deltatau.\nn_stab::Int: Frequency with which numerical stabilization is performed, i.e. every n_s imaginary time slices the equal-time Green's function is recomputed from scratch.\nN_stab::Int: Number of numerical stabilization intervals, N_s = leftlceil L_tau n_s rightrceil\nN::Int: Orbitals in system.\nβ::E: The inverse temperature beta=1T where T is temperature.\nΔτ::E: Discretization in imaginary time.\nLτ::Int: Length of imaginary time axis, L_tau = beta Deltatau\nB_bar::Vector{Matrix{T}}: A multidimensional array where the matrix B_bar[:,:,n] represents barB_n\nF::Vector{LDR{T,E}}: A vector of N_s LDR factorizations to represent the matrices B(0tau) and B(taubeta).\nG′::Matrix{T}: Matrix used for calculating the error corrected by numerical stabilization of the equal time Green's function.\nldr_ws::LDRWorkspace{T}: Workspace for performing LDR factorization while avoiding dynamic memory allocations.\n\n\n\n\n\n","category":"type"},{"location":"api/#JDQMCFramework.FermionGreensCalculator-Union{Tuple{P}, Tuple{E}, Tuple{T}, Tuple{AbstractVector{P}, E, E, Int64}} where {T<:Number, E<:AbstractFloat, P<:(AbstractPropagator{T})}","page":"API","title":"JDQMCFramework.FermionGreensCalculator","text":"FermionGreensCalculator(\n B::AbstractVector{P},\n β::E, Δτ::E, n_stab::Int\n) where {T<:Number, E<:AbstractFloat, P<:AbstractPropagator{T}}\n\nInitialize and return FermionGreensCalculator struct based on the vector of propagators B passed to the function.\n\n\n\n\n\n","category":"method"},{"location":"api/#JDQMCFramework.FermionGreensCalculator-Union{Tuple{FermionGreensCalculator{T, E}}, Tuple{E}, Tuple{T}} where {T, E}","page":"API","title":"JDQMCFramework.FermionGreensCalculator","text":"FermionGreensCalculator(fgc::FermionGreensCalculator{T,E}) where {T,E}\n\nReturn a new FermionGreensCalculator that is a copy of fgc.\n\n\n\n\n\n","category":"method"},{"location":"api/#DQMC-Building-Block-Routines","page":"API","title":"DQMC Building Block Routines","text":"","category":"section"},{"location":"api/","page":"API","title":"API","text":"calculate_equaltime_greens!\npropagate_equaltime_greens!\nstabilize_equaltime_greens!\ninitialize_unequaltime_greens!\npropagate_unequaltime_greens!\nstabilize_unequaltime_greens!\nlocal_update_det_ratio\nlocal_update_greens!\npartially_wrap_greens_forward!\npartially_wrap_greens_reverse!","category":"page"},{"location":"api/","page":"API","title":"API","text":"calculate_equaltime_greens!\npropagate_equaltime_greens!\nstabilize_equaltime_greens!\ninitialize_unequaltime_greens!\npropagate_unequaltime_greens!\nstabilize_unequaltime_greens!\nlocal_update_det_ratio\nlocal_update_greens!\npartially_wrap_greens_forward!\npartially_wrap_greens_reverse!","category":"page"},{"location":"api/#JDQMCFramework.calculate_equaltime_greens!","page":"API","title":"JDQMCFramework.calculate_equaltime_greens!","text":"calculate_equaltime_greens!(\n G::AbstractMatrix{T},\n fgc::FermionGreensCalculator{T,E}\n)::Tuple{E,T} where {T,E}\n\nCalculate the equal-time Greens function G(00) = G(betabeta) = I + B(beta0)^-1 using a numerically stable procedure. This method also returns log(vert det G vert) and textrmsign(det G) Note that this routine requires fgc.l == 1 or fgc.l == fgc.Lτ.\n\n\n\n\n\ncalculate_equaltime_greens!(\n G::AbstractMatrix{T},\n fgc::FermionGreensCalculator{T,E},\n B::AbstractVector{P}\n)::Tuple{E,T} where {T, E, P<:AbstractPropagator{T}}\n\nCalculate the equal-time Greens function G(00) = G(betabeta) = I + B(beta0)^-1 using a numerically stable procedure. Also re-calculate the barB_n matrices and the LDR matrix factorizations representing either B(tau0) or B(betatau) stored in fgc.F. This routine is useful for implementing global updates where every propagator matrix B_l has been modified, and the equal-time Green's function needs to be re-calculated from scratch. This method also returns log(vert det G vert) and textrmsign(det G) Note that this routine requires fgc.l == 1 or fgc.l == fgc.Lτ.\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.propagate_equaltime_greens!","page":"API","title":"JDQMCFramework.propagate_equaltime_greens!","text":"propagate_equaltime_greens!(\n G::AbstractMatrix{T},\n fgc::FermionGreensCalculator{T,E},\n B::AbstractVector{P}\n) where {T, E, P<:AbstractPropagator{T}}\n\nPropagate the equal-time Green's function matrix G from the previous imaginary time slice to the current imaginary time slice fgc.l. If iterating over imaginary time in the forward direction (fgc.forward = true) the relationship\n\nG(tau+Deltatautau+Deltatau) = B_l+1 cdot G(tautau) cdot B_l+1^-1\n\nis used, and if iterating over imaginary time in the reverse direction (fgc.forward = false) the relationship\n\nG(tau-Deltatautau-Deltatau)= B_l^-1 cdot G(tautau) cdot B_l\n\nis used instead, where the B_l propagator is given by B[l].\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.stabilize_equaltime_greens!","page":"API","title":"JDQMCFramework.stabilize_equaltime_greens!","text":"stabilize_equaltime_greens!(\n G::AbstractMatrix{T},\n logdetG::E, sgndetG::T,\n fgc::FermionGreensCalculator{T,E},\n B::AbstractVector{P};\n # KEYWORD ARGUMENTS\n update_B̄::Bool=true\n)::Tuple{E,T,E,E} where {T, E, P<:AbstractPropagator{T}}\n\nStabilize the equal-time Green's function as iterating through imaginary time tau = Deltatau cdot l For a given imaginary time slice fgc.l, this routine should be called after all changes to the B_l propagator have been made. When iterating through imaginary time in the forwards direction (fgc.forward = true), this function re-computes\n\nG(tautau) = I + B(tau0)B(betatau)^-1\n\nwhen at imaginary time slice fgc.l every fgc.n_stab imaginary time slice. When iterating through imaginary time in the reverse direction (fgc.forward = false), this function instead re-computes\n\nG(tau-Deltatautau-Deltatau) = I + B(tau-Deltatau0)B(betatau-Deltatau)^-1\n\nfor fgc.l.\n\nThis method returns four values. The first two values returned are log(vert det G(tautau) vert) and textrmsign(det G(tautau)). The latter two are the maximum error in a Green's function corrected by numerical stabilization vert delta G vert, and the error in the phase of the determinant corrected by numerical stabilization deltatheta relative to naive propagation of the Green's function matrix in imaginary time occuring instead. If no stabilization was performed, than vert delta G vert = 0 and delta theta = 0\n\nThis method also computes the LDR matrix factorizations representing B(tau 0) or B(beta tau-Deltatau) when iterating through imaginary time tau = Deltatau cdot l in the forward and reverse directions respectively. If update_B̄ = true, then the barB_n matrices are re-calculated as needed, but if update_B̄ = false, then they are left unchanged.\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.initialize_unequaltime_greens!","page":"API","title":"JDQMCFramework.initialize_unequaltime_greens!","text":"initialize_unequaltime_greens!(\n Gτ0::AbstractMatrix{T},\n G0τ::AbstractMatrix{T},\n Gττ::AbstractMatrix{T},\n G00::AbstractMatrix{T}\n) where {T<:Number}\n\nInitialize the Green's function matrices G(tau0) G(0tau) and G(tautau) for tau = 0 based on the matrix G(00)\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.propagate_unequaltime_greens!","page":"API","title":"JDQMCFramework.propagate_unequaltime_greens!","text":"propagate_unequaltime_greens!(\n Gτ0::AbstractMatrix{T},\n G0τ::AbstractMatrix{T},\n Gττ::AbstractMatrix{T},\n fgc::FermionGreensCalculator{T,E},\n B::AbstractVector{P}\n) where {T, E, P<:AbstractPropagator{T}}\n\nPropagate the Green's function matrices G(tau0), G(0tau) and G(tautau) from the previous imaginary time slice to the current imaginary time slice fgc.l. If iterating over imaginary time in the forward direction (fgc.forward = true) the relationships\n\nbeginalign\nG(tau0) = B_l cdot G(tau-Deltatau 0) \nG(0tau) = G(0 tau-Deltatau) cdot B^-1_l \nG(tautau) = B_l cdot G(tau-Deltatau tau-Deltatau) cdot B_l^-1\nendalign\n\nare used, and if iterating over imaginary time in the reverse direction (fgc.forward = false) the relationships\n\nbeginalign\nG(tau0) = B_l+1^-1 cdot G(tau+Deltatau 0) \nG(0tau) = G(0 tau + Deltatau) cdot B_l+1 \nG(tautau) = B_l+1^-1 cdot G(tau+Deltatau tau+Deltatau) cdot B_l+1\nendalign\n\nare used instead, where the B_l propagator is given by B[l].\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.stabilize_unequaltime_greens!","page":"API","title":"JDQMCFramework.stabilize_unequaltime_greens!","text":"stabilize_unequaltime_greens!(\n Gτ0::AbstractMatrix{T},\n G0τ::AbstractMatrix{T},\n Gττ::AbstractMatrix{T},\n logdetG::E, sgndetG::T,\n fgc::FermionGreensCalculator{T,E},\n B::AbstractVector{P};\n # KEYWORD ARGUMENTS\n update_B̄::Bool=true\n)::Tuple{E,T,E,E} where {T, E, P<:AbstractPropagator{T}}\n\nStabilize the Green's function matrice G(tau0), G(0tau) and G(tautau) as iterating through imaginary time tau = Deltatau cdot l For a given imaginary time slice fgc.l, this routine should be called after all changes to the B_l propagator have been made. When iterating through imaginary time in the forwards direction (fgc.forward = true), this function re-computes\n\nbeginalign\nG(tau0) = B^-1(tau0) + B(betatau)^-1 \nG(0 tau) = B^-1(betatau) + B(tau0)^-1 \nG(tautau) = I + B(tau0)B(betatau)^-1\nendalign\n\nwhen at imaginary time slice fgc.l every fgc.n_stab imaginary time slice. When iterating through imaginary time in the reverse direction (fgc.forward = false), this function instead re-computes\n\nbeginalign*\nG(tau-Deltatau0) = B^-1(tau-Deltatau0) + B(betatau-Deltatau)^-1 \nG(0tau-Deltatau) = B^-1(betatau-Deltatau) + B(tau-Deltatau0)^-1 \nG(tau-Deltatautau-Deltatau) = I + B(tau-Deltatau0)B(betatau-Deltatau)^-1\nbeginalign*\n\nfor fgc.l.\n\nThis method returns four values. The first two values returned are log(vert det G(tautau) vert) and textrmsign(det G(tautau)). The latter two are the maximum error in a Green's function corrected by numerical stabilization vert delta G vert, and the error in the phase of the determinant corrected by numerical stabilization deltatheta relative to naive propagation of the Green's function matrix in imaginary time occuring instead. If no stabilization was performed, than vert delta G vert = 0 and delta theta = 0\n\nThis method also computes the LDR matrix factorizations representing B(tau 0) or B(beta tau-Deltatau) when iterating through imaginary time tau = Deltatau cdot l in the forward and reverse directions respectively. If update_B̄ = true, then the barB_n matrices are re-calculated as needed, but if update_B̄ = false, then they are left unchanged.\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.local_update_det_ratio","page":"API","title":"JDQMCFramework.local_update_det_ratio","text":"local_update_det_ratio(\n G::AbstractMatrix{T},\n B::AbstractPropagator{T},\n V′::T, i::Int, Δτ::E\n)::Tuple{T,T} where {T,E}\n\nCalculate the determinant ratio R_li associated with a local update to the equal-time Green's function G(tautau) Also returns Delta_li which is defined below.\n\nArguments\n\nG::AbstractMatrix{T}: Equal-time Green's function matrix G(tautau)\nB::AbstractPropagator{T,E}: Represents the propagator matrix B_l where tau = Deltatau cdot l\nV′::T: The new value for the V^prime_lii matrix element in the diagonal on-site energy matrix V_l\ni::Int: Diagonal matrix element index in V_l being updated.\nΔτ::E: Discretization in imaginary time Deltatau\n\nAlgorithm\n\nThe propagator matrix B_l above is given by\n\nB_l = Lambda_l cdot Gamma_l(Deltatau)\n\nwhere, assuming the we are working in the orbital basis, Gamma_l(Deltatau) = e^-Deltatau K_l represents the exponentiated hopping matrix K_l, and Lambda_l = e^-Deltatau V_l represents the exponentiated diagonal on-site energy matrix V_l\n\nGiven a proposed update to the (ii) matrix element of the diagonal on-site energy matrix V_l, (V_lii rightarrow V^prime_lii) the corresponding determinant ratio associated with this proposed udpate is given by\n\nR_li = fracdet G(tautau)det G^prime(tautau) = 1+Delta_ii(taui)left(1-G_ii(tautau)right)\n\nwhere\n\nDelta_li = fracLambda^prime_liiLambda_lii - 1 = e^-Deltatau (V^prime_lii - V_lii) - 1\n\nThis routine returns the scalar quantities R_li and Delta_li\n\nNote that if the propagator matrix is instead represented using the symmetric form\n\nB_l = Gamma_l(Deltatau2) cdot Lambda_l cdot Gamma^dagger_l(Deltatau2)\n\nthen the matrix G needs to instead represent the transformed equal-time Green's function matrix\n\ntildeG(tautau) = Gamma_l^-1(Deltatau2) cdot G(tautau) cdot Gamma_l(Deltatau2)\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.local_update_greens!","page":"API","title":"JDQMCFramework.local_update_greens!","text":"local_update_greens!(\n G::AbstractMatrix{T}, logdetG::E, sgndetG::T,\n B::AbstractPropagator{T},\n R::T, Δ::T, i::Int,\n u::AbstractVector{T}, v::AbstractVector{T}\n)::Tuple{E,T} where {T, E<:AbstractFloat}\n\nUpdate the equal-time Green's function matrix G resulting from a local update in-place.\n\nArguments\n\nG::AbstractMatrix{T}: Equal-time Green's function matrix G(tautau) that will be updated in-place.\nlogdetG::E: The log of the absolute value of the initial Green's function matrix, log( vert det G(tautau) vert )\nsgndetG::T: The sign/phase of the determinant of the initial Green's function matrix, textrmsign( det G(tautau) )\nB::AbstractPropagator{T,E}: Propagator that needs to be updated to reflect accepted local update.\nR::T: The determinant ratio R_li = fracdet G(tautau)det G^prime(tautau)\nΔ::T: Change in the exponentiated on-site energy matrix, Delta_li = e^-Deltatau (V^prime_l(ii) - V_l(ii)) - 1\ni::Int: Matrix element of diagonal on-site energy matrix V_l that is being updated.\nu::AbstractVector{T}: Vector of length size(G,1) that is used to avoid dynamic memory allocations.\nv::AbstractVector{T}: Vector of length size(G,2) that is used to avoid dynamic memory allocations.\n\nAlgorithm\n\nThe equal-time Green's function matrix is updated using the relationship\n\nG_jk^primeleft(tautauright)=G_jkleft(tautauright)-frac1R_liG_jileft(tautauright)Delta_lileft(delta_ik-G_ikleft(tautauright)right)\n\nThe B_l progpagator B is also udpated. Additionally, this method returns log( vert det G^prime(tautau) vert ) and textrmsign( det G^prime(tautau) )\n\nAn important note is that if the propagator matrices are represented in a symmetric form, then G′ and G need to correspond to the transformed eqaul-time Green's function matrices tildeG^prime(tautau) and tildeG(tautau) Refer to the local_update_det_ratio docstring for more information.\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.partially_wrap_greens_forward!","page":"API","title":"JDQMCFramework.partially_wrap_greens_forward!","text":"partially_wrap_greens_forward!(\n G::Matrix{T},\n B::P,\n M::Matrix{T} = similar(G)\n) where {T, E, P<:AbstractPropagator{T,E}}\n\nIf the propagator B is represented in the symmetric form\n\nB_l = Gamma_l(Deltatau2) cdot Lambda_l(Deltatau) cdot Gamma_l^dagger(Deltatau2)\n\nwith tau = l cdot Deltatau where Gamma(Deltatau2) = e^-Deltatau K_l2 and Lambda(Deltatau) = e^-Deltatau V_l, then apply the transformation\n\ntildeG(tautau) = Gamma^-1_l(Deltatau2) cdot G(tautau) cdot Gamma_l(Deltatau2)\n\nto the equal-time Green's function matrix G in-place.\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.partially_wrap_greens_reverse!","page":"API","title":"JDQMCFramework.partially_wrap_greens_reverse!","text":"partially_wrap_greens_reverse!(\n G::Matrix{T},\n B::P,\n M::Matrix{T} = similar(G)\n) where {T, E, P<:AbstractPropagator{T,E}}\n\nIf the propagator B is represented in the symmetric form\n\nB_l = Gamma_l(Deltatau2) cdot Lambda_l(Deltatau) cdot Gamma_l^dagger(Deltatau2)\n\nwith tau = l cdot Deltatau where Gamma(Deltatau2) = e^-Deltatau K_l2 and Lambda(Deltatau) = e^-Deltatau V_l, then apply the transformation\n\nG(tautau) = Gamma_l(Deltatau2) cdot tildeG(tautau) cdot Gamma_l^-1(Deltatau2)\n\nto the equal-time Green's function matrix G in-place.\n\n\n\n\n\n","category":"function"},{"location":"api/#Overloaded-Functions","page":"API","title":"Overloaded Functions","text":"","category":"section"},{"location":"api/","page":"API","title":"API","text":"iterate\neltype\nresize!\nsize\ncopyto!\nishermitian\nmul!\nlmul!\nrmul!\nldiv!\nrdiv!","category":"page"},{"location":"api/","page":"API","title":"API","text":"Base.iterate\nBase.eltype\nBase.resize!\nBase.size\nBase.copyto!\nLinearAlgebra.ishermitian\nLinearAlgebra.mul!\nLinearAlgebra.lmul!\nLinearAlgebra.rmul!\nLinearAlgebra.ldiv!\nLinearAlgebra.rdiv!","category":"page"},{"location":"api/#Base.iterate","page":"API","title":"Base.iterate","text":"iterate(iter::FermionGreensCalculator)\n\niterate(iter::FermionGreensCalculator, state)\n\nIterate over imaginary time slices, alternating between iterating in the forward direction from l=1 to l=L_tau and in the reverse direction from l=L_tau to l=1. The iter.forward boolean field in the FermionGreensCalculator type determines whether the imaginary time slices are iterated over in forward or reverse order. The iter.forward field is updated as needed automatically and should not be adjusted manually.\n\n\n\n\n\n","category":"function"},{"location":"api/#Base.eltype","page":"API","title":"Base.eltype","text":"eltype(B::AbstractPropagator{T,E}) where {T,E}\n\nReturn the matrix element type of the propagator T.\n\n\n\n\n\neltype(fgc::FermionGreensCalculator{T,E}) where {T,E}\n\nReturn matrix element type T associated with an instance of FermionGreensCalculator.\n\n\n\n\n\n","category":"function"},{"location":"api/#Base.resize!","page":"API","title":"Base.resize!","text":"resize!(\n fgc::FermionGreensCalculator{T,E},\n G::Matrix{T}, logdetG::E, sgndetG::T,\n B::Vector{P}, n_stab::Int\n) where {T<:Number, E<:AbstractFloat, P<:AbstractPropagator{T}}\n\nresize!(\n fgc::FermionGreensCalculator{T,E}, n_stab::Int\n) where {T,E}\n\nUpdate fgc to reflect a new stabilizaiton frequency n_stab. If G, logdetG, sgndetG and B are also passed then the equal-time Green's function G is re-calculated and the corresponding updated values for (logdetG, sgndetG) are returned.\n\n\n\n\n\n","category":"function"},{"location":"api/#Base.size","page":"API","title":"Base.size","text":"size(B::AbstractPropagator)\n\nsize(B::AbstractPropagator, dim)\n\nReturn the size of a propagator.\n\n\n\n\n\n","category":"function"},{"location":"api/#Base.copyto!","page":"API","title":"Base.copyto!","text":"copyto!(B′::SymExactPropagator{T,E}, B::SymExactPropagator{T,E}) where {T,E}\n\ncopyto!(B′::AsymExactPropagator{T,E}, B::AsymExactPropagator{T,E}) where {T,E}\n\ncopyto!(B′::SymChkbrdPropagator{T,E}, B::SymChkbrdPropagator{T,E}) where {T,E}\n\ncopyto!(B′::AsymChkbrdPropagator{T,E}, B::AsymChkbrdPropagator{T,E}) where {T,E}\n\nCopy the propagator B to B′.\n\n\n\n\n\ncopyto!(\n fgc_out::FermionGreensCalculator{T,E},\n fgc_in::FermionGreensCalculator{T,E}\n) where {T,E}\n\nCopy the contents of fgc_in to fgc_out. If fgc_out.n_stab != fgc_in.n_stab is true, then fgc_out will be resized using resize! to match fgc_in.\n\n\n\n\n\n","category":"function"},{"location":"api/#LinearAlgebra.ishermitian","page":"API","title":"LinearAlgebra.ishermitian","text":"ishermitian(B::AbstractPropagator)\n\nReturn whether a propagator is hermitian or not.\n\n\n\n\n\n","category":"function"},{"location":"api/#LinearAlgebra.mul!","page":"API","title":"LinearAlgebra.mul!","text":"mul!(A::AbstractMatrix{T}, B::SymExactPropagator{T}, C::AbstractMatrix{T};\n M::AbstractMatrix{T}=similar(A)) where {T}\n\nmul!(A::AbstractMatrix{T}, B::AsymExactPropagator{T}, C::AbstractMatrix{T};\n M::AbstractMatrix{T}=similar(A)) where {T}\n\nmul!(A::AbstractMatrix{T}, B::AbstractChkbrdPropagator{T}, C::AbstractMatrix{T};\n M=nothing) where {T}\n\nCalculate the product A = B cdot C, where B is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then A = B^dagger cdot C is evaluated instead.\n\n\n\n\n\nmul!(A::AbstractMatrix{T}, C::AbstractMatrix{T}, B::SymExactPropagator{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nmul!(A::AbstractMatrix{T}, C::AbstractMatrix{T}, B::AsymExactPropagator{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nmul!(A::AbstractMatrix{T}, C::AbstractMatrix{T}, B::AbstractChkbrdPropagator{T};\n M=nothing) where {T}\n\nCalculate the matrix product A = C cdot B, where B is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then A = C cdot B^dagger is evaluated instead.\n\n\n\n\n\n","category":"function"},{"location":"api/#LinearAlgebra.lmul!","page":"API","title":"LinearAlgebra.lmul!","text":"lmul!(B::SymExactPropagator{T}, A::AbstractMatrix{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nlmul!(B::AsymExactPropagator{T}, A::AbstractMatrix{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nlmul!(B::AsymExactPropagator{T}, A::AbstractMatrix{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nlmul!(B::AsymChkbrdPropagator{T}, A::AbstractMatrix{T};\n M = nothing) where {T}\n\nCalculate the matrix product A = B cdot A, where B is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, when A = B^dagger cdot A is evaluated instead.\n\n\n\n\n\n","category":"function"},{"location":"api/#LinearAlgebra.rmul!","page":"API","title":"LinearAlgebra.rmul!","text":"rmul!(A::AbstractMatrix{T}, B::SymExactPropagator{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nrmul!(A::AbstractMatrix{T}, B::AsymExactPropagator{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nrmul!(A::AbstractMatrix{T}, B::SymChkbrdPropagator{T};\n M = nothing) where {T}\n\nrmul!(A::AbstractMatrix{T}, B::AsymChkbrdPropagator{T};\n M = nothing) where {T}\n\nCalculate the matrix product A = A cdot B, where B is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then A = A cdot B^dagger is evaluated instead. \n\n\n\n\n\n","category":"function"},{"location":"api/#LinearAlgebra.ldiv!","page":"API","title":"LinearAlgebra.ldiv!","text":"ldiv!(A::AbstractMatrix{T}, B::AbstractExactPropagator{T}, C::AbstractMatrix{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nldiv!(A::AbstractMatrix{T}, B::AbstractChkbrdPropagator{T}, C::AbstractMatrix{T};\n M = nothing) where {T}\n\nCalculate the matrix product A = B^-1 cdot C, where B is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then A = B^dagger^-1 cdot C is evaluated instead.\n\n\n\n\n\nldiv!(B::SymExactPropagator{T}, A::AbstractMatrix{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nldiv!(B::AsymExactPropagator{T}, A::AbstractMatrix{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nldiv!(B::SymChkbrdPropagator{T}, A::AbstractMatrix{T};\n M = nothing) where {T}\n\nldiv!(B::AsymChkbrdPropagator{T}, A::AbstractMatrix{T};\n M = nothing) where {T}\n\nCalculate the matrix product A = B^-1 cdot A, where B is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then A = B^dagger^-1 cdot A is evaluated instead.\n\n\n\n\n\n","category":"function"},{"location":"api/#LinearAlgebra.rdiv!","page":"API","title":"LinearAlgebra.rdiv!","text":"rldiv!(A::AbstractMatrix{T}, C::AbstractMatrix{T}, B::AbstractExactPropagator{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nrdiv!(A::AbstractMatrix{T}, C::AbstractMatrix{T}, B::AbstractChkbrdPropagator{T};\n M = nothing) where {T}\n\nCalculate the matrix product A = C cdot B^-1, where B is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B is asymmetric and B.adjointed = true, then A = C cdot B^dagger^-1 is evaluated instead.\n\n\n\n\n\nrdiv!(A::AbstractMatrix{T}, B::SymExactPropagator{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nrdiv!(A::AbstractMatrix{T}, B::AsymExactPropagator{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nrdiv!(A::AbstractMatrix{T}, B::SymChkbrdPropagator{T};\n M = nothing) where {T}\n\nrdiv!(A::AbstractMatrix{T}, B::AsymChkbrdPropagator{T};\n M = nothing) where {T}\n\nCalculate the matrix product A = A cdot B^-1, where B is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then A = A cdot B^dagger^-1 is evaluated instead.\n\n\n\n\n\n","category":"function"},{"location":"api/#Utility-Functions","page":"API","title":"Utility Functions","text":"","category":"section"},{"location":"api/","page":"API","title":"API","text":"eval_length_imaginary_axis\nexp!\nbuild_hopping_matrix!","category":"page"},{"location":"api/","page":"API","title":"API","text":"eval_length_imaginary_axis\nexp!\nbuild_hopping_matrix!","category":"page"},{"location":"api/#JDQMCFramework.eval_length_imaginary_axis","page":"API","title":"JDQMCFramework.eval_length_imaginary_axis","text":"eval_length_imaginary_axis(\n β::T,\n Δτ::T\n)::Int where {T<:AbstractFloat}\n\nGiven an inverse temperature β and discretization in imaginary time Δτ, return the length of the imaginary time axis Lτ.\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.exp!","page":"API","title":"JDQMCFramework.exp!","text":"exp!(\n expαH::AbstractMatrix{T},\n H::AbstractMatrix{T},\n α::E;\n # KEYWORD ARGUMENTS\n workspace::HermitianEigenWs{T,Matrix{T},R} = HermitianEigenWs(H),\n tol::R = 1e-6\n) where {T<:Number, E<:Number, R<:AbstractFloat}\n\nGiven a Hermitian matrix H, calculate the matrix exponentials e^alpha H Note that H is left modified by this method. The workspace field is of type HermitianEigenWs, which is exported from the FastLapackInterface.jl package, is used to avoid dynamic memory allocations.\n\n\n\n\n\nexp!(\n exppαH::AbstractMatrix{T},\n expmαH::AbstractMatrix{T},\n H::AbstractMatrix{T}, α::E;\n # KEYWORD ARGUMENTS\n workspace::HermitianEigenWs{T,Matrix{T},R} = HermitianEigenWs(H),\n tol::R = 1e-6\n) where {T<:Number, E<:Number, R<:AbstractFloat}\n\nGiven a Hermitian matrix H, calculate the matrix exponentials e^+alpha H and e^-alpha H, which are written to exppαH and expmαH respectively. Note that H is left modified by this method. The workspace field is of type HermitianEigenWs, which is exported from the FastLapackInterface.jl package, is used to avoid dynamic memory allocations.\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.build_hopping_matrix!","page":"API","title":"JDQMCFramework.build_hopping_matrix!","text":"build_hopping_matrix!(\n K::AbstractMatrix{T},\n neighbor_table::Matrix{Int},\n t::AbstractVector{T}\n) where {T<:Continuous}\n\nConstruct a hopping matrix K using neighbor_table along with the corresponding hopping amplitudes t. Each column of neighbor_table stores a pair of neighboring orbitals in the lattice, such that size(neighbor_table,1) = 2.\n\n\n\n\n\n","category":"function"},{"location":"api/#Developer-API","page":"API","title":"Developer API","text":"","category":"section"},{"location":"api/","page":"API","title":"API","text":"JDQMCFramework.Continuous\nJDQMCFramework.update_factorizations!\nJDQMCFramework.update_B̄!\nJDQMCFramework.calculate_B̄!\nJDQMCFramework.stabilization_interval","category":"page"},{"location":"api/","page":"API","title":"API","text":"JDQMCFramework.Continuous\nJDQMCFramework.update_factorizations!\nJDQMCFramework.update_B̄!\nJDQMCFramework.calculate_B̄!\nJDQMCFramework.stabilization_interval","category":"page"},{"location":"api/#JDQMCFramework.Continuous","page":"API","title":"JDQMCFramework.Continuous","text":"Continuous = Union{AbstractFloat,Complex{<:AbstractFloat}}\n\nAn abstract type to represent continuous real and complex numbers.\n\n\n\n\n\n","category":"type"},{"location":"api/#JDQMCFramework.update_factorizations!","page":"API","title":"JDQMCFramework.update_factorizations!","text":"update_factorizations!(\n fgc::FermionGreensCalculator{T,E},\n B::AbstractVector{P}\n) where {T, E, P<:AbstractPropagator{T}}\n\nIf current imaginary time slice fgc.l corresponds to the boundary of a stabilization interval, calculate a LDR factorization to represent B(0 tau) or B(tau-Deltatau beta) if iterating over imaginary time in the forward (fgc.forward = true) or reverse (fgc.forward = false) directions respectively. This method should be called after all changes to the current time slice propagator matrix B_l have been made This method will also recompute barB_n as needed.\n\n\n\n\n\nupdate_factorizations!(\n fgc::FermionGreensCalculator{T,E}\n) where {T, E}\n\nIf current imaginary time slice fgc.l corresponds to the boundary of a stabilization interval, calculate a LDR factorization to represent B(tau 0) or B(beta tau-Deltatau) if iterating over imaginary time in the forward (fgc.forward = true) or reverse (fgc.forward = false) directions respectively. This method should be called after all changes to the current time slice propagator matrix B_l have been made, and any required updates to a barB_n matrix have been performed using the JDQMCFramework.update_B̄! routine.\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.update_B̄!","page":"API","title":"JDQMCFramework.update_B̄!","text":"update_B̄!(\n fgc::FermionGreensCalculator{T,E},\n B::AbstractVector{P}\n) where {T,E,P<:AbstractPropagator{T}}\n\nRecalculate barB_n if the current timeslice fgc.l corresponds to the boundary of a stabilization interval, accounting for whether imaginary time is being iterated over in the forward (fgc.forward = true) or reverse (fgc.forward = false) direction.\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.calculate_B̄!","page":"API","title":"JDQMCFramework.calculate_B̄!","text":"calculate_B̄!(\n fgc::FermionGreensCalculator{T,E},\n B::AbstractVector{P}, n::Int\n) where {T,E,P<:AbstractPropagator{T}}\n\nGiven B, a vector of all the propagator matrices B_l, calculate the matrix product\n\nbarB_sigman=prod_l=(n-1)cdot n_s+1^min(ncdot n_sL_tau)B_sigmal\n\nwith the result getting written to fgc.B_bar[n].\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.stabilization_interval","page":"API","title":"JDQMCFramework.stabilization_interval","text":"stabilization_interval(\n fgc::FermionGreensCalculator\n)::Tuple{Int,Int}\n\nGiven the current imaginary time slice fgc.l, return the corresponding stabilization interval n = ceil(Int, fgc.l/fgc.n_stab), and the relative location within that stabilization interval l′ = mod1(fgc.l, fgc.n_stab), such that l′∈[1,n_stab]. \n\n\n\n\n\n","category":"function"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"EditURL = \"../../../examples/square_hubbard.jl\"","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Download this example as Jupyter notebook or Julia script.","category":"page"},{"location":"examples/square_hubbard/#Tutorial-1:-Square-Lattice-Hubbard-Model-DQMC-Simulation","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"","category":"section"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"This tutorial implements a determinant quantum Monte Carlo (DQMC) simulation from \"scratch\" using the JDQMCFramework.jl package, along with several others. The purpose of this tutorial is to empower researchers to write their own lightweight DQMC codes in order to address specific research needs that fall outside the scope of existing high-level DQMC packages like SmoQyDQMC.jl, and to enable rapid prototyping of algorithmic improvements to existing DQMC methods.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"This tutorial is relatively long as a lot goes into writing a full DQMC code. However, in spite of the length, each step is relatively straightforward. This is made possible by leveraging the functionality exported by JDQMCFramework.jl and other packages. For instance, the JDQMCFramework.jl package takes care of all the numerical stabilization nonsense that is one of the most challenging parts of writing a DQMC code. Also, implementing various correlation measurements in a DQMC simulation is typically very time consuming and challening, as it requires working through arduous Wick's contractions, and then implementing each term. Once again, this hurdle is largely avoided by leveraging the functionality exported by the JDQMCMeasurements.jl package, which implements a variety of standard correlation function measurements for arbitary lattice geometries.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"The repulsive Hubbard model Hamiltonian on a square lattice considered in this tutorial is given by","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"hatH = -t sum_sigmalangle ijrangle (hatc^dagger_sigmai hatc^phantom dagger_sigmaj + rm hc)\n + U sum_i (hatn_uparrowi-tfrac12)(hatn_downarrowi-tfrac12) - mu sum_sigmai hatn_sigmai","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"where hatc^dagger_sigmai (hatc^phantom dagger_sigmai) creates (annihilates) a spin sigma electron on site i in the lattice, and hatn_sigmai = hatc^dagger_sigmai hatc^phantom dagger_sigmai is the spin-sigma electron number operator for site i. In the above Hamiltonian, t is the nearest neighbor hopping integral, mu is the chemical potential, and U 0 controls the strength of the on-site Hubbard repulsion. Lastly, if mu = 00 then the Hamiltonian is particle-hole symmetric, ensuring the system is half-filled (langle n_sigma rangle = tfrac12) and that there is no sign problem. In the case of mu ne 0 there will be a sign problem.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"The script version of this tutorial, which can be downloaded using the link found at the top of this page, can be run with the command","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"julia square_hubbard.jl","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"in a terminal. This tutorial can also be downloaded as a notebook at the top of this page.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"We begin by importing the relevant packages we will need to use in this example. Note that to run this tutorial you will need to install all the required Julia packages. However, this is straightforward as all the packages used in this tutorial are registered with the Julia General package registry. This means they can all be easily installed with the Julia package manager using the add command in the same way that the JDQMCFramework.jl package is installed.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Import relevant standard template libraries.\nusing Random\nusing LinearAlgebra\n\n# Provides framework for implementing DQMC code.\nimport JDQMCFramework as jdqmcf\n\n# Exports methods for measuring various correlation functions in a DQMC simulation.\nimport JDQMCMeasurements as jdqmcm\n\n# Exports types and methods for representing lattice geometries.\nimport LatticeUtilities as lu\n\n# Exports the checkerboard approximation for representing an exponentiated hopping matrix.\nimport Checkerboard as cb\n\n# Exports useful methods for analyzing correlated MCMC data.\nimport BinningAnalysis as ba\n\n# Package for performing Fast Fourier Transforms (FFTs).\nusing FFTW","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"The next incantations are included for annoying technical reasons. Without going into too much detail, the default multithreading behavior used by BLAS/LAPACK in Julia is somewhat sub-optimal. As a result, it is typically a good idea to include these commands in Julia DQMC codes, as they ensure that BLAS/LAPACK (and FFTW) run in a single-threaded fashion. For more information on this issue, I refer readers to this discussion, which is found in the documentation for the ThreadPinning.jl package.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Set number of threads used by BLAS/LAPACK to one.\nBLAS.set_num_threads(1)\n\n# Set number of threads used by FFTW to one.\nFFTW.set_num_threads(1)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now we define the relevant Hamiltonian parameter values that we want to simulate. In this example we will stick to a relatively small system size (4 times 4) and inverse temperature (beta = 4) to ensure that this tutorial can be run quickly on a personal computer. Also, in this tutorial I will include many print statements so that when the tutorial is run users can keep track of what is going on. That said, for a DQMC code that will be used in actual research you will want to replace the print statements with code that writes relevant information and measurement results to file.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Nearest-neighbor hopping amplitude.\nt = 1.0\nprintln(\"Nearest-neighbor hopping amplitude, t = \", t)\n\n# Hubbard interaction.\nU = 6.0\nprintln(\"Hubbard interaction, U = \", U)\n\n# Chemical potential.\nμ = 2.0\nprintln(\"Chemical potential, mu = \", μ)\n\n# Inverse temperature.\nβ = 4.0\nprintln(\"Inverse temperature, beta = \", β)\n\n# Lattice size.\nL = 4\nprintln(\"Linear lattice size, L = \", L)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Next we define the relevant DQMC simulation parameters.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Discretization in imaginary time.\nΔτ = 0.05\nprintln(\"Disretization in imaginary time, dtau = \", Δτ)\n\n# Length of imaginary time axis.\nLτ = round(Int, β/Δτ)\nprintln(\"Length of imaginary time axis, Ltau = \", Lτ)\n\n# Whether or not to use a symmetric or asymmetric definition for the propagator matrices.\nsymmetric = false\nprintln(\"Whether symmetric or asymmetric propagator matrices are used, symmetric = \", symmetric)\n\n# Whether or not to use the checkerboard approximation to represent the\n# exponentiated electron kinetic energy matrix exp(-Δτ⋅K).\ncheckerboard = false\nprintln(\"Whether the checkerboard approximation is used, checkerboard = \", checkerboard)\n\n# Period with which numerical stabilization is performed i.e.\n# how many imaginary time slices separate more expensive recomputations\n# of the Green's function matrix using numerically stable routines.\nn_stab = 10\nprintln(\"Numerical stabilization period, n_stab = \", n_stab)\n\n# The number of burnin sweeps through the lattice performing local updates that\n# are performed to thermalize the system.\nN_burnin = 2_500\nprintln(\"Number of burnin sweeps, N_burnin = \", N_burnin)\n\n# The number of measurements made once the system is thermalized.\nN_measurements = 10_000\nprintln(\"Number of measurements, N_measurements = \", N_measurements)\n\n# Number of local update sweeps separating sequential measurements.\nN_sweeps = 1\nprintln(\"Number of local update sweeps seperating measurements, n_sweeps = \", N_sweeps)\n\n# Number of bins used to performing a binning analysis when calculating final error bars\n# for measured observables.\nN_bins = 50\nprintln(\"Number of measurement bins, N_bins = \", N_bins)\n\n# Number of measurements averaged over per measurement bin.\nN_binsize = N_measurements ÷ N_bins\nprintln(\"Number of measurements per bin, N_binsize = \", N_binsize)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now we initialize the random number generator (RNG) that will be used in the rest of the simulation.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Initialize random number generator.\nseed = abs(rand(Int))\nrng = Xoshiro(seed)\nprintln(\"Random seed used to initialize RNG, seed = \", seed)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Next, we define our square lattice geometry using the LatticeUtilities.jl package.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Define the square lattice unit cell.\nunit_cell = lu.UnitCell(\n lattice_vecs = [[1.0, 0.0],\n [0.0, 1.0]],\n basis_vecs = [[0.0, 0.0]]\n)\n\n# Define the size of the periodic square lattice.\nlattice = lu.Lattice(\n L = [L, L],\n periodic = [true, true]\n)\n\n# Define nearest-neighbor bond in +x direction\nbond_px = lu.Bond(\n orbitals = (1,1),\n displacement = [1,0]\n)\n\n# Define nearest-neighbor bond in +y direction\nbond_py = lu.Bond(\n orbitals = (1,1),\n displacement = [0,1]\n)\n\n# Build the neighbor table corresponding to all nearest-neighbor bonds.\nneighbor_table = lu.build_neighbor_table([bond_px, bond_py], unit_cell, lattice)\nprintln(\"The neighbor table, neighbor_table =\")\nshow(stdout, \"text/plain\", neighbor_table)\nprintln(\"\\n\")\n\n# The total number of sites/orbitals in the lattice.\nN = lu.nsites(unit_cell, lattice) # For square lattice this is simply N = L^2\nprintln(\"Total number of sites in lattice, N = \", N)\n\n# Total number of bonds in lattice.\nN_bonds = size(neighbor_table, 2)\nprintln(\"Total number of bonds in lattice, N_bonds = \", N_bonds)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now we define a few other bonds that are needed to measure the local s-wave, extended s-wave and d-wave pair susceptibilities.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Define a \"trivial\" bond that maps a site back onto itself.\nbond_trivial = lu.Bond(\n orbitals = (1,1),\n displacement = [0,0]\n)\n\n# Define bond in -x direction.\nbond_nx = lu.Bond(\n orbitals = (1,1),\n displacement = [-1,0]\n)\n\n# Define bond in -y direction.\nbond_ny = lu.Bond(\n orbitals = (1,1),\n displacement = [0,-1]\n)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now let us calculated the exponentiated electron kinetic energy matrix e^-Deltatau^prime K, where","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"hatK = -t sum_sigmalangle ijrangle (hatc^dagger_sigmai hatc^phantom dagger_sigmaj + rm hc)\n = sum_sigma hatmathbfc^dagger_sigma K hatmathbfc^phantomdagger_sigma","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"and hatmathbfc^dagger_sigmai = left hatc^dagger_sigma1 dots hatc^dagger_sigmaN right is a row vector of electron creation operators. Note that if symmetric = true, i.e. the symmetric definition for the propagator matrices","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"B_sigmal = e^-Deltatau^prime K cdot e^-Deltatau V_sigmal cdot e^-Deltatau^prime K","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"is being used, then Deltatau^prime = tfrac12 Deltatau. If the asymmetric definition","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"B_sigmal = e^-Deltatau V_sigmal cdot e^-Deltatau^prime K","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"is used (symmetric = false), then Deltatau^prime = Deltatau","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Note the branching logic below associated with whether or not the matrix e^-Deltatau^prime K is calculated exactly, or represented by the sparse checkerboard approximation using the package Checkerboard.jl.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Define Δτ′=Δτ/2 if symmetric = true, otherwise Δτ′=Δτ\nΔτ′ = symmetric ? Δτ/2 : Δτ\n\n# If the matrix exp(Δτ′⋅K) is represented by the checkerboard approximation.\nif checkerboard\n\n # Construct the checkerboard approximation to the matrix exp(-Δτ′⋅K).\n expnΔτ′K = cb.CheckerboardMatrix(neighbor_table, fill(t, N_bonds), Δτ′)\n\n# If the matrix exp(Δτ′⋅K) is NOT represented by the checkerboard approximation.\nelse\n\n # Construct the electron kinetic energy matrix.\n K = zeros(typeof(t), N, N)\n for bond in 1:N_bonds\n i, j = neighbor_table[1, bond], neighbor_table[2, bond]\n K[i,j] = -t\n K[j,i] = -t\n end\n\n # Calculate the exponentiated kinetic energy matrix, exp(-Δτ⋅K).\n # Note that behind the scenes Julia is diagonalizing the matrix K in order to exponentiate it.\n expnΔτ′K = exp(-Δτ′*K)\n\n # Calculate the inverse of the exponentiated kinetic energy matrix, exp(+Δτ⋅K).\n exppΔτ′K = exp(+Δτ′*K)\nend;\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"In this example we are going to introduce an Ising Hubbard-Stratonovich (HS) field to decouple the Hubbard interaction. The Ising HS transformation","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"e^-Deltatau U (hatn_uparrowil-tfrac12)(hatn_downarrowil-tfrac12) =\n frac12 e^-tfrac14 Deltatau U sum_s_il = pm 1 e^alpha s_il(hatn_uparrowil-hatn_downarrowil)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"is introduced for all imaginary time slices l in 1 L_tau and sites i in 1 N in the lattice, where","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"alpha = cosh^-1left( e^tfrac12Deltatau U right)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"is a constant. We start the simulation from a random s_il Ising HS field configuration.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Define constant associated Ising Hubbard-Stratonovich (HS) transformation.\nα = acosh(exp(Δτ*U/2))\n\n# Initialize a random Ising HS configuration.\ns = rand(rng, -1:2:1, N, Lτ)\nprintln(\"Random initial Ising HS configuration, s =\")\nshow(stdout, \"text/plain\", s)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Next we initialize a propagator matrix B_sigmal for each imaginary time slice l in 1L_tau. We first initialize a pair of vectors Bup and Bdn that will contain the L_tau propagators associated with each time slice. The branching logic below enforces the correct propagator matrix definition is used based on the boolean flags symmetric and checkerboard defined above.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Matrix element type for exponentiated electron kinetic energy matrix exp{-Δτ′⋅K}\nT_expnΔτK = eltype(t)\n\n# Matrix element type for diagonal exponentiated electron potential energy matrix exp{-Δτ⋅V[σ,l]}\nT_expnΔτV = typeof(α)\n\n# Initialize empty vector to contain propagator matrices for each imaginary time slice.\nif checkerboard && symmetric\n\n # Propagator defined as B[σ,l] = exp{-Δτ⋅K/2}⋅exp{-Δτ⋅V[σ,l]}⋅exp{-Δτ⋅K/2},\n # where the dense matrix exp{-Δτ⋅K/2} is approximated by the sparse checkerboard matrix.\n Bup = jdqmcf.SymChkbrdPropagator{T_expnΔτK, T_expnΔτV}[]\n Bdn = jdqmcf.SymChkbrdPropagator{T_expnΔτK, T_expnΔτV}[]\n\nelseif checkerboard && !symmetric\n\n # Propagator defined as B[σ,l] = exp{-Δτ⋅V[σ,l]}⋅exp{-Δτ⋅K},\n # where the dense matrix exp{-Δτ⋅K} is approximated by the sparse checkerboard matrix.\n Bup = jdqmcf.AbstractChkbrdPropagator{T_expnΔτK, T_expnΔτV}[]\n Bdn = jdqmcf.AbstractChkbrdPropagator{T_expnΔτK, T_expnΔτV}[]\n\nelseif !checkerboard && symmetric\n\n # Propagator defined as B[σ,l] = exp{-Δτ⋅K/2}⋅exp{-Δτ⋅V[σ,l]}⋅exp{-Δτ⋅K/2},\n # where the dense matrix exp{-Δτ⋅K/2} is exactly calculated.\n Bup = jdqmcf.SymExactPropagator{T_expnΔτK, T_expnΔτV}[]\n Bdn = jdqmcf.SymExactPropagator{T_expnΔτK, T_expnΔτV}[]\n\nelseif !checkerboard && !symmetric\n\n # Propagator defined as B[σ,l] = exp{-Δτ⋅V[σ,l]}⋅exp{-Δτ⋅K},\n # where the dense matrix exp{-Δτ⋅K} is exactly calculated.\n Bup = jdqmcf.AsymExactPropagator{T_expnΔτK, T_expnΔτV}[]\n Bdn = jdqmcf.AsymExactPropagator{T_expnΔτK, T_expnΔτV}[]\nend;\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Having an initialized the vector Bup and Bdn that will contain the propagator matrices, we now construct the propagator matrices for each time-slice based on the initial HS field configuration s.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Iterate over time-slices.\nfor l in 1:Lτ\n\n # Get the HS fields associated with the current time-slice l.\n s_l = @view s[:,l]\n\n # Calculate the spin-up diagonal exponentiated potential energy\n # matrix exp{-Δτ⋅V[↑,l]} = exp{-Δτ⋅(-α/Δτ⋅s[i,l]-μ)} = exp{+α⋅s[i,l] + Δτ⋅μ}.\n expnΔτVup = zeros(T_expnΔτV, N)\n @. expnΔτVup = exp(+α * s_l + Δτ*μ)\n\n # Calculate the spin-down diagonal exponentiated potential energy\n # matrix exp{-Δτ⋅V[↓,l]} = exp{-Δτ⋅(+α/Δτ⋅s[i,l]-μ)} = exp{-α⋅s[i,l] + Δτ⋅μ}.\n expnΔτVdn = zeros(T_expnΔτV, N)\n @. expnΔτVdn = exp(-α * s_l + Δτ*μ)\n\n # Initialize spin-up and spin-down propagator matrix for the current time-slice l.\n if checkerboard && symmetric\n\n push!(Bup, jdqmcf.SymChkbrdPropagator(expnΔτVup, expnΔτ′K))\n push!(Bdn, jdqmcf.SymChkbrdPropagator(expnΔτVdn, expnΔτ′K))\n\n elseif checkerboard && !symmetric\n\n push!(Bup, jdqmcf.AsymChkbrdPropagator(expnΔτVup, expnΔτ′K))\n push!(Bdn, jdqmcf.AsymChkbrdPropagator(expnΔτVdn, expnΔτ′K))\n\n elseif !checkerboard && symmetric\n\n push!(Bup, jdqmcf.SymExactPropagator(expnΔτVup, expnΔτ′K, exppΔτ′K))\n push!(Bdn, jdqmcf.SymExactPropagator(expnΔτVdn, expnΔτ′K, exppΔτ′K))\n\n elseif !checkerboard && !symmetric\n\n push!(Bup, jdqmcf.AsymExactPropagator(expnΔτVup, expnΔτ′K, exppΔτ′K))\n push!(Bdn, jdqmcf.AsymExactPropagator(expnΔτVdn, expnΔτ′K, exppΔτ′K))\n end\nend","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now we instantiate two instances for the FermionGreensCalculator type, one for each spin species, spin up and spin down. This object enables the efficient and numerically stable calculation of the Green's functions behind-the-scenes, so that we do not need to concern ourselves with implementing numerical stablization routines ourselves.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Initialize a FermionGreensCalculator for both spin up and down electrons.\nfermion_greens_calc_up = jdqmcf.FermionGreensCalculator(Bup, β, Δτ, n_stab)\nfermion_greens_calc_dn = jdqmcf.FermionGreensCalculator(Bdn, β, Δτ, n_stab);\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Next we calculate the equal-time Green's function matrices","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"G_sigma(00) = 1 + B_sigma(beta0)^-1 = 1 + B_sigmaL_tau dots B_sigma1^-1","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"for both electron spin species, sigma = (uparrow downarrow)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Calculate spin-up equal-time Green's function matrix.\nGup = zeros(typeof(t), N, N)\nlogdetGup, sgndetGup = jdqmcf.calculate_equaltime_greens!(Gup, fermion_greens_calc_up)\n\n# Calculate spin-down equal-time Green's function matrix.\nGdn = zeros(typeof(t), N, N)\nlogdetGdn, sgndetGdn = jdqmcf.calculate_equaltime_greens!(Gdn, fermion_greens_calc_dn);\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"In order to perform the DQMC simulation all we need are the equal-time Green's function matrices G_sigma(00) calculated above. However, in order to make time-displaced correlation function measurements we also need to initialize six more matrices, which correspond to G_sigma(tautau) G_sigma(tau0) and G_sigma(0tau)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Allcoate time-displaced Green's functions.\nGup_τ0 = zero(Gup) # Gup(τ,0)\nGup_0τ = zero(Gup) # Gup(0,τ)\nGup_ττ = zero(Gup) # Gup(τ,τ)\nGdn_τ0 = zero(Gdn) # Gdn(τ,0)\nGdn_0τ = zero(Gdn) # Gdn(0,τ)\nGdn_ττ = zero(Gdn); # Gdn(τ,τ)\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now we will allocate arrays to contain the various measurements we will make during the simulation, including various correlation functions. Note that the definition for each measurement will be supplied later in the tutorial when we begin processing the data to calculate the final statistics for each measured observable.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Vector to contain binned average sign measurement.\navg_sign = zeros(eltype(Gup), N_bins)\n\n# Vector to contain binned density measurement.\ndensity = zeros(eltype(Gup), N_bins)\n\n# Vector to contain binned double occupancy measurement.\ndouble_occ = zeros(eltype(Gup), N_bins)\n\n# Array to contain binned position-space time-displaced Green's function measurements.\nC_greens = zeros(Complex{Float64}, N_bins, L, L, Lτ+1)\n\n# Array to contain binned position-space time-displaced Spin-Z correlation function measurements.\nC_spinz = zeros(Complex{Float64}, N_bins, L, L, Lτ+1)\n\n# Array to contain binned position-space time-displaced density correlation function measurements.\nC_density = zeros(Complex{Float64}, N_bins, L, L, Lτ+1)\n\n# Array to contain binned position-space local s-wave pair correlation function.\nC_loc_swave = zeros(Complex{Float64}, N_bins, L, L, Lτ+1)\n\n# Array to contain binned position-space extended s-wave pair correlation function.\nC_ext_swave = zeros(Complex{Float64}, N_bins, L, L, Lτ+1)\n\n# Array to contain binned position-space d-wave pair correlation function.\nC_dwave = zeros(Complex{Float64}, N_bins, L, L, Lτ+1)\n\n# Array to contain binned momentum-space d-wave pair susceptibility.\nP_d_q = zeros(Complex{Float64}, N_bins, L, L);\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Below we implement a function that sweeps through all time-slices and sites in the lattice, attempting an update to each Ising HS field s_il.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Function to perform local updates to all Ising HS fields.\nfunction local_update!(\n Gup::Matrix{T}, logdetGup, sgndetGup, Bup, fermion_greens_calc_up,\n Gdn::Matrix{T}, logdetGdn, sgndetGdn, Bdn, fermion_greens_calc_dn,\n s, μ, α, Δτ, δG, rng\n) where {T<:Number}\n\n # Length of imaginary time axis.\n Lτ = length(Bup)\n\n # Number of sites in lattice.\n N = size(Gup,1)\n\n # Allocate temporary arrays that will be used to avoid dynamic memory allocation.\n A = zeros(T, N, N)\n u = zeros(T, N)\n v = zeros(T, N)\n\n # Allocate vector of integers to contain random permutation specifying the order in which\n # sites are iterated over at each imaginary time slice when performing local updates.\n perm = collect(1:size(Gup,1))\n\n # Variable to keep track of the acceptance rate.\n acceptance_rate = 0.0\n\n # Iterate over imaginary time slices.\n for l in fermion_greens_calc_up\n\n # Propagate equal-time Green's function matrix to current imaginary time\n # G(τ±Δτ,τ±Δτ) ==> G(τ,τ) depending on whether iterating over imaginary\n # time in the forward or reverse direction\n jdqmcf.propagate_equaltime_greens!(Gup, fermion_greens_calc_up, Bup)\n jdqmcf.propagate_equaltime_greens!(Gdn, fermion_greens_calc_dn, Bdn)\n\n # If using symmetric propagator definition (symmetric = true), then apply\n # the transformation G ==> G̃ = exp{+Δτ⋅K/2}⋅G⋅exp{-Δτ⋅K/2}.\n # If asymmetric propagator definition is used (symmetric = false),\n # then this does nothing.\n jdqmcf.partially_wrap_greens_forward!(Gup, Bup[l], A)\n jdqmcf.partially_wrap_greens_forward!(Gdn, Bdn[l], A)\n\n # Get the HS fields associated with the current imaginary time-slice.\n s_l = @view s[:,l]\n\n # Perform local updates HS fields associated with the current imaginary time slice.\n (logdetGup, sgndetGup, logdetGdn, sgndetGdn, acceptance_rate_l) = _local_update!(\n Gup, logdetGup, sgndetGup, Bup[l], Gdn, logdetGdn, sgndetGdn, Bdn[l],\n s_l, μ, α, Δτ, rng, perm, u, v\n )\n\n # Record the acceptance rate\n acceptance_rate += acceptance_rate_l / Lτ\n\n # If using symmetric propagator definition (symmetric = true), then apply\n # the transformation G̃ ==> G = exp{-Δτ⋅K/2}⋅G̃⋅exp{+Δτ⋅K/2}.\n # If asymmetric propagator definition is used (symmetric = false),\n # then this does nothing.\n jdqmcf.partially_wrap_greens_reverse!(Gup, Bup[l], A)\n jdqmcf.partially_wrap_greens_reverse!(Gdn, Bdn[l], A)\n\n # Periodically re-calculate the Green's function matrix for numerical stability.\n logdetGup, sgndetGup, δGup, δθup = jdqmcf.stabilize_equaltime_greens!(\n Gup, logdetGup, sgndetGup, fermion_greens_calc_up, Bup, update_B̄ = true\n )\n logdetGdn, sgndetGdn, δGdn, δθdn = jdqmcf.stabilize_equaltime_greens!(\n Gdn, logdetGdn, sgndetGdn, fermion_greens_calc_dn, Bdn, update_B̄ = true\n )\n\n # Record largest numerical error corrected by numerical stabilization.\n δG = max(δG, δGup, δGdn)\n\n # Keep up and down spin Green's functions synchronized as iterating over imaginary time.\n iterate(fermion_greens_calc_dn, fermion_greens_calc_up.forward)\n end\n\n return logdetGup, sgndetGup, logdetGdn, sgndetGdn, δG, acceptance_rate\nend\n\n# Iterate over all sites for single imaginary time-slice, attempting a local\n# update to each corresponding Ising HS field.\nfunction _local_update!(\n Gup, logdetGup, sgndetGup, Bup, Gdn, logdetGdn, sgndetGdn, Bdn,\n s, μ, α, Δτ, rng, perm, u, v\n)\n\n # Randomize the order in which the sites are iterated over.\n shuffle!(rng, perm)\n\n # Counter for number of accepted updates.\n accepted = 0\n\n # Iterate over sites in lattice.\n for i in perm\n\n # Calculate the new value of the diagonal potential energy matrix element\n # assuming the sign of the Ising HS field is changed.\n Vup′ = -α/Δτ * (-s[i]) - μ\n Vdn′ = +α/Δτ * (-s[i]) - μ\n\n # Calculate the determinant ratio associated with the proposed update.\n Rup, Δup = jdqmcf.local_update_det_ratio(Gup, Bup, Vup′, i, Δτ)\n Rdn, Δdn = jdqmcf.local_update_det_ratio(Gdn, Bdn, Vdn′, i, Δτ)\n\n # Calculate the acceptance probability based on the Metropolis accept/reject criteria.\n P = min(1.0, abs(Rup * Rdn))\n\n # Randomly Accept or reject the proposed update with the specified probability.\n if rand(rng) < P\n\n # Increment the accepted update counter.\n accepted += 1\n\n # Flip the appropriate Ising HS field.\n s[i] = -s[i]\n\n # Update the Green's function matrices.\n logdetGup, sgndetGup = jdqmcf.local_update_greens!(\n Gup, logdetGup, sgndetGup, Bup, Rup, Δup, i, u, v\n )\n logdetGdn, sgndetGdn = jdqmcf.local_update_greens!(\n Gdn, logdetGdn, sgndetGdn, Bdn, Rdn, Δdn, i, u, v\n )\n end\n end\n\n # Calculate the acceptance rate.\n acceptance_rate = accepted / N\n\n return logdetGup, sgndetGup, logdetGdn, sgndetGdn, acceptance_rate\nend;\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Next we implement a function to make measurements during the simulation, including time-displaced measurements. Note that if we want to calculate the expectation value for some observable langle mathcalO rangle, then during the simulation we actually measure langle mathcalS O rangle_mathcalW, where langle bullet rangle_mathcalW denotes an average with respect to states sampled according to the DQMC weights","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"mathcalW = det G_uparrow^-1 det G_downarrow^-1 ","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"such that","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"mathcalS = textsign(det G_uparrow^-1 det G_downarrow^-1)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"is the sign associated with each state. The reweighting method is then used at the end of a simulation to recover the correct expectation value according to","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"langle mathcalO rangle = frac langle mathcalSO rangle_mathcalW langle mathcalS rangle_mathcalW ","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"where langle mathcalS rangle_mathcalW is the average sign measured over the course of the simulation.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Make measurements.\nfunction make_measurements!(\n Gup, logdetGup, sgndetGup, Gup_ττ, Gup_τ0, Gup_0τ, Bup, fermion_greens_calc_up,\n Gdn, logdetGdn, sgndetGdn, Gdn_ττ, Gdn_τ0, Gdn_0τ, Bdn, fermion_greens_calc_dn,\n unit_cell, lattice, bond_trivial, bond_px, bond_nx, bond_py, bond_ny,\n bin, avg_sign, density, double_occ, C_greens, C_spinz, C_density,\n C_loc_swave, C_ext_swave, C_dwave\n)\n\n\n # Initialize time-displaced Green's function matrices for both spin species:\n # G(τ=0,τ=0) = G(0,0)\n # G(τ=0,0) = G(0,0)\n # G(0,τ=0) = -(I-G(0,0))\n jdqmcf.initialize_unequaltime_greens!(Gup_τ0, Gup_0τ, Gup_ττ, Gup)\n jdqmcf.initialize_unequaltime_greens!(Gdn_τ0, Gdn_0τ, Gdn_ττ, Gdn)\n\n # Calculate the current sign.\n sgn = sign(sgndetGup * sgndetGdn)\n\n # Measure the average sign.\n avg_sign[bin] += sgn\n\n # Measure the density.\n nup = jdqmcm.measure_n(Gup)\n ndn = jdqmcm.measure_n(Gdn)\n density[bin] += sgn * (nup + ndn)\n\n # Measure the double occupancy.\n double_occ[bin] += sgn * jdqmcm.measure_double_occ(Gup, Gdn)\n\n # Measure equal-time correlation functions.\n make_correlation_measurements!(\n Gup, Gup_ττ, Gup_τ0, Gup_0τ, Gdn, Gdn_ττ, Gdn_τ0, Gdn_0τ,\n unit_cell, lattice, bond_trivial, bond_px, bond_nx, bond_py, bond_ny,\n bin, 0, sgn, C_greens, C_spinz, C_density, C_loc_swave, C_ext_swave, C_dwave\n )\n\n # Iterate over imaginary time slices.\n for l in fermion_greens_calc_up\n\n # Propagate equal-time Green's function matrix to current imaginary time\n # G(τ±Δτ,τ±Δτ) ==> G(τ,τ) depending on whether iterating over imaginary\n # time in the forward or reverse direction\n jdqmcf.propagate_unequaltime_greens!(Gup_τ0, Gup_0τ, Gup_ττ, fermion_greens_calc_up, Bup)\n jdqmcf.propagate_unequaltime_greens!(Gdn_τ0, Gdn_0τ, Gdn_ττ, fermion_greens_calc_dn, Bdn)\n\n # Measure time-displaced correlation function measurements for τ = l⋅Δτ.\n make_correlation_measurements!(\n Gup, Gup_ττ, Gup_τ0, Gup_0τ, Gdn, Gdn_ττ, Gdn_τ0, Gdn_0τ,\n unit_cell, lattice, bond_trivial, bond_px, bond_nx, bond_py, bond_ny,\n bin, l, sgn, C_greens, C_spinz, C_density, C_loc_swave, C_ext_swave, C_dwave,\n )\n\n # Periodically re-calculate the Green's function matrix for numerical stability.\n logdetGup, sgndetGup, δGup, δθup = jdqmcf.stabilize_unequaltime_greens!(\n Gup_τ0, Gup_0τ, Gup_ττ, logdetGup, sgndetGup, fermion_greens_calc_up, Bup, update_B̄=false\n )\n logdetGdn, sgndetGdn, δGdn, δθdn = jdqmcf.stabilize_unequaltime_greens!(\n Gdn_τ0, Gdn_0τ, Gdn_ττ, logdetGdn, sgndetGdn, fermion_greens_calc_dn, Bdn, update_B̄=false\n )\n\n # Keep up and down spin Green's functions synchronized as iterating over imaginary time.\n iterate(fermion_greens_calc_dn, fermion_greens_calc_up.forward)\n end\n\n return nothing\nend\n\n# Make time-displaced measurements.\nfunction make_correlation_measurements!(\n Gup, Gup_ττ, Gup_τ0, Gup_0τ, Gdn, Gdn_ττ, Gdn_τ0, Gdn_0τ,\n unit_cell, lattice, bond_trivial, bond_px, bond_nx, bond_py, bond_ny,\n bin, l, sgn, C_greens, C_spinz, C_density, C_loc_swave, C_ext_swave, C_dwave,\n tmp = zeros(eltype(C_greens), lattice.L...)\n)\n\n # Get a view into the arrays accumulating the correlation measurements\n # for the current imaginary time-slice and bin.\n C_greens_bin_l = @view C_greens[bin,:,:,l+1]\n C_spinz_bin_l = @view C_spinz[bin,:,:,l+1]\n C_density_bin_l = @view C_density[bin,:,:,l+1]\n C_loc_swave_bin_l = @view C_loc_swave[bin,:,:,l+1]\n C_ext_swave_bin_l = @view C_ext_swave[bin,:,:,l+1]\n C_dwave_bin_l = @view C_dwave[bin,:,:,l+1]\n\n # Measure Green's function for both spin-up and spin-down.\n jdqmcm.greens!(C_greens_bin_l, 1, 1, unit_cell, lattice, Gup_τ0, sgn)\n jdqmcm.greens!(C_greens_bin_l, 1, 1, unit_cell, lattice, Gdn_τ0, sgn)\n\n # Measure spin-z spin-spin correlation.\n jdqmcm.spin_z_correlation!(\n C_spinz_bin_l, 1, 1, unit_cell, lattice,\n Gup_τ0, Gup_0τ, Gup_ττ, Gup, Gdn_τ0, Gdn_0τ, Gdn_ττ, Gdn, sgn\n )\n\n # Measure density-density correlation.\n jdqmcm.density_correlation!(\n C_density_bin_l, 1, 1, unit_cell, lattice,\n Gup_τ0, Gup_0τ, Gup_ττ, Gup, Gdn_τ0, Gdn_0τ, Gdn_ττ, Gdn, sgn\n )\n\n # Measure local s-wave correlation measurement.\n jdqmcm.pair_correlation!(\n C_loc_swave_bin_l, bond_trivial, bond_trivial, unit_cell, lattice, Gup_τ0, Gdn_τ0, sgn\n )\n\n # Group the nearest-neighbor bonds together.\n bonds = (bond_px, bond_nx, bond_py, bond_ny)\n\n # d-wave correlation phases.\n dwave_phases = (+1, +1, -1, -1)\n\n # Iterate over all pairs of nearest-neigbbor bonds.\n for i in eachindex(bonds)\n for j in eachindex(bonds)\n # Measure pair correlation associated with bond pair.\n fill!(tmp, 0)\n jdqmcm.pair_correlation!(\n tmp, bonds[i], bonds[j], unit_cell, lattice, Gup_τ0, Gdn_τ0, sgn\n )\n # Add contribution to extended s-wave and d-wave pair correlation.\n @. C_ext_swave_bin_l += tmp / 4\n @. C_dwave_bin_l += dwave_phases[i] * dwave_phases[j] * tmp / 4\n end\n end\n\n return nothing\nend;\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now we will write a top-level function to run the simulation, including both the thermalization and measurement portions of the simulation.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# High-level function to run the DQMC simulation.\nfunction run_simulation!(\n s, μ, α, Δτ, rng, N_burnin, N_bins, N_binsize, N_sweeps,\n Gup, logdetGup, sgndetGup, Gup_ττ, Gup_τ0, Gup_0τ, Bup, fermion_greens_calc_up,\n Gdn, logdetGdn, sgndetGdn, Gdn_ττ, Gdn_τ0, Gdn_0τ, Bdn, fermion_greens_calc_dn,\n unit_cell, lattice, bond_trivial, bond_px, bond_nx, bond_py, bond_ny,\n avg_sign, density, double_occ, C_greens, C_spinz, C_density,\n C_loc_swave, C_ext_swave, C_dwave\n)\n\n # Initialize variable to keep track of largest corrected numerical error.\n δG = 0.0\n\n # The acceptance rate on local updates.\n acceptance_rate = 0.0\n\n\n # Perform burnin updates to thermalize system.\n for n in 1:N_burnin\n\n # Attempt local update to every Ising HS field.\n (logdetGup, sgndetGup, logdetGdn, sgndetGdn, δG′, ac) = local_update!(\n Gup, logdetGup, sgndetGup, Bup, fermion_greens_calc_up,\n Gdn, logdetGdn, sgndetGdn, Bdn, fermion_greens_calc_dn,\n s, μ, α, Δτ, δG, rng\n )\n\n # Record max numerical error.\n δG = max(δG, δG′)\n\n # Update acceptance rate.\n acceptance_rate += ac\n end\n\n\n # Iterate over measurement bins.\n for bin in 1:N_bins\n\n # Iterate over updates and measurements in bin.\n for n in 1:N_binsize\n\n # Iterate over number of local update sweeps per measurement.\n for sweep in 1:N_sweeps\n # Attempt local update to every Ising HS field.\n (logdetGup, sgndetGup, logdetGdn, sgndetGdn, δG′, ac) = local_update!(\n Gup, logdetGup, sgndetGup, Bup, fermion_greens_calc_up,\n Gdn, logdetGdn, sgndetGdn, Bdn, fermion_greens_calc_dn,\n s, μ, α, Δτ, δG, rng\n )\n\n # Record max numerical error.\n δG = max(δG, δG′)\n\n # Update acceptance rate.\n acceptance_rate += ac\n end\n\n # Make measurements.\n make_measurements!(\n Gup, logdetGup, sgndetGup, Gup_ττ, Gup_τ0, Gup_0τ, Bup, fermion_greens_calc_up,\n Gdn, logdetGdn, sgndetGdn, Gdn_ττ, Gdn_τ0, Gdn_0τ, Bdn, fermion_greens_calc_dn,\n unit_cell, lattice, bond_trivial, bond_px, bond_nx, bond_py, bond_ny,\n bin, avg_sign, density, double_occ, C_greens, C_spinz, C_density,\n C_loc_swave, C_ext_swave, C_dwave\n )\n end\n\n # Normalize accumulated measurements by the bin size.\n avg_sign[bin] /= N_binsize\n density[bin] /= N_binsize\n double_occ[bin] /= N_binsize\n C_greens[bin,:,:,:] /= (2 * N_binsize)\n C_spinz[bin,:,:,:] /= N_binsize\n C_density[bin,:,:,:] /= N_binsize\n C_loc_swave[bin,:,:,:] /= N_binsize\n C_ext_swave[bin,:,:,:] /= N_binsize\n C_dwave[bin,:,:,:] /= N_binsize\n end\n\n # Calculate the final acceptance rate for local updates.\n acceptance_rate /= (N_burnin + N_bins * N_binsize * N_sweeps)\n\n\n return acceptance_rate, δG\nend;\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now let us run our DQMC simulation.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Run the DQMC simulation.\nacceptance_rate, δG = run_simulation!(\n s, μ, α, Δτ, rng, N_burnin, N_bins, N_binsize, N_sweeps,\n Gup, logdetGup, sgndetGup, Gup_ττ, Gup_τ0, Gup_0τ, Bup, fermion_greens_calc_up,\n Gdn, logdetGdn, sgndetGdn, Gdn_ττ, Gdn_τ0, Gdn_0τ, Bdn, fermion_greens_calc_dn,\n unit_cell, lattice, bond_trivial, bond_px, bond_nx, bond_py, bond_ny,\n avg_sign, density, double_occ, C_greens, C_spinz, C_density,\n C_loc_swave, C_ext_swave, C_dwave\n)\nprintln(\"Acceptance Rate = \", acceptance_rate)\nprintln(\"Largest Numerical Error = \", δG)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Having completed the DQMC simulation, the next step is the analyze the results, calculating the mean and error for various measuremed observables. We will first calculate the relevant global measurements, including the average density langle n rangle = langle n_uparrow + n_downarrow rangle and double occupancy langle n_uparrow n_downarrow rangle Note that the binning method is used to calculate the error bar for the correlated data. The Jackknife algorithm is also used to propagate error and correct for bias when evaluating","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"langle mathcalO rangle = frac langle mathcalS O rangle_mathcalW langle mathcalS rangle_mathcalW ","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"to account for the sign problem.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Calculate the average sign for the simulation.\nsign_avg, sign_std = ba.jackknife(identity, avg_sign)\nprintln(\"Avg Sign, S = \", sign_avg, \" +/- \", sign_std)\n\n# Calculate the average density.\ndensity_avg, density_std = ba.jackknife(/, density, avg_sign)\nprintln(\"Density, n = \", density_avg, \" +/- \", density_std)\n\n# Calculate the average double occupancy.\ndouble_occ_avg, double_occ_std = ba.jackknife(/, double_occ, avg_sign)\nprintln(\"Double occupancy, nup_ndn = \", double_occ_avg, \" +/- \", double_occ_std)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now we move onto processing the measured correlation function data. We define two functions to assist with this process. The first function integrates the binned time-displaced correlation function data over the imaginary time axis in order to generate binned susceptibility data. Note that the integration over the imaginary time axis is performed using Simpson's rule, which is accurate to order mathcalO(Deltatau^4).","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Given the binned time-displaced correlation function/structure factor data,\n# calculate and return the corresponding binned susceptibility data.\nfunction susceptibility(S::AbstractArray{T}, Δτ) where {T<:Number}\n\n # Allocate array to contain susceptibility.\n χ = zeros(T, size(S)[1:3])\n\n # Iterate over bins.\n for bin in axes(S,1)\n\n # Calculate the susceptibility for the current bin by integrating the correlation\n # data over the imaginary time axis using Simpson's rule.\n S_bin = @view S[bin,:,:,:]\n χ_bin = @view χ[bin,:,:]\n jdqmcm.susceptibility!(χ_bin, S_bin, Δτ, 3)\n end\n\n return χ\nend","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"We also define a function to calculate the average and error of a correlation function measurement based on the input binned correlation function data.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Calculate average correlation function values based on binned data.\nfunction correlation_stats(\n S::AbstractArray{Complex{T}},\n avg_sign::Vector{T}\n) where {T<:AbstractFloat}\n\n # Allocate arrays to contain the mean and standard deviation of\n # measured correlation function.\n S_avg = zeros(Complex{T}, size(S)[2:end])\n S_std = zeros(T, size(S)[2:end])\n\n # Iterate over correlation functions.\n for n in CartesianIndices(S_avg)\n # Use the jackknife method to calculage average and error.\n vals = @view S[:,n]\n S_avg[n], S_std[n] = ba.jackknife(/, vals, avg_sign)\n end\n\n return S_avg, S_std\nend","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"First, let us compute the average and error for the time-displaced electron Green's function","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"G_sigma(mathbfrtau) = langle hatc^phantom dagger_sigmamathbfi+mathbfr(tau) hatc^dagger_sigmamathbfi(0) rangle","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"in position space, and","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"G_sigma(mathbfktau) = langle hatc^phantom dagger_sigmamathbfk(tau) hatc^dagger_sigmamathbfk(0) rangle","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"in momentum space, where tau in 0 Deltatau dots beta-Deltatau beta","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Fourier transform Green's function from position to momentum space.\nS_greens = copy(C_greens)\njdqmcm.fourier_transform!(S_greens, 1, 1, (1,4), unit_cell, lattice)\n\n# Calculate average Green's function in position space.\nC_greens_avg, C_greens_std = correlation_stats(C_greens, avg_sign)\n\n# Calculate average Green's function in momentum space.\nS_greens_avg, S_greens_std = correlation_stats(S_greens, avg_sign)\n\n# Verify that the position space G(r=0,τ=0) measurement agrees with the\n# average density measurement.\nagreement = (2*(1-C_greens_avg[1,1,1]) ≈ density_avg)\nprintln(\"(2*[1-G(r=0,tau=0)] == ) = \", agreement)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now we will calculate the spin susceptibility","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"chi_z(mathbfq) = int_0^beta S_z(mathbfqtau) dtau","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"where the time-displaced spin structure","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"S_z(mathbfqtau) = sum_mathbfr e^-rm i mathbfqcdotmathbfr C_z(mathbfrtau)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"is given by the fourier transform of the spin-z correlation function","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"C_z(mathbfrtau) = frac1N sum_mathbfi langle hatS_zmathbfi+mathbfr(tau) hatS_zmathbfi(0) rangle","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"in position space. Then we report the spin-suscpetibility chi_rm afm = chi_z(pipi) corresponding to antiferromagnetism.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Fourier transform the binned Cz(r,τ) position space spin-z correlation function\n# data to get the binned Sz(q,τ) spin-z structure factor data.\nS_spinz = copy(C_spinz)\njdqmcm.fourier_transform!(S_spinz, 1, 1, (1,4), unit_cell, lattice)\n\n# Integrate the binned Sz(q,τ) spin-z structure factor data over the imaginary\n# time axis to get the binned χz(q) spin susceptibility.\nχ_spinz = susceptibility(S_spinz, Δτ)\n\n# Calculate the average spin correlation functions in position space.\nC_spinz_avg, C_spinz_std = correlation_stats(C_spinz, avg_sign)\n\n# Calculate the average spin structure factor in momentum space.\nS_spinz_avg, S_spinz_std = correlation_stats(S_spinz, avg_sign)\n\n# Calculate the average spin susceptibility for all scattering momentum q.\nχ_spinz_avg, χ_spinz_std = correlation_stats(χ_spinz, avg_sign)\n\n# Report the spin susceptibility χafm = χz(π,π) corresponding to antiferromagnetism.\nχafm_avg = real(χ_spinz_avg[L÷2+1, L÷2+1])\nχafm_std = χ_spinz_std[L÷2+1, L÷2+1]\nprintln(\"Antiferromagentic Spin Susceptibility, chi_afm = \", χafm_avg, \" +/- \", χafm_std)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Given the measured time-displaced density correlation function","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"C_rho(mathbfrtau) = sum_mathbfi\n langle hatn_mathbfi+mathbfr(tau) hatn_mathbfi(0) rangle","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"where hatn_mathbfi = (hatn_mathbfi uparrow + hatn_mathbfi downarrow) we can compute the time-displaced charge structure factor","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"S_rho(mathbfqtau) = sum_mathbfr e^-rm imathbfqcdotmathbfr C_rho(mathbfrtau)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"and corresponding charge susceptibility","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"chi_rho(mathbfq) int_0^beta S_rho(mathbfqtau) dtau","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Fourier transform the binned Cρ(r,τ) position space density correlation\n# data to get the time-dispaced charge structure factor Sρ(q,τ) in\n# momentum space.\nS_density = copy(C_density)\njdqmcm.fourier_transform!(S_density, 1, 1, (1,4), unit_cell, lattice)\n\n# Integrate the binned Sρ(q,τ) density structure factor data over the imaginary\n# time axis to get the binned χρ(q) density susceptibility.\nχ_density = susceptibility(S_density, Δτ)\n\n# Calculate the average charge correlation functions in position space.\nC_density_avg, C_density_std = correlation_stats(C_density, avg_sign)\n\n# Calculate the average charge structure factor in momentum space.\nS_density_avg, S_density_std = correlation_stats(S_density, avg_sign)\n\n# Calculate the average charge susceptibility for all scattering momentum q.\nχ_density_avg, χ_density_std = correlation_stats(χ_spinz, avg_sign);\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now we calculate the local s-wave pair susceptibility","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"P_s = frac1N int_0^beta langle hatDelta_s(tau) hatDelta_s(0) rangle dtau","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"where hatDelta_s = sum_mathbfi hatc_downarrowmathbfi hatc_uparrowmathbfi","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Fourier transform binned position space local s-wave correlation function data to get\n# the binned momentum space local s-wave structure factor data.\nS_loc_swave = copy(C_loc_swave)\njdqmcm.fourier_transform!(S_loc_swave, 1, 1, (1,4), unit_cell, lattice)\n\n# Integrate the binned local s-wave structure factor data to get the\n# binned local s-wave pair susceptibility data.\nP_loc_swave = susceptibility(S_loc_swave, Δτ)\n\n# Calculate the average local s-wave pair susceptibility for all scattering momentum q.\nP_loc_swave_avg, P_loc_swave_std = correlation_stats(P_loc_swave, avg_sign)\n\n# Report the local s-wave pair suspcetibility.\nPs_avg = real(P_loc_swave_avg[1,1])\nPs_std = P_loc_swave_std[1,1]\nprintln(\"Local s-wave pair susceptibility, P_s = \", Ps_avg, \" +/- \", Ps_std)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Next, we calculate the local s-wave pair susceptibility","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"P_textrmext-s = frac1N int_0^beta langle hatDelta_textrmext-s(tau) hatDelta_textrmext-s(0) rangle dtau","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"where","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"hatDelta_textrmext-s = frac12 sum_mathbfi\n (hatc_downarrowmathbfi+mathbfx\n +hatc_downarrowmathbfi-mathbfx\n +hatc_downarrowmathbfi+mathbfy\n +hatc_downarrowmathbfi-mathbfy)\n hatc_uparrowmathbfi","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Fourier transform binned position space extended s-wave correlation function data to get\n# the binned momentum space extended s-wave structure factor data.\nS_ext_swave = copy(C_ext_swave)\njdqmcm.fourier_transform!(S_ext_swave, 1, 1, (1,4), unit_cell, lattice)\n\n# Integrate the binned extended s-wave structure factor data to get the\n# binned extended s-wave pair susceptibility data.\nP_ext_swave = susceptibility(S_ext_swave, Δτ)\n\n# Calculate the average extended s-wave pair susceptibility for all scattering momentum q.\nP_ext_swave_avg, P_ext_swave_std = correlation_stats(P_ext_swave, avg_sign)\n\n# Report the local s-wave pair suspcetibility.\nPexts_avg = real(P_ext_swave_avg[1,1])\nPexts_std = P_ext_swave_std[1,1]\nprintln(\"Extended s-wave pair susceptibility, P_ext-s = \", Pexts_avg, \" +/- \", Pexts_std)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Lastly, we calculate the d-wave pair susceptibility","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"P_d = frac1N int_0^beta langle hatDelta_d(tau) hatDelta_d(0) rangle dtau","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"where","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"hatDelta_d = frac12 sum_mathbfi\n (hatc_downarrowmathbfi+mathbfx\n +hatc_downarrowmathbfi-mathbfx\n -hatc_downarrowmathbfi+mathbfy\n -hatc_downarrowmathbfi-mathbfy)\n hatc_uparrowmathbfi","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Fourier transform binned position space d-wave correlation function data to get\n# the binned momentum space d-wave structure factor data.\nS_dwave = copy(C_dwave)\njdqmcm.fourier_transform!(S_dwave, 1, 1, (1,4), unit_cell, lattice)\n\n# Integrate the binned d-wave structure factor data to get the\n# binned d-wave pair susceptibility data.\nP_dwave = susceptibility(S_dwave, Δτ)\n\n# Calculate the average d-wave pair susceptibility for all scattering momentum q.\nP_dwave_avg, P_dwave_std = correlation_stats(P_dwave, avg_sign)\n\n# Report the d-wave pair susceptibility.\nPd_avg = real(P_dwave_avg[1,1])\nPd_std = P_dwave_std[1,1]\nprintln(\"Extended s-wave pair susceptibility, P_d = \", Pd_avg, \" +/- \", Pd_std)","category":"page"},{"location":"","page":"Home","title":"Home","text":"CurrentModule = JDQMCFramework","category":"page"},{"location":"#JDQMCFramework.jl","page":"Home","title":"JDQMCFramework.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Documentation for JDQMCFramework. This is a utility package that exports a suite of types and routines to simplify the process of writing a DQMC code.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Matrix stabilization routines are supplied by the StableLinearAlgebra.jl package.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The checkerboard decomposition functionality supported here is provided by the Checkerboard.jl package.","category":"page"},{"location":"#Funding","page":"Home","title":"Funding","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"The development of this code was supported by the U.S. Department of Energy, Office of Science, Basic Energy Sciences, under Award Number DE-SC0022311.","category":"page"},{"location":"#Installation","page":"Home","title":"Installation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"To install JDQMCFramework.jl, simply open the Julia REPL and run the commands","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> ]\npkg> add JDQMCFramework","category":"page"},{"location":"","page":"Home","title":"Home","text":"or equivalently via Pkg do","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> using Pkg; Pkg.add(\"JDQMCFramework\")","category":"page"},{"location":"#Citation","page":"Home","title":"Citation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"If you found this library to be useful in the course of academic work, please consider citing us:","category":"page"},{"location":"","page":"Home","title":"Home","text":"@misc{SmoQyDQMC,\n title={SmoQyDQMC.jl: A flexible implementation of determinant quantum Monte Carlo for Hubbard and electron-phonon interactions}, \n author={Benjamin Cohen-Stead and Sohan Malkaruge Costa and James Neuhaus and Andy Tanjaroon Ly and Yutan Zhang and Richard Scalettar and Kipton Barros and Steven Johnston},\n year={2023},\n eprint={2311.09395},\n archivePrefix={arXiv},\n primaryClass={cond-mat.str-el},\n url={https://arxiv.org/abs/2311.09395}\n}","category":"page"},{"location":"#Formalism-and-Definitions","page":"Home","title":"Formalism and Definitions","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"This section describes the formalism and definitions adopted by the JDQMCFramework package. The following discussion assumes an existing familiarity with the determinant quantum Monte Carlo (DQMC) algorithm, a method for simulating systems of itinerant fermions on a lattice at finite temperature in the grand canonical ensemble. The DQMC formalism starts by representing the partition funciton as a path integral","category":"page"},{"location":"","page":"Home","title":"Home","text":"beginalign*\nZ= textrmTre^-betahatH=textrmTrleftprod_l=1^L_taue^-DeltatauhatHright\nendalign*","category":"page"},{"location":"","page":"Home","title":"Home","text":"in imaginary time tau=lcdotDeltatau, at inverse temperature beta=L_taucdotDeltatau. Next, the Suzuki-Trotter approximation is applied, and Hubbard-Stratonivich transformations are used as needed to render the Hamiltonian quadratic in fermion creation and annihilation operators. Lastly, the fermionic degrees of freedom are integrated out.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The resulting approximate expression for the partition function allows for the definition of Monte Carlo weights of the form","category":"page"},{"location":"","page":"Home","title":"Home","text":"W(mathbfx)=e^-S_Bprod_sigmadet M_sigma","category":"page"},{"location":"","page":"Home","title":"Home","text":"where mathbfx signifies all the relevant degrees of freedom that need to be sampled. While not written explicitly, the bosonic action S_B and each fermion determinant matrix M_sigma depend on mathbfx. In the absence of a mean field pairing term or some similarly exotic interaction, the index sigma typically corresponds to the fermion spin species. In the case of electrons this means sigma=uparrowdownarrow.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Each fermion determinant matrix is of the form","category":"page"},{"location":"","page":"Home","title":"Home","text":"beginalign*\nM_sigma(tau)= I+B_sigma(tau0)B_sigma(betatau)\n= I+B_sigmalB_sigmal-1dots B_sigma1B_sigmaL_taudots B_sigmal+2B_sigmal+1\nendalign*","category":"page"},{"location":"","page":"Home","title":"Home","text":"where","category":"page"},{"location":"","page":"Home","title":"Home","text":"B_sigma(tautau)=B_sigmalB_sigmal-1dots B_sigmal+1","category":"page"},{"location":"","page":"Home","title":"Home","text":"such that det M_sigma(tau)=det M_sigma(tau) for any pair (ll)in1L_tau.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Each propagator matrix B_sigmal=B_sigma(tautau-Deltatau) may be represented in either the symmetric form","category":"page"},{"location":"","page":"Home","title":"Home","text":"B_sigmal=e^-tfracDeltatau2K_l e^-Deltatau V_l e^-tfracDeltatau2K_l","category":"page"},{"location":"","page":"Home","title":"Home","text":"or the asymmetric form","category":"page"},{"location":"","page":"Home","title":"Home","text":"B_sigmal = e^-Deltatau V_l e^-Deltatau K_l","category":"page"},{"location":"","page":"Home","title":"Home","text":"where V_l is a diagonal matrix corresponding to the on-site energy for each site in the lattice, and K_l is the strictly off-diagonal hopping matrix.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The single-particle fermion Green's function is given by ","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigmaij(tautau)=langlehatmathcalThatc_sigmai(tau)hatc_sigmaj^dagger(tau)rangle=begincases\nlanglehatc_sigmai(tau)hatc_sigmaj^dagger(tau)rangle taugetau\n-langlehatc_sigmaj^dagger(tau)hatc_sigmai(tau)rangle tautau\nendcases","category":"page"},{"location":"","page":"Home","title":"Home","text":"where hatc_sigmai^dagger(hatc_sigmai) is the fermion creation (annihilation) operator for a fermion with spin sigma on site i on the lattice, and hatmathcalT is the time-ordering operator. The equal-time Green's function is related to the fermion determinant matrix by","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigmaij(tautau)=M_sigmaij^-1(tau)","category":"page"},{"location":"","page":"Home","title":"Home","text":"where again tau=lcdotDeltatau. The equal-time Green's function matrix can be advanced to the next imaginary time slice using the relationship","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigma(tau+Deltatautau+Deltatau)=B_sigmal+1G_sigma(tautau)B_sigmal+1^-1","category":"page"},{"location":"","page":"Home","title":"Home","text":"and","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigma(tau-Deltatautau-Deltatau)=B_sigmal^-1G_sigma(tautau)B_sigmal","category":"page"},{"location":"","page":"Home","title":"Home","text":"The unequal-time Green's function is accessible using the relations","category":"page"},{"location":"","page":"Home","title":"Home","text":"beginalign*\nG_sigma(tau0) = B_sigma(tau0)G_sigma(00)\n = B_sigma^-1(tau0) + B_sigma(betatau)^-1\nendalign*","category":"page"},{"location":"","page":"Home","title":"Home","text":"and","category":"page"},{"location":"","page":"Home","title":"Home","text":"beginalign*\nG_sigma(0tau) = -I-G_sigma(00) B_sigma^-1(tau0) \n = -B_sigma^-1(betatau) + B_sigma(tau0)^-1\nendalign*","category":"page"},{"location":"","page":"Home","title":"Home","text":"where the second relationship may be shown by applying the Woodbury matrix identity. These relationships also imply","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigma(tau0) = B_sigma^-1(tautau)G_sigma(tau0)","category":"page"},{"location":"","page":"Home","title":"Home","text":"and","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigma(0tau) = G_sigma(0tau) B_sigma(tautau)","category":"page"},{"location":"","page":"Home","title":"Home","text":"for tauin0beta-Deltatau and tautaubeta. By applying the anti-periodic boundary conditions of the single-particle Green's function in imaginary time it immediately follows that","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigma(beta0) = I-G_sigma(00)","category":"page"},{"location":"","page":"Home","title":"Home","text":"and","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigma(0beta) = -G_sigma(00)","category":"page"},{"location":"","page":"Home","title":"Home","text":"where","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigma(00)=I+B_sigma(beta0)^-1=I+B_sigmaL_taudots B_sigma1^-1","category":"page"},{"location":"","page":"Home","title":"Home","text":"subject to the boundary condition G_sigma(00)=G_sigma(betabeta).","category":"page"},{"location":"","page":"Home","title":"Home","text":"The DQMC method also requires periodic re-calculation of the fermion Green's function matrix as G_sigma(tautau) is propagated to later or ealier imaginary times to maintain numerical stability. Therefore, we introduce a parameter n_s which describes the frequency with which numerical stabilization needs to occur. The number of \"stabilization intervals\" in imaginary time is then given by N_s=leftlceil L_taun_sright rceil, and we introduce the notation","category":"page"},{"location":"","page":"Home","title":"Home","text":"barB_sigman=prod_l=(n-1)cdot n_s+1^min(ncdot n_sN_s)B_sigmal","category":"page"},{"location":"","page":"Home","title":"Home","text":"where nin1N_s, to represent the product of propagator matrices over a single stabilization interval. Using this definition we may express G_sigma(00) as","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigma(00) = (I + B_sigmaL_tau B_sigmaL_tau-1 dots B_sigma 2 B_sigma1)^-1\n = (I + barB_sigmaN_s barB_sigmaN_s-1 dots barB_sigma 2 barB_sigma1)^-1","category":"page"},{"location":"#Basic-Usage","page":"Home","title":"Basic Usage","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"In this section we introduce some of the basics of using this package by setting up the framework for a DQMC simulations in the case of a simple non-interacting square lattice tight binding model, assuming two electron spin species, spin up and spin down. While this is a \"tivial\" example, it is instructive.","category":"page"},{"location":"","page":"Home","title":"Home","text":"using LinearAlgebra\nusing LatticeUtilities\nusing JDQMCFramework","category":"page"},{"location":"","page":"Home","title":"Home","text":"First let us define the relevant model parameters.","category":"page"},{"location":"","page":"Home","title":"Home","text":"# hopping amplitude\nt = 1.0\n\n# chemical potential\nμ = 0.0\n\n# lattice size\nL = 4\n\n# inverse temperature\nβ = 3.7\n\n# discretization in imaginary time\nΔτ = 0.1\n\n# frequency of numerical stabilization\nn_stab = 10\nnothing; # hide","category":"page"},{"location":"","page":"Home","title":"Home","text":"Next we calculate the length of the imaginary time axis L_tau using the eval_length_imaginary_axis method.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Lτ = eval_length_imaginary_axis(β, Δτ)","category":"page"},{"location":"","page":"Home","title":"Home","text":"Using functionality imported from the LatticeUtilities.jl package, we construct the neighbor table for a square lattice.","category":"page"},{"location":"","page":"Home","title":"Home","text":"# define unit cell\nunit_cell = UnitCell(lattice_vecs = [[1.,0.],[0.,1.]], basis_vecs = [[0.,0.]])\n\n# define size of lattice\nlattice = Lattice(L = [L,L], periodic = [true,true])\n\n# define bonds/hoppings in x and y directions\nbond_x = Bond(orbitals = (1,1), displacement = [1,0])\nbond_y = Bond(orbitals = (1,1), displacement = [0,1])\n\n# construct neighbor table\nneighbor_table = build_neighbor_table([bond_x, bond_y], unit_cell, lattice)\n\n# calculate number of sites in lattice\nN = nsites(unit_cell, lattice)\n\n# calculate number of bonds in lattice\nNbonds = size(neighbor_table, 2)\n\n(N, Nbonds)","category":"page"},{"location":"","page":"Home","title":"Home","text":"Next we construct the strictly off-diagonal hopping matrix K and a vector to represent the diagonal on-site energy matrix V","category":"page"},{"location":"","page":"Home","title":"Home","text":"# build hopping matrix\nK = zeros(typeof(t), N, N)\nbuild_hopping_matrix!(K, neighbor_table, fill(t, Nbonds))\n\n# build vector representing diagonal on-site energy matrix\nV = fill(-μ, N)","category":"page"},{"location":"","page":"Home","title":"Home","text":"Now we define a the propagator B_sigmal for each spin species sigma and imaginary time slice tau = Deltatau cdot l Of course, in the non-interacting limit considered here all the propagators matrices are identical. This will no longer be the case if interactions are introduced, in which case each B_sigmal matrix will in general be unique.","category":"page"},{"location":"","page":"Home","title":"Home","text":"expmΔτV = exp.(-Δτ*V)\nexpmΔτK = exp(-Δτ*K)\nexppΔτK = exp(+Δτ*K)\n\n# null vector spin up propagators to fill\nBup = AsymExactPropagator{eltype(expmΔτK),eltype(expmΔτV)}[]\n\n# null vecotr of spin down propagators to fill\nBdn = AsymExactPropagator{eltype(expmΔτK),eltype(expmΔτV)}[]\n\n# construct propagator for each spin species and append to appropriate vector\nfor l in 1:Lτ\n B_l = AsymExactPropagator(expmΔτV, expmΔτK, exppΔτK)\n push!(Bup, B_l)\n push!(Bdn, B_l)\nend","category":"page"},{"location":"","page":"Home","title":"Home","text":"In the above we chose to represent the propagator matrices using the AsymExactPropagator type, which assumes the B_l = e^-Deltatau K_l e^-Deltatau V_l definition, where the K_l hopping matrix is exactly exponentiated. This package includes the other possible definitions AsymChkbrdPropagator, SymExactPropagator and SymChkbrdPropagator.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Next we instantiate two instances of the FermionGreensCalculator type, one for each of the two electron spin species, spin up and spin down.","category":"page"},{"location":"","page":"Home","title":"Home","text":"fgc_up = FermionGreensCalculator(Bup, β, Δτ, n_stab)\nfgc_dn = FermionGreensCalculator(Bdn, β, Δτ, n_stab)","category":"page"},{"location":"","page":"Home","title":"Home","text":"Now we initialize the spin up and spin down equal time Green's function matrices G_uparrow(00) and G_downarrow(00)","category":"page"},{"location":"","page":"Home","title":"Home","text":"Gup = zeros(N,N)\nlogdetGup, sgndetGup = calculate_equaltime_greens!(Gup, fgc_up)\n\nGdn = zeros(N,N)\nlogdetGdn, sgndetGdn = calculate_equaltime_greens!(Gdn, fgc_dn)","category":"page"},{"location":"","page":"Home","title":"Home","text":"Now we will demonstrate how to synchronously iterate over the imaginary time slices for both the spin up and spin down sectors.","category":"page"},{"location":"","page":"Home","title":"Home","text":"# Iterate over imaginary time τ=Δτ⋅l.\nfor l in fgc_up\n\n # Propagate equal-time Green's function matrix to current imaginary time G(τ±Δτ,τ±Δτ) ==> G(τ,τ)\n # depending on whether iterating over imaginary time in the forward or reverse direction\n propagate_equaltime_greens!(Gup, fgc_up, Bup)\n propagate_equaltime_greens!(Gdn, fgc_dn, Bdn)\n\n # LOCAL UPDATES OR EVALUATION OF DERIVATIVE OF FERMIONIC ACTION FOR THE CURRENT\n # IMAGINARY TIME SLICE WOULD GO HERE\n\n # Periodically re-calculate the Green's function matrix for numerical stability.\n # Comment: if not performing updates, but just evaluating the derivative of the action, then\n # set update_B̄=false to avoid wasting cpu time re-computing B_barₙ matrices.\n logdetGup, sgndetGup, δGup, δθup = stabilize_equaltime_greens!(Gup, logdetGup, sgndetGup, fgc_up, Bup, update_B̄=true)\n logdetGdn, sgndetGdn, δGdn, δθdn = stabilize_equaltime_greens!(Gdn, logdetGdn, sgndetGdn, fgc_dn, Bdn, update_B̄=true)\n\n # Keep up and down spin Green's functions synchronized as iterating over imaginary time.\n iterate(fgc_dn, fgc_up.forward)\nend","category":"page"},{"location":"","page":"Home","title":"Home","text":"Note that if we iterate over imaginary time again, it will iterate in the opposite direction. This is expected behavior. Each time you iterate over imaginary time the direction of iteration reverses. While not immediately obvious, this allows for a reduction in the number of required matrix factorizations.","category":"page"},{"location":"","page":"Home","title":"Home","text":"This package also exports two routines, local_update_det_ratio and local_update_greens!, that are useful for implementing local updates in a DQMC simulation.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Lastly, we will will calculate the unequal-time Green's functions G_sigma(tau0) and G_sigma(0tau), and the equal-time Green's function G_sigma(tautau) for all imaginary time slices. This functionality is important ","category":"page"},{"location":"","page":"Home","title":"Home","text":"# initialize unequal-time Green's functions\nGup_τ0 = similar(Gdn) # G₊(τ,0)\nGup_0τ = similar(Gdn) # G₊(0,τ)\nGup_ττ = similar(Gdn) # G₊(τ,τ)\nGdn_τ0 = similar(Gdn) # G₋(τ,0)\nGdn_0τ = similar(Gdn) # G₋(0,τ)\nGdn_ττ = similar(Gdn) # G₋(τ,τ)\ninitialize_unequaltime_greens!(Gup_τ0, Gup_0τ, Gup_ττ, Gup)\ninitialize_unequaltime_greens!(Gdn_τ0, Gdn_0τ, Gdn_ττ, Gdn)\n\n# EQUAL-TIME CORRELATION MEASUREMENTS WOULD GO HERE\n\n# Iterate over imaginary time τ=Δτ⋅l.\nfor l in fgc_up\n\n # Propagate Green's function matrices to current imaginary time slice\n propagate_unequaltime_greens!(Gup_τ0, Gup_0τ, Gup_ττ, fgc_up, Bup)\n propagate_unequaltime_greens!(Gdn_τ0, Gdn_0τ, Gdn_ττ, fgc_dn, Bdn)\n\n # UNEQUAL-TIME CORRELATION FUNCTION MEASUREMENTS WOULD GO HERE\n\n # Periodically re-calculate the Green's function matrix for numerical stability.\n logdetGup, sgndetGup, δGup, δθup = stabilize_unequaltime_greens!(Gup_τ0, Gup_0τ, Gup_ττ, logdetGup, sgndetGup, fgc_up, Bup, update_B̄=false)\n logdetGdn, sgndetGdn, δGdn, δθdn = stabilize_unequaltime_greens!(Gdn_τ0, Gdn_0τ, Gdn_ττ, logdetGdn, sgndetGdn, fgc_dn, Bdn, update_B̄=false)\n\n # Keep up and down spin Green's functions synchronized as iterating over imaginary time.\n iterate(fgc_dn, fgc_up.forward)\nend","category":"page"}] +[{"location":"api/#API","page":"API","title":"API","text":"","category":"section"},{"location":"api/#Propagator-Types","page":"API","title":"Propagator Types","text":"","category":"section"},{"location":"api/","page":"API","title":"API","text":"AbstractPropagator\nAbstractExactPropagator\nAbstractChkbrdPropagator\nSymExactPropagator\nAsymExactPropagator\nSymChkbrdPropagator\nAsymChkbrdPropagator\nSymPropagators","category":"page"},{"location":"api/","page":"API","title":"API","text":"AbstractPropagator\nAbstractExactPropagator\nAbstractChkbrdPropagator\nSymExactPropagator\nAsymExactPropagator\nSymChkbrdPropagator\nAsymChkbrdPropagator\nSymPropagators","category":"page"},{"location":"api/#JDQMCFramework.AbstractPropagator","page":"API","title":"JDQMCFramework.AbstractPropagator","text":"abstract type AbstractPropagator{T<:Continuous, E<:Continuous} end\n\nAbstract type to represent imaginary time propagator matrices B. All specific propagators types inherit from this abstract type. In the above T is data type of the matrix elements of the exponentiated kintetic energy matrix e^-Deltatau K_l appearing in B_l, and E is data type of the matrix elements appearing in the diagonal exponentiated potential energy matrix e^-Deltatau V_l.\n\n\n\n\n\n","category":"type"},{"location":"api/#JDQMCFramework.AbstractExactPropagator","page":"API","title":"JDQMCFramework.AbstractExactPropagator","text":"abstract type AbstractExactPropagator{T,E} <: AbstractPropagator{T,E} end\n\nAbstract type to represent imaginary time propagator matrices B defined with an exactly exponentiated hopping matrix K.\n\n\n\n\n\n","category":"type"},{"location":"api/#JDQMCFramework.AbstractChkbrdPropagator","page":"API","title":"JDQMCFramework.AbstractChkbrdPropagator","text":"abstract type AbstractChkbrdPropagator{T,E} <: AbstractPropagator{T,E} end\n\nAbstract type to represent imaginary time propagator matrices B defined with the exponentiated hopping matrix K represented by the checkerboard approximation.\n\n\n\n\n\n","category":"type"},{"location":"api/#JDQMCFramework.SymExactPropagator","page":"API","title":"JDQMCFramework.SymExactPropagator","text":"SymExactPropagator{T, E} <: AbstractExactPropagator{T,E}\n\nRepresents imaginary time propagator matrix as using the symmetric form\n\nB_l = e^-Deltatau K_l2 e^-Deltatau V_l e^-Deltatau K_l2\n\nwhere K_l is the strictly off-diagonal hopping matrix and V_l is the diagonal total on-site energy matrix.\n\nFields\n\nexpmΔτV::Vector{E}: A vector representing the diagonal exponeniated on-site energy matrix e^-Deltatau V_l\nexpmΔτKo2::Matrix{T}: The exponentiated hopping matrix e^-Deltatau K_l2\nexppΔτKo2::Matrix{T}: Inverse of the exponentiated hopping matrix e^+Deltatau K_l2\n\n\n\n\n\n","category":"type"},{"location":"api/#JDQMCFramework.AsymExactPropagator","page":"API","title":"JDQMCFramework.AsymExactPropagator","text":"AsymExactPropagator{T, E} <: AbstractExactPropagator{T,E}\n\nRepresents imaginary time propagator matrix as using the symmetric form\n\nB_l = e^-Deltatau V_l e^-Deltatau K_l\n\nwhere K_l is the strictly off-diagonal hopping matrix and V_l is the diagonal total on-site energy matrix.\n\nFields\n\nexpmΔτV::Vector{E}: A vector representing the diagonal exponeniated on-site energy matrix e^-Deltatau V_l\nexpmΔτK::Matrix{T}: The exponentiated hopping matrix e^-Deltatau K_l\nexppΔτK::Matrix{T}: Inverse of the exponentiated hopping matrix e^+Deltatau K_l\n\n\n\n\n\n","category":"type"},{"location":"api/#JDQMCFramework.SymChkbrdPropagator","page":"API","title":"JDQMCFramework.SymChkbrdPropagator","text":"SymChkbrdPropagator{T, E} <: AbstractChkbrdPropagator{T,E}\n\nRepresents imaginary time propagator matrix as using the symmetric form\n\nB_l = e^-Deltatau K_l2 e^-Deltatau V_l e^-Deltatau K_l2^dagger\n\nwhere K_l is the strictly off-diagonal hopping matrix and V_l is the diagonal total on-site energy matrix. The exponentiated hopping matrix e^-Deltatau K2 is represented by the checkerboard approximation.\n\nFields\n\nexpmΔτV::Vector{E}: A vector representing the diagonal exponeniated on-site energy matrix e^-Deltatau V_l\nexpmΔτKo2::CheckerboardMatrix{T}: The exponentiated hopping matrix e^-Deltatau K_l2 represented by the checkerboard approximation.\n\n\n\n\n\n","category":"type"},{"location":"api/#JDQMCFramework.AsymChkbrdPropagator","page":"API","title":"JDQMCFramework.AsymChkbrdPropagator","text":"AsymChkbrdPropagator{T, E} <: AbstractChkbrdPropagator{T,E}\n\nRepresents imaginary time propagator matrix as using the symmetric form\n\nB_l = e^-Deltatau V_l e^-Deltatau K_l\n\nwhere K_l is the strictly off-diagonal hopping matrix and V_l is the diagonal total on-site energy matrix. The exponentiated hopping matrix e^-Deltatau K is represented by the checkerboard approximation.\n\nFields\n\nexpmΔτV::Vector{E}: The vector representing the diagonal exponeniated on-site energy matrix e^-Deltatau V_l\nexpmΔτK::CheckerboardMatrix{T}: The exponentiated hopping matrix e^-Deltatau K_l represented by the checkerboard approximation.\n\n\n\n\n\n","category":"type"},{"location":"api/#JDQMCFramework.SymPropagators","page":"API","title":"JDQMCFramework.SymPropagators","text":"SymPropagators\n\nA union of the all the symmetric propagators types to help test whether a propagator type is symmetric. Assuming typeof{B} <: AbstractPropagator returns true, if typeof(B) <: SymPropagators returns true, then B represents a symmetric propagator, otherwise it represents an asymmetric propagator.\n\n\n\n\n\n","category":"type"},{"location":"api/#FermionGreensCalculator-Type","page":"API","title":"FermionGreensCalculator Type","text":"","category":"section"},{"location":"api/","page":"API","title":"API","text":"FermionGreensCalculator","category":"page"},{"location":"api/","page":"API","title":"API","text":"FermionGreensCalculator\nFermionGreensCalculator(::AbstractVector{P}, ::E, ::E, ::Int) where {T<:Number, E<:AbstractFloat, P<:AbstractPropagator{T}}\nFermionGreensCalculator(::FermionGreensCalculator{T,E}) where {T,E}","category":"page"},{"location":"api/#JDQMCFramework.FermionGreensCalculator","page":"API","title":"JDQMCFramework.FermionGreensCalculator","text":"FermionGreensCalculator{T<:Continuous, E<:AbstractFloat}\n\nA type to facilitate calculating the single-particle fermion Green's function matrix.\n\nFields\n\nforward::Bool: If true then iterate over imaginary time slices from l=1 to l=L_tau, if false then iterate over imaginary time slices from l=L_tau to l=1.\nl::Int: The current imaginary time slice tau = l cdot Deltatau.\nn_stab::Int: Frequency with which numerical stabilization is performed, i.e. every n_s imaginary time slices the equal-time Green's function is recomputed from scratch.\nN_stab::Int: Number of numerical stabilization intervals, N_s = leftlceil L_tau n_s rightrceil\nN::Int: Orbitals in system.\nβ::E: The inverse temperature beta=1T where T is temperature.\nΔτ::E: Discretization in imaginary time.\nLτ::Int: Length of imaginary time axis, L_tau = beta Deltatau\nB_bar::Vector{Matrix{T}}: A multidimensional array where the matrix B_bar[:,:,n] represents barB_n\nF::Vector{LDR{T,E}}: A vector of N_s LDR factorizations to represent the matrices B(0tau) and B(taubeta).\nG′::Matrix{T}: Matrix used for calculating the error corrected by numerical stabilization of the equal time Green's function.\nldr_ws::LDRWorkspace{T}: Workspace for performing LDR factorization while avoiding dynamic memory allocations.\n\n\n\n\n\n","category":"type"},{"location":"api/#JDQMCFramework.FermionGreensCalculator-Union{Tuple{P}, Tuple{E}, Tuple{T}, Tuple{AbstractVector{P}, E, E, Int64}} where {T<:Number, E<:AbstractFloat, P<:(AbstractPropagator{T})}","page":"API","title":"JDQMCFramework.FermionGreensCalculator","text":"FermionGreensCalculator(\n B::AbstractVector{P},\n β::E, Δτ::E, n_stab::Int\n) where {T<:Number, E<:AbstractFloat, P<:AbstractPropagator{T}}\n\nInitialize and return FermionGreensCalculator struct based on the vector of propagators B passed to the function.\n\n\n\n\n\n","category":"method"},{"location":"api/#JDQMCFramework.FermionGreensCalculator-Union{Tuple{FermionGreensCalculator{T, E}}, Tuple{E}, Tuple{T}} where {T, E}","page":"API","title":"JDQMCFramework.FermionGreensCalculator","text":"FermionGreensCalculator(fgc::FermionGreensCalculator{T,E}) where {T,E}\n\nReturn a new FermionGreensCalculator that is a copy of fgc.\n\n\n\n\n\n","category":"method"},{"location":"api/#DQMC-Building-Block-Routines","page":"API","title":"DQMC Building Block Routines","text":"","category":"section"},{"location":"api/","page":"API","title":"API","text":"calculate_equaltime_greens!\npropagate_equaltime_greens!\nstabilize_equaltime_greens!\ninitialize_unequaltime_greens!\npropagate_unequaltime_greens!\nstabilize_unequaltime_greens!\nlocal_update_det_ratio\nlocal_update_greens!\npartially_wrap_greens_forward!\npartially_wrap_greens_reverse!","category":"page"},{"location":"api/","page":"API","title":"API","text":"calculate_equaltime_greens!\npropagate_equaltime_greens!\nstabilize_equaltime_greens!\ninitialize_unequaltime_greens!\npropagate_unequaltime_greens!\nstabilize_unequaltime_greens!\nlocal_update_det_ratio\nlocal_update_greens!\npartially_wrap_greens_forward!\npartially_wrap_greens_reverse!","category":"page"},{"location":"api/#JDQMCFramework.calculate_equaltime_greens!","page":"API","title":"JDQMCFramework.calculate_equaltime_greens!","text":"calculate_equaltime_greens!(\n G::AbstractMatrix{T},\n fgc::FermionGreensCalculator{T,E}\n)::Tuple{E,T} where {T,E}\n\nCalculate the equal-time Greens function G(00) = G(betabeta) = I + B(beta0)^-1 using a numerically stable procedure. This method also returns log(vert det G vert) and textrmsign(det G) Note that this routine requires fgc.l == 1 or fgc.l == fgc.Lτ.\n\n\n\n\n\ncalculate_equaltime_greens!(\n G::AbstractMatrix{T},\n fgc::FermionGreensCalculator{T,E},\n B::AbstractVector{P}\n)::Tuple{E,T} where {T, E, P<:AbstractPropagator{T}}\n\nCalculate the equal-time Greens function G(00) = G(betabeta) = I + B(beta0)^-1 using a numerically stable procedure. Also re-calculate the barB_n matrices and the LDR matrix factorizations representing either B(tau0) or B(betatau) stored in fgc.F. This routine is useful for implementing global updates where every propagator matrix B_l has been modified, and the equal-time Green's function needs to be re-calculated from scratch. This method also returns log(vert det G vert) and textrmsign(det G) Note that this routine requires fgc.l == 1 or fgc.l == fgc.Lτ.\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.propagate_equaltime_greens!","page":"API","title":"JDQMCFramework.propagate_equaltime_greens!","text":"propagate_equaltime_greens!(\n G::AbstractMatrix{T},\n fgc::FermionGreensCalculator{T,E},\n B::AbstractVector{P}\n) where {T, E, P<:AbstractPropagator{T}}\n\nPropagate the equal-time Green's function matrix G from the previous imaginary time slice to the current imaginary time slice fgc.l. If iterating over imaginary time in the forward direction (fgc.forward = true) the relationship\n\nG(tau+Deltatautau+Deltatau) = B_l+1 cdot G(tautau) cdot B_l+1^-1\n\nis used, and if iterating over imaginary time in the reverse direction (fgc.forward = false) the relationship\n\nG(tau-Deltatautau-Deltatau)= B_l^-1 cdot G(tautau) cdot B_l\n\nis used instead, where the B_l propagator is given by B[l].\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.stabilize_equaltime_greens!","page":"API","title":"JDQMCFramework.stabilize_equaltime_greens!","text":"stabilize_equaltime_greens!(\n G::AbstractMatrix{T},\n logdetG::E, sgndetG::T,\n fgc::FermionGreensCalculator{T,E},\n B::AbstractVector{P};\n # KEYWORD ARGUMENTS\n update_B̄::Bool=true\n)::Tuple{E,T,E,E} where {T, E, P<:AbstractPropagator{T}}\n\nStabilize the equal-time Green's function as iterating through imaginary time tau = Deltatau cdot l For a given imaginary time slice fgc.l, this routine should be called after all changes to the B_l propagator have been made. When iterating through imaginary time in the forwards direction (fgc.forward = true), this function re-computes\n\nG(tautau) = I + B(tau0)B(betatau)^-1\n\nwhen at imaginary time slice fgc.l every fgc.n_stab imaginary time slice. When iterating through imaginary time in the reverse direction (fgc.forward = false), this function instead re-computes\n\nG(tau-Deltatautau-Deltatau) = I + B(tau-Deltatau0)B(betatau-Deltatau)^-1\n\nfor fgc.l.\n\nThis method returns four values. The first two values returned are log(vert det G(tautau) vert) and textrmsign(det G(tautau)). The latter two are the maximum error in a Green's function corrected by numerical stabilization vert delta G vert, and the error in the phase of the determinant corrected by numerical stabilization deltatheta relative to naive propagation of the Green's function matrix in imaginary time occuring instead. If no stabilization was performed, than vert delta G vert = 0 and delta theta = 0\n\nThis method also computes the LDR matrix factorizations representing B(tau 0) or B(beta tau-Deltatau) when iterating through imaginary time tau = Deltatau cdot l in the forward and reverse directions respectively. If update_B̄ = true, then the barB_n matrices are re-calculated as needed, but if update_B̄ = false, then they are left unchanged.\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.initialize_unequaltime_greens!","page":"API","title":"JDQMCFramework.initialize_unequaltime_greens!","text":"initialize_unequaltime_greens!(\n Gτ0::AbstractMatrix{T},\n G0τ::AbstractMatrix{T},\n Gττ::AbstractMatrix{T},\n G00::AbstractMatrix{T}\n) where {T<:Number}\n\nInitialize the Green's function matrices G(tau0) G(0tau) and G(tautau) for tau = 0 based on the matrix G(00)\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.propagate_unequaltime_greens!","page":"API","title":"JDQMCFramework.propagate_unequaltime_greens!","text":"propagate_unequaltime_greens!(\n Gτ0::AbstractMatrix{T},\n G0τ::AbstractMatrix{T},\n Gττ::AbstractMatrix{T},\n fgc::FermionGreensCalculator{T,E},\n B::AbstractVector{P}\n) where {T, E, P<:AbstractPropagator{T}}\n\nPropagate the Green's function matrices G(tau0), G(0tau) and G(tautau) from the previous imaginary time slice to the current imaginary time slice fgc.l. If iterating over imaginary time in the forward direction (fgc.forward = true) the relationships\n\nbeginalign\nG(tau0) = B_l cdot G(tau-Deltatau 0) \nG(0tau) = G(0 tau-Deltatau) cdot B^-1_l \nG(tautau) = B_l cdot G(tau-Deltatau tau-Deltatau) cdot B_l^-1\nendalign\n\nare used, and if iterating over imaginary time in the reverse direction (fgc.forward = false) the relationships\n\nbeginalign\nG(tau0) = B_l+1^-1 cdot G(tau+Deltatau 0) \nG(0tau) = G(0 tau + Deltatau) cdot B_l+1 \nG(tautau) = B_l+1^-1 cdot G(tau+Deltatau tau+Deltatau) cdot B_l+1\nendalign\n\nare used instead, where the B_l propagator is given by B[l].\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.stabilize_unequaltime_greens!","page":"API","title":"JDQMCFramework.stabilize_unequaltime_greens!","text":"stabilize_unequaltime_greens!(\n Gτ0::AbstractMatrix{T},\n G0τ::AbstractMatrix{T},\n Gττ::AbstractMatrix{T},\n logdetG::E, sgndetG::T,\n fgc::FermionGreensCalculator{T,E},\n B::AbstractVector{P};\n # KEYWORD ARGUMENTS\n update_B̄::Bool=true\n)::Tuple{E,T,E,E} where {T, E, P<:AbstractPropagator{T}}\n\nStabilize the Green's function matrice G(tau0), G(0tau) and G(tautau) as iterating through imaginary time tau = Deltatau cdot l For a given imaginary time slice fgc.l, this routine should be called after all changes to the B_l propagator have been made. When iterating through imaginary time in the forwards direction (fgc.forward = true), this function re-computes\n\nbeginalign\nG(tau0) = B^-1(tau0) + B(betatau)^-1 \nG(0 tau) = B^-1(betatau) + B(tau0)^-1 \nG(tautau) = I + B(tau0)B(betatau)^-1\nendalign\n\nwhen at imaginary time slice fgc.l every fgc.n_stab imaginary time slice. When iterating through imaginary time in the reverse direction (fgc.forward = false), this function instead re-computes\n\nbeginalign*\nG(tau-Deltatau0) = B^-1(tau-Deltatau0) + B(betatau-Deltatau)^-1 \nG(0tau-Deltatau) = B^-1(betatau-Deltatau) + B(tau-Deltatau0)^-1 \nG(tau-Deltatautau-Deltatau) = I + B(tau-Deltatau0)B(betatau-Deltatau)^-1\nbeginalign*\n\nfor fgc.l.\n\nThis method returns four values. The first two values returned are log(vert det G(tautau) vert) and textrmsign(det G(tautau)). The latter two are the maximum error in a Green's function corrected by numerical stabilization vert delta G vert, and the error in the phase of the determinant corrected by numerical stabilization deltatheta relative to naive propagation of the Green's function matrix in imaginary time occuring instead. If no stabilization was performed, than vert delta G vert = 0 and delta theta = 0\n\nThis method also computes the LDR matrix factorizations representing B(tau 0) or B(beta tau-Deltatau) when iterating through imaginary time tau = Deltatau cdot l in the forward and reverse directions respectively. If update_B̄ = true, then the barB_n matrices are re-calculated as needed, but if update_B̄ = false, then they are left unchanged.\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.local_update_det_ratio","page":"API","title":"JDQMCFramework.local_update_det_ratio","text":"local_update_det_ratio(\n G::AbstractMatrix{T},\n B::AbstractPropagator{T},\n V′::T, i::Int, Δτ::E\n)::Tuple{T,T} where {T,E}\n\nCalculate the determinant ratio R_li associated with a local update to the equal-time Green's function G(tautau) Also returns Delta_li which is defined below.\n\nArguments\n\nG::AbstractMatrix{T}: Equal-time Green's function matrix G(tautau)\nB::AbstractPropagator{T,E}: Represents the propagator matrix B_l where tau = Deltatau cdot l\nV′::T: The new value for the V^prime_lii matrix element in the diagonal on-site energy matrix V_l\ni::Int: Diagonal matrix element index in V_l being updated.\nΔτ::E: Discretization in imaginary time Deltatau\n\nAlgorithm\n\nThe propagator matrix B_l above is given by\n\nB_l = Lambda_l cdot Gamma_l(Deltatau)\n\nwhere, assuming the we are working in the orbital basis, Gamma_l(Deltatau) = e^-Deltatau K_l represents the exponentiated hopping matrix K_l, and Lambda_l = e^-Deltatau V_l represents the exponentiated diagonal on-site energy matrix V_l\n\nGiven a proposed update to the (ii) matrix element of the diagonal on-site energy matrix V_l, (V_lii rightarrow V^prime_lii) the corresponding determinant ratio associated with this proposed udpate is given by\n\nR_li = fracdet G(tautau)det G^prime(tautau) = 1+Delta_ii(taui)left(1-G_ii(tautau)right)\n\nwhere\n\nDelta_li = fracLambda^prime_liiLambda_lii - 1 = e^-Deltatau (V^prime_lii - V_lii) - 1\n\nThis routine returns the scalar quantities R_li and Delta_li\n\nNote that if the propagator matrix is instead represented using the symmetric form\n\nB_l = Gamma_l(Deltatau2) cdot Lambda_l cdot Gamma^dagger_l(Deltatau2)\n\nthen the matrix G needs to instead represent the transformed equal-time Green's function matrix\n\ntildeG(tautau) = Gamma_l^-1(Deltatau2) cdot G(tautau) cdot Gamma_l(Deltatau2)\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.local_update_greens!","page":"API","title":"JDQMCFramework.local_update_greens!","text":"local_update_greens!(\n G::AbstractMatrix{T}, logdetG::E, sgndetG::T,\n B::AbstractPropagator{T},\n R::T, Δ::T, i::Int,\n u::AbstractVector{T}, v::AbstractVector{T}\n)::Tuple{E,T} where {T, E<:AbstractFloat}\n\nUpdate the equal-time Green's function matrix G resulting from a local update in-place.\n\nArguments\n\nG::AbstractMatrix{T}: Equal-time Green's function matrix G(tautau) that will be updated in-place.\nlogdetG::E: The log of the absolute value of the initial Green's function matrix, log( vert det G(tautau) vert )\nsgndetG::T: The sign/phase of the determinant of the initial Green's function matrix, textrmsign( det G(tautau) )\nB::AbstractPropagator{T,E}: Propagator that needs to be updated to reflect accepted local update.\nR::T: The determinant ratio R_li = fracdet G(tautau)det G^prime(tautau)\nΔ::T: Change in the exponentiated on-site energy matrix, Delta_li = e^-Deltatau (V^prime_l(ii) - V_l(ii)) - 1\ni::Int: Matrix element of diagonal on-site energy matrix V_l that is being updated.\nu::AbstractVector{T}: Vector of length size(G,1) that is used to avoid dynamic memory allocations.\nv::AbstractVector{T}: Vector of length size(G,2) that is used to avoid dynamic memory allocations.\n\nAlgorithm\n\nThe equal-time Green's function matrix is updated using the relationship\n\nG_jk^primeleft(tautauright)=G_jkleft(tautauright)-frac1R_liG_jileft(tautauright)Delta_lileft(delta_ik-G_ikleft(tautauright)right)\n\nThe B_l progpagator B is also udpated. Additionally, this method returns log( vert det G^prime(tautau) vert ) and textrmsign( det G^prime(tautau) )\n\nAn important note is that if the propagator matrices are represented in a symmetric form, then G′ and G need to correspond to the transformed eqaul-time Green's function matrices tildeG^prime(tautau) and tildeG(tautau) Refer to the local_update_det_ratio docstring for more information.\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.partially_wrap_greens_forward!","page":"API","title":"JDQMCFramework.partially_wrap_greens_forward!","text":"partially_wrap_greens_forward!(\n G::Matrix{T},\n B::P,\n M::Matrix{T} = similar(G)\n) where {T, E, P<:AbstractPropagator{T,E}}\n\nIf the propagator B is represented in the symmetric form\n\nB_l = Gamma_l(Deltatau2) cdot Lambda_l(Deltatau) cdot Gamma_l^dagger(Deltatau2)\n\nwith tau = l cdot Deltatau where Gamma(Deltatau2) = e^-Deltatau K_l2 and Lambda(Deltatau) = e^-Deltatau V_l, then apply the transformation\n\ntildeG(tautau) = Gamma^-1_l(Deltatau2) cdot G(tautau) cdot Gamma_l(Deltatau2)\n\nto the equal-time Green's function matrix G in-place.\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.partially_wrap_greens_reverse!","page":"API","title":"JDQMCFramework.partially_wrap_greens_reverse!","text":"partially_wrap_greens_reverse!(\n G::Matrix{T},\n B::P,\n M::Matrix{T} = similar(G)\n) where {T, E, P<:AbstractPropagator{T,E}}\n\nIf the propagator B is represented in the symmetric form\n\nB_l = Gamma_l(Deltatau2) cdot Lambda_l(Deltatau) cdot Gamma_l^dagger(Deltatau2)\n\nwith tau = l cdot Deltatau where Gamma(Deltatau2) = e^-Deltatau K_l2 and Lambda(Deltatau) = e^-Deltatau V_l, then apply the transformation\n\nG(tautau) = Gamma_l(Deltatau2) cdot tildeG(tautau) cdot Gamma_l^-1(Deltatau2)\n\nto the equal-time Green's function matrix G in-place.\n\n\n\n\n\n","category":"function"},{"location":"api/#Overloaded-Functions","page":"API","title":"Overloaded Functions","text":"","category":"section"},{"location":"api/","page":"API","title":"API","text":"iterate\neltype\nresize!\nsize\ncopyto!\nishermitian\nmul!\nlmul!\nrmul!\nldiv!\nrdiv!","category":"page"},{"location":"api/","page":"API","title":"API","text":"Base.iterate\nBase.eltype\nBase.resize!\nBase.size\nBase.copyto!\nLinearAlgebra.ishermitian\nLinearAlgebra.mul!\nLinearAlgebra.lmul!\nLinearAlgebra.rmul!\nLinearAlgebra.ldiv!\nLinearAlgebra.rdiv!","category":"page"},{"location":"api/#Base.iterate","page":"API","title":"Base.iterate","text":"iterate(iter::FermionGreensCalculator)\n\niterate(iter::FermionGreensCalculator, state)\n\nIterate over imaginary time slices, alternating between iterating in the forward direction from l=1 to l=L_tau and in the reverse direction from l=L_tau to l=1. The iter.forward boolean field in the FermionGreensCalculator type determines whether the imaginary time slices are iterated over in forward or reverse order. The iter.forward field is updated as needed automatically and should not be adjusted manually.\n\n\n\n\n\n","category":"function"},{"location":"api/#Base.eltype","page":"API","title":"Base.eltype","text":"eltype(B::AbstractPropagator{T,E}) where {T,E}\n\nReturn the matrix element type of the propagator T.\n\n\n\n\n\neltype(fgc::FermionGreensCalculator{T,E}) where {T,E}\n\nReturn matrix element type T associated with an instance of FermionGreensCalculator.\n\n\n\n\n\n","category":"function"},{"location":"api/#Base.resize!","page":"API","title":"Base.resize!","text":"resize!(\n fgc::FermionGreensCalculator{T,E},\n G::Matrix{T}, logdetG::E, sgndetG::T,\n B::Vector{P}, n_stab::Int\n) where {T<:Number, E<:AbstractFloat, P<:AbstractPropagator{T}}\n\nresize!(\n fgc::FermionGreensCalculator{T,E}, n_stab::Int\n) where {T,E}\n\nUpdate fgc to reflect a new stabilizaiton frequency n_stab. If G, logdetG, sgndetG and B are also passed then the equal-time Green's function G is re-calculated and the corresponding updated values for (logdetG, sgndetG) are returned.\n\n\n\n\n\n","category":"function"},{"location":"api/#Base.size","page":"API","title":"Base.size","text":"size(B::AbstractPropagator)\n\nsize(B::AbstractPropagator, dim)\n\nReturn the size of a propagator.\n\n\n\n\n\n","category":"function"},{"location":"api/#Base.copyto!","page":"API","title":"Base.copyto!","text":"copyto!(B′::SymExactPropagator{T,E}, B::SymExactPropagator{T,E}) where {T,E}\n\ncopyto!(B′::AsymExactPropagator{T,E}, B::AsymExactPropagator{T,E}) where {T,E}\n\ncopyto!(B′::SymChkbrdPropagator{T,E}, B::SymChkbrdPropagator{T,E}) where {T,E}\n\ncopyto!(B′::AsymChkbrdPropagator{T,E}, B::AsymChkbrdPropagator{T,E}) where {T,E}\n\nCopy the propagator B to B′.\n\n\n\n\n\ncopyto!(\n fgc_out::FermionGreensCalculator{T,E},\n fgc_in::FermionGreensCalculator{T,E}\n) where {T,E}\n\nCopy the contents of fgc_in to fgc_out. If fgc_out.n_stab != fgc_in.n_stab is true, then fgc_out will be resized using resize! to match fgc_in.\n\n\n\n\n\n","category":"function"},{"location":"api/#LinearAlgebra.ishermitian","page":"API","title":"LinearAlgebra.ishermitian","text":"ishermitian(B::AbstractPropagator)\n\nReturn whether a propagator is hermitian or not.\n\n\n\n\n\n","category":"function"},{"location":"api/#LinearAlgebra.mul!","page":"API","title":"LinearAlgebra.mul!","text":"mul!(A::AbstractMatrix{T}, B::SymExactPropagator{T}, C::AbstractMatrix{T};\n M::AbstractMatrix{T}=similar(A)) where {T}\n\nmul!(A::AbstractMatrix{T}, B::AsymExactPropagator{T}, C::AbstractMatrix{T};\n M::AbstractMatrix{T}=similar(A)) where {T}\n\nmul!(A::AbstractMatrix{T}, B::AbstractChkbrdPropagator{T}, C::AbstractMatrix{T};\n M=nothing) where {T}\n\nCalculate the product A = B cdot C, where B is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then A = B^dagger cdot C is evaluated instead.\n\n\n\n\n\nmul!(A::AbstractMatrix{T}, C::AbstractMatrix{T}, B::SymExactPropagator{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nmul!(A::AbstractMatrix{T}, C::AbstractMatrix{T}, B::AsymExactPropagator{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nmul!(A::AbstractMatrix{T}, C::AbstractMatrix{T}, B::AbstractChkbrdPropagator{T};\n M=nothing) where {T}\n\nCalculate the matrix product A = C cdot B, where B is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then A = C cdot B^dagger is evaluated instead.\n\n\n\n\n\n","category":"function"},{"location":"api/#LinearAlgebra.lmul!","page":"API","title":"LinearAlgebra.lmul!","text":"lmul!(B::SymExactPropagator{T}, A::AbstractMatrix{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nlmul!(B::AsymExactPropagator{T}, A::AbstractMatrix{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nlmul!(B::AsymExactPropagator{T}, A::AbstractMatrix{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nlmul!(B::AsymChkbrdPropagator{T}, A::AbstractMatrix{T};\n M = nothing) where {T}\n\nCalculate the matrix product A = B cdot A, where B is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, when A = B^dagger cdot A is evaluated instead.\n\n\n\n\n\n","category":"function"},{"location":"api/#LinearAlgebra.rmul!","page":"API","title":"LinearAlgebra.rmul!","text":"rmul!(A::AbstractMatrix{T}, B::SymExactPropagator{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nrmul!(A::AbstractMatrix{T}, B::AsymExactPropagator{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nrmul!(A::AbstractMatrix{T}, B::SymChkbrdPropagator{T};\n M = nothing) where {T}\n\nrmul!(A::AbstractMatrix{T}, B::AsymChkbrdPropagator{T};\n M = nothing) where {T}\n\nCalculate the matrix product A = A cdot B, where B is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then A = A cdot B^dagger is evaluated instead. \n\n\n\n\n\n","category":"function"},{"location":"api/#LinearAlgebra.ldiv!","page":"API","title":"LinearAlgebra.ldiv!","text":"ldiv!(A::AbstractMatrix{T}, B::AbstractExactPropagator{T}, C::AbstractMatrix{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nldiv!(A::AbstractMatrix{T}, B::AbstractChkbrdPropagator{T}, C::AbstractMatrix{T};\n M = nothing) where {T}\n\nCalculate the matrix product A = B^-1 cdot C, where B is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then A = B^dagger^-1 cdot C is evaluated instead.\n\n\n\n\n\nldiv!(B::SymExactPropagator{T}, A::AbstractMatrix{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nldiv!(B::AsymExactPropagator{T}, A::AbstractMatrix{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nldiv!(B::SymChkbrdPropagator{T}, A::AbstractMatrix{T};\n M = nothing) where {T}\n\nldiv!(B::AsymChkbrdPropagator{T}, A::AbstractMatrix{T};\n M = nothing) where {T}\n\nCalculate the matrix product A = B^-1 cdot A, where B is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then A = B^dagger^-1 cdot A is evaluated instead.\n\n\n\n\n\n","category":"function"},{"location":"api/#LinearAlgebra.rdiv!","page":"API","title":"LinearAlgebra.rdiv!","text":"rldiv!(A::AbstractMatrix{T}, C::AbstractMatrix{T}, B::AbstractExactPropagator{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nrdiv!(A::AbstractMatrix{T}, C::AbstractMatrix{T}, B::AbstractChkbrdPropagator{T};\n M = nothing) where {T}\n\nCalculate the matrix product A = C cdot B^-1, where B is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B is asymmetric and B.adjointed = true, then A = C cdot B^dagger^-1 is evaluated instead.\n\n\n\n\n\nrdiv!(A::AbstractMatrix{T}, B::SymExactPropagator{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nrdiv!(A::AbstractMatrix{T}, B::AsymExactPropagator{T};\n M::AbstractMatrix{T} = similar(A)) where {T}\n\nrdiv!(A::AbstractMatrix{T}, B::SymChkbrdPropagator{T};\n M = nothing) where {T}\n\nrdiv!(A::AbstractMatrix{T}, B::AsymChkbrdPropagator{T};\n M = nothing) where {T}\n\nCalculate the matrix product A = A cdot B^-1, where B is a propagator matrix represented by an instance of a type inheriting from AbstractPropagator. If B is asymmetric and B.adjointed = true, then A = A cdot B^dagger^-1 is evaluated instead.\n\n\n\n\n\n","category":"function"},{"location":"api/#Utility-Functions","page":"API","title":"Utility Functions","text":"","category":"section"},{"location":"api/","page":"API","title":"API","text":"eval_length_imaginary_axis\nexp!\nbuild_hopping_matrix!","category":"page"},{"location":"api/","page":"API","title":"API","text":"eval_length_imaginary_axis\nexp!\nbuild_hopping_matrix!","category":"page"},{"location":"api/#JDQMCFramework.eval_length_imaginary_axis","page":"API","title":"JDQMCFramework.eval_length_imaginary_axis","text":"eval_length_imaginary_axis(\n β::T,\n Δτ::T\n)::Int where {T<:AbstractFloat}\n\nGiven an inverse temperature β and discretization in imaginary time Δτ, return the length of the imaginary time axis Lτ.\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.exp!","page":"API","title":"JDQMCFramework.exp!","text":"exp!(\n expαH::AbstractMatrix{T},\n H::AbstractMatrix{T},\n α::E;\n # KEYWORD ARGUMENTS\n workspace::HermitianEigenWs{T,Matrix{T},R} = HermitianEigenWs(H),\n tol::R = 1e-6\n) where {T<:Number, E<:Number, R<:AbstractFloat}\n\nGiven a Hermitian matrix H, calculate the matrix exponentials e^alpha H Note that H is left modified by this method. The workspace field is of type HermitianEigenWs, which is exported from the FastLapackInterface.jl package, is used to avoid dynamic memory allocations.\n\n\n\n\n\nexp!(\n exppαH::AbstractMatrix{T},\n expmαH::AbstractMatrix{T},\n H::AbstractMatrix{T}, α::E;\n # KEYWORD ARGUMENTS\n workspace::HermitianEigenWs{T,Matrix{T},R} = HermitianEigenWs(H),\n tol::R = 1e-6\n) where {T<:Number, E<:Number, R<:AbstractFloat}\n\nGiven a Hermitian matrix H, calculate the matrix exponentials e^+alpha H and e^-alpha H, which are written to exppαH and expmαH respectively. Note that H is left modified by this method. The workspace field is of type HermitianEigenWs, which is exported from the FastLapackInterface.jl package, is used to avoid dynamic memory allocations.\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.build_hopping_matrix!","page":"API","title":"JDQMCFramework.build_hopping_matrix!","text":"build_hopping_matrix!(\n K::AbstractMatrix{T},\n neighbor_table::Matrix{Int},\n t::AbstractVector{T}\n) where {T<:Continuous}\n\nConstruct a hopping matrix K using neighbor_table along with the corresponding hopping amplitudes t. Each column of neighbor_table stores a pair of neighboring orbitals in the lattice, such that size(neighbor_table,1) = 2.\n\n\n\n\n\n","category":"function"},{"location":"api/#Developer-API","page":"API","title":"Developer API","text":"","category":"section"},{"location":"api/","page":"API","title":"API","text":"JDQMCFramework.Continuous\nJDQMCFramework.update_factorizations!\nJDQMCFramework.update_B̄!\nJDQMCFramework.calculate_B̄!\nJDQMCFramework.stabilization_interval","category":"page"},{"location":"api/","page":"API","title":"API","text":"JDQMCFramework.Continuous\nJDQMCFramework.update_factorizations!\nJDQMCFramework.update_B̄!\nJDQMCFramework.calculate_B̄!\nJDQMCFramework.stabilization_interval","category":"page"},{"location":"api/#JDQMCFramework.Continuous","page":"API","title":"JDQMCFramework.Continuous","text":"Continuous = Union{AbstractFloat,Complex{<:AbstractFloat}}\n\nAn abstract type to represent continuous real and complex numbers.\n\n\n\n\n\n","category":"type"},{"location":"api/#JDQMCFramework.update_factorizations!","page":"API","title":"JDQMCFramework.update_factorizations!","text":"update_factorizations!(\n fgc::FermionGreensCalculator{T,E},\n B::AbstractVector{P}\n) where {T, E, P<:AbstractPropagator{T}}\n\nIf current imaginary time slice fgc.l corresponds to the boundary of a stabilization interval, calculate a LDR factorization to represent B(0 tau) or B(tau-Deltatau beta) if iterating over imaginary time in the forward (fgc.forward = true) or reverse (fgc.forward = false) directions respectively. This method should be called after all changes to the current time slice propagator matrix B_l have been made This method will also recompute barB_n as needed.\n\n\n\n\n\nupdate_factorizations!(\n fgc::FermionGreensCalculator{T,E}\n) where {T, E}\n\nIf current imaginary time slice fgc.l corresponds to the boundary of a stabilization interval, calculate a LDR factorization to represent B(tau 0) or B(beta tau-Deltatau) if iterating over imaginary time in the forward (fgc.forward = true) or reverse (fgc.forward = false) directions respectively. This method should be called after all changes to the current time slice propagator matrix B_l have been made, and any required updates to a barB_n matrix have been performed using the JDQMCFramework.update_B̄! routine.\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.update_B̄!","page":"API","title":"JDQMCFramework.update_B̄!","text":"update_B̄!(\n fgc::FermionGreensCalculator{T,E},\n B::AbstractVector{P}\n) where {T,E,P<:AbstractPropagator{T}}\n\nRecalculate barB_n if the current timeslice fgc.l corresponds to the boundary of a stabilization interval, accounting for whether imaginary time is being iterated over in the forward (fgc.forward = true) or reverse (fgc.forward = false) direction.\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.calculate_B̄!","page":"API","title":"JDQMCFramework.calculate_B̄!","text":"calculate_B̄!(\n fgc::FermionGreensCalculator{T,E},\n B::AbstractVector{P}, n::Int\n) where {T,E,P<:AbstractPropagator{T}}\n\nGiven B, a vector of all the propagator matrices B_l, calculate the matrix product\n\nbarB_sigman=prod_l=(n-1)cdot n_s+1^min(ncdot n_sL_tau)B_sigmal\n\nwith the result getting written to fgc.B_bar[n].\n\n\n\n\n\n","category":"function"},{"location":"api/#JDQMCFramework.stabilization_interval","page":"API","title":"JDQMCFramework.stabilization_interval","text":"stabilization_interval(\n fgc::FermionGreensCalculator\n)::Tuple{Int,Int}\n\nGiven the current imaginary time slice fgc.l, return the corresponding stabilization interval n = ceil(Int, fgc.l/fgc.n_stab), and the relative location within that stabilization interval l′ = mod1(fgc.l, fgc.n_stab), such that l′∈[1,n_stab]. \n\n\n\n\n\n","category":"function"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"EditURL = \"../../../examples/square_hubbard.jl\"","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Download this example as Jupyter notebook or Julia script.","category":"page"},{"location":"examples/square_hubbard/#Tutorial-1:-Square-Lattice-Hubbard-Model-DQMC-Simulation","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"","category":"section"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"This tutorial implements a determinant quantum Monte Carlo (DQMC) simulation from \"scratch\" using the JDQMCFramework.jl package, along with several others. The purpose of this tutorial is to empower researchers to write their own lightweight DQMC codes in order to address specific research needs that fall outside the scope of existing high-level DQMC packages like SmoQyDQMC.jl, and to enable rapid prototyping of algorithmic improvements to existing DQMC methods.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"This tutorial is relatively long as a lot goes into writing a full DQMC code. However, in spite of the length, each step is relatively straightforward. This is made possible by leveraging the functionality exported by JDQMCFramework.jl and other packages. For instance, the JDQMCFramework.jl package takes care of all the numerical stabilization nonsense that is one of the most challenging parts of writing a DQMC code. Also, implementing various correlation measurements in a DQMC simulation is typically very time consuming and challening, as it requires working through arduous Wick's contractions, and then implementing each term. Once again, this hurdle is largely avoided by leveraging the functionality exported by the JDQMCMeasurements.jl package, which implements a variety of standard correlation function measurements for arbitary lattice geometries.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"The repulsive Hubbard model Hamiltonian on a square lattice considered in this tutorial is given by","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"hatH = -t sum_sigmalangle ijrangle (hatc^dagger_sigmai hatc^phantom dagger_sigmaj + rm hc)\n + U sum_i (hatn_uparrowi-tfrac12)(hatn_downarrowi-tfrac12) - mu sum_sigmai hatn_sigmai","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"where hatc^dagger_sigmai (hatc^phantom dagger_sigmai) creates (annihilates) a spin sigma electron on site i in the lattice, and hatn_sigmai = hatc^dagger_sigmai hatc^phantom dagger_sigmai is the spin-sigma electron number operator for site i. In the above Hamiltonian, t is the nearest neighbor hopping integral, mu is the chemical potential, and U 0 controls the strength of the on-site Hubbard repulsion. Lastly, if mu = 00 then the Hamiltonian is particle-hole symmetric, ensuring the system is half-filled (langle n_sigma rangle = tfrac12) and that there is no sign problem. In the case of mu ne 0 there will be a sign problem.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"The script version of this tutorial, which can be downloaded using the link found at the top of this page, can be run with the command","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"julia square_hubbard.jl","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"in a terminal. This tutorial can also be downloaded as a notebook at the top of this page.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"We begin by importing the relevant packages we will need to use in this example. Note that to run this tutorial you will need to install all the required Julia packages. However, this is straightforward as all the packages used in this tutorial are registered with the Julia General package registry. This means they can all be easily installed with the Julia package manager using the add command in the same way that the JDQMCFramework.jl package is installed.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Import relevant standard template libraries.\nusing Random\nusing LinearAlgebra\n\n# Provides framework for implementing DQMC code.\nimport JDQMCFramework as jdqmcf\n\n# Exports methods for measuring various correlation functions in a DQMC simulation.\nimport JDQMCMeasurements as jdqmcm\n\n# Exports types and methods for representing lattice geometries.\nimport LatticeUtilities as lu\n\n# Exports the checkerboard approximation for representing an exponentiated hopping matrix.\nimport Checkerboard as cb\n\n# Package for performing Fast Fourier Transforms (FFTs).\nusing FFTW","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"The next incantations are included for annoying technical reasons. Without going into too much detail, the default multithreading behavior used by BLAS/LAPACK in Julia is somewhat sub-optimal. As a result, it is typically a good idea to include these commands in Julia DQMC codes, as they ensure that BLAS/LAPACK (and FFTW) run in a single-threaded fashion. For more information on this issue, I refer readers to this discussion, which is found in the documentation for the ThreadPinning.jl package.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Set number of threads used by BLAS/LAPACK to one.\nBLAS.set_num_threads(1)\n\n# Set number of threads used by FFTW to one.\nFFTW.set_num_threads(1)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now we define the relevant Hamiltonian parameter values that we want to simulate. In this example we will stick to a relatively small system size (4 times 4) and inverse temperature (beta = 4) to ensure that this tutorial can be run quickly on a personal computer. Also, in this tutorial I will include many print statements so that when the tutorial is run users can keep track of what is going on. That said, for a DQMC code that will be used in actual research you will want to replace the print statements with code that writes relevant information and measurement results to file.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Nearest-neighbor hopping amplitude.\nt = 1.0\nprintln(\"Nearest-neighbor hopping amplitude, t = \", t)\n\n# Hubbard interaction.\nU = 6.0\nprintln(\"Hubbard interaction, U = \", U)\n\n# Chemical potential.\nμ = 2.0\nprintln(\"Chemical potential, mu = \", μ)\n\n# Inverse temperature.\nβ = 4.0\nprintln(\"Inverse temperature, beta = \", β)\n\n# Lattice size.\nL = 4\nprintln(\"Linear lattice size, L = \", L)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Next we define the relevant DQMC simulation parameters.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Discretization in imaginary time.\nΔτ = 0.05\nprintln(\"Disretization in imaginary time, dtau = \", Δτ)\n\n# Length of imaginary time axis.\nLτ = round(Int, β/Δτ)\nprintln(\"Length of imaginary time axis, Ltau = \", Lτ)\n\n# Whether or not to use a symmetric or asymmetric definition for the propagator matrices.\nsymmetric = false\nprintln(\"Whether symmetric or asymmetric propagator matrices are used, symmetric = \", symmetric)\n\n# Whether or not to use the checkerboard approximation to represent the\n# exponentiated electron kinetic energy matrix exp(-Δτ⋅K).\ncheckerboard = false\nprintln(\"Whether the checkerboard approximation is used, checkerboard = \", checkerboard)\n\n# Period with which numerical stabilization is performed i.e.\n# how many imaginary time slices separate more expensive recomputations\n# of the Green's function matrix using numerically stable routines.\nn_stab = 10\nprintln(\"Numerical stabilization period, n_stab = \", n_stab)\n\n# The number of burnin sweeps through the lattice performing local updates that\n# are performed to thermalize the system.\nN_burnin = 2_500\nprintln(\"Number of burnin sweeps, N_burnin = \", N_burnin)\n\n# The number of measurements made once the system is thermalized.\nN_measurements = 10_000\nprintln(\"Number of measurements, N_measurements = \", N_measurements)\n\n# Number of local update sweeps separating sequential measurements.\nN_sweeps = 1\nprintln(\"Number of local update sweeps seperating measurements, n_sweeps = \", N_sweeps)\n\n# Number of bins used to performing a binning analysis when calculating final error bars\n# for measured observables.\nN_bins = 50\nprintln(\"Number of measurement bins, N_bins = \", N_bins)\n\n# Number of measurements averaged over per measurement bin.\nN_binsize = N_measurements ÷ N_bins\nprintln(\"Number of measurements per bin, N_binsize = \", N_binsize)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now we initialize the random number generator (RNG) that will be used in the rest of the simulation.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Initialize random number generator.\nseed = abs(rand(Int))\nrng = Xoshiro(seed)\nprintln(\"Random seed used to initialize RNG, seed = \", seed)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Next, we define our square lattice geometry using the LatticeUtilities.jl package.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Define the square lattice unit cell.\nunit_cell = lu.UnitCell(\n lattice_vecs = [[1.0, 0.0],\n [0.0, 1.0]],\n basis_vecs = [[0.0, 0.0]]\n)\n\n# Define the size of the periodic square lattice.\nlattice = lu.Lattice(\n L = [L, L],\n periodic = [true, true]\n)\n\n# Define nearest-neighbor bond in +x direction\nbond_px = lu.Bond(\n orbitals = (1,1),\n displacement = [1,0]\n)\n\n# Define nearest-neighbor bond in +y direction\nbond_py = lu.Bond(\n orbitals = (1,1),\n displacement = [0,1]\n)\n\n# Build the neighbor table corresponding to all nearest-neighbor bonds.\nneighbor_table = lu.build_neighbor_table([bond_px, bond_py], unit_cell, lattice)\nprintln(\"The neighbor table, neighbor_table =\")\nshow(stdout, \"text/plain\", neighbor_table)\nprintln(\"\\n\")\n\n# The total number of sites/orbitals in the lattice.\nN = lu.nsites(unit_cell, lattice) # For square lattice this is simply N = L^2\nprintln(\"Total number of sites in lattice, N = \", N)\n\n# Total number of bonds in lattice.\nN_bonds = size(neighbor_table, 2)\nprintln(\"Total number of bonds in lattice, N_bonds = \", N_bonds)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now we define a few other bonds that are needed to measure the local s-wave, extended s-wave and d-wave pair susceptibilities.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Define a \"trivial\" bond that maps a site back onto itself.\nbond_trivial = lu.Bond(\n orbitals = (1,1),\n displacement = [0,0]\n)\n\n# Define bond in -x direction.\nbond_nx = lu.Bond(\n orbitals = (1,1),\n displacement = [-1,0]\n)\n\n# Define bond in -y direction.\nbond_ny = lu.Bond(\n orbitals = (1,1),\n displacement = [0,-1]\n)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now let us calculated the exponentiated electron kinetic energy matrix e^-Deltatau^prime K, where","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"hatK = -t sum_sigmalangle ijrangle (hatc^dagger_sigmai hatc^phantom dagger_sigmaj + rm hc)\n = sum_sigma hatmathbfc^dagger_sigma K hatmathbfc^phantomdagger_sigma","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"and hatmathbfc^dagger_sigmai = left hatc^dagger_sigma1 dots hatc^dagger_sigmaN right is a row vector of electron creation operators. Note that if symmetric = true, i.e. the symmetric definition for the propagator matrices","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"B_sigmal = e^-Deltatau^prime K cdot e^-Deltatau V_sigmal cdot e^-Deltatau^prime K","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"is being used, then Deltatau^prime = tfrac12 Deltatau. If the asymmetric definition","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"B_sigmal = e^-Deltatau V_sigmal cdot e^-Deltatau^prime K","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"is used (symmetric = false), then Deltatau^prime = Deltatau","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Note the branching logic below associated with whether or not the matrix e^-Deltatau^prime K is calculated exactly, or represented by the sparse checkerboard approximation using the package Checkerboard.jl.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Define Δτ′=Δτ/2 if symmetric = true, otherwise Δτ′=Δτ\nΔτ′ = symmetric ? Δτ/2 : Δτ\n\n# If the matrix exp(Δτ′⋅K) is represented by the checkerboard approximation.\nif checkerboard\n\n # Construct the checkerboard approximation to the matrix exp(-Δτ′⋅K).\n expnΔτ′K = cb.CheckerboardMatrix(neighbor_table, fill(t, N_bonds), Δτ′)\n\n# If the matrix exp(Δτ′⋅K) is NOT represented by the checkerboard approximation.\nelse\n\n # Construct the electron kinetic energy matrix.\n K = zeros(typeof(t), N, N)\n for bond in 1:N_bonds\n i, j = neighbor_table[1, bond], neighbor_table[2, bond]\n K[i,j] = -t\n K[j,i] = -t\n end\n\n # Calculate the exponentiated kinetic energy matrix, exp(-Δτ⋅K).\n # Note that behind the scenes Julia is diagonalizing the matrix K in order to exponentiate it.\n expnΔτ′K = exp(-Δτ′*K)\n\n # Calculate the inverse of the exponentiated kinetic energy matrix, exp(+Δτ⋅K).\n exppΔτ′K = exp(+Δτ′*K)\nend;\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"In this example we are going to introduce an Ising Hubbard-Stratonovich (HS) field to decouple the Hubbard interaction. The Ising HS transformation","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"e^-Deltatau U (hatn_uparrowil-tfrac12)(hatn_downarrowil-tfrac12) =\n frac12 e^-tfrac14 Deltatau U sum_s_il = pm 1 e^alpha s_il(hatn_uparrowil-hatn_downarrowil)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"is introduced for all imaginary time slices l in 1 L_tau and sites i in 1 N in the lattice, where","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"alpha = cosh^-1left( e^tfrac12Deltatau U right)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"is a constant. We start the simulation from a random s_il Ising HS field configuration.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Define constant associated Ising Hubbard-Stratonovich (HS) transformation.\nα = acosh(exp(Δτ*U/2))\n\n# Initialize a random Ising HS configuration.\ns = rand(rng, -1:2:1, N, Lτ)\nprintln(\"Random initial Ising HS configuration, s =\")\nshow(stdout, \"text/plain\", s)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Next we initialize a propagator matrix B_sigmal for each imaginary time slice l in 1L_tau. We first initialize a pair of vectors Bup and Bdn that will contain the L_tau propagators associated with each time slice. The branching logic below enforces the correct propagator matrix definition is used based on the boolean flags symmetric and checkerboard defined above.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Matrix element type for exponentiated electron kinetic energy matrix exp{-Δτ′⋅K}\nT_expnΔτK = eltype(t)\n\n# Matrix element type for diagonal exponentiated electron potential energy matrix exp{-Δτ⋅V[σ,l]}\nT_expnΔτV = typeof(α)\n\n# Initialize empty vector to contain propagator matrices for each imaginary time slice.\nif checkerboard && symmetric\n\n # Propagator defined as B[σ,l] = exp{-Δτ⋅K/2}⋅exp{-Δτ⋅V[σ,l]}⋅exp{-Δτ⋅K/2},\n # where the dense matrix exp{-Δτ⋅K/2} is approximated by the sparse checkerboard matrix.\n Bup = jdqmcf.SymChkbrdPropagator{T_expnΔτK, T_expnΔτV}[]\n Bdn = jdqmcf.SymChkbrdPropagator{T_expnΔτK, T_expnΔτV}[]\n\nelseif checkerboard && !symmetric\n\n # Propagator defined as B[σ,l] = exp{-Δτ⋅V[σ,l]}⋅exp{-Δτ⋅K},\n # where the dense matrix exp{-Δτ⋅K} is approximated by the sparse checkerboard matrix.\n Bup = jdqmcf.AbstractChkbrdPropagator{T_expnΔτK, T_expnΔτV}[]\n Bdn = jdqmcf.AbstractChkbrdPropagator{T_expnΔτK, T_expnΔτV}[]\n\nelseif !checkerboard && symmetric\n\n # Propagator defined as B[σ,l] = exp{-Δτ⋅K/2}⋅exp{-Δτ⋅V[σ,l]}⋅exp{-Δτ⋅K/2},\n # where the dense matrix exp{-Δτ⋅K/2} is exactly calculated.\n Bup = jdqmcf.SymExactPropagator{T_expnΔτK, T_expnΔτV}[]\n Bdn = jdqmcf.SymExactPropagator{T_expnΔτK, T_expnΔτV}[]\n\nelseif !checkerboard && !symmetric\n\n # Propagator defined as B[σ,l] = exp{-Δτ⋅V[σ,l]}⋅exp{-Δτ⋅K},\n # where the dense matrix exp{-Δτ⋅K} is exactly calculated.\n Bup = jdqmcf.AsymExactPropagator{T_expnΔτK, T_expnΔτV}[]\n Bdn = jdqmcf.AsymExactPropagator{T_expnΔτK, T_expnΔτV}[]\nend;\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Having an initialized the vector Bup and Bdn that will contain the propagator matrices, we now construct the propagator matrices for each time-slice based on the initial HS field configuration s.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Iterate over time-slices.\nfor l in 1:Lτ\n\n # Get the HS fields associated with the current time-slice l.\n s_l = @view s[:,l]\n\n # Calculate the spin-up diagonal exponentiated potential energy\n # matrix exp{-Δτ⋅V[↑,l]} = exp{-Δτ⋅(-α/Δτ⋅s[i,l]-μ)} = exp{+α⋅s[i,l] + Δτ⋅μ}.\n expnΔτVup = zeros(T_expnΔτV, N)\n @. expnΔτVup = exp(+α * s_l + Δτ*μ)\n\n # Calculate the spin-down diagonal exponentiated potential energy\n # matrix exp{-Δτ⋅V[↓,l]} = exp{-Δτ⋅(+α/Δτ⋅s[i,l]-μ)} = exp{-α⋅s[i,l] + Δτ⋅μ}.\n expnΔτVdn = zeros(T_expnΔτV, N)\n @. expnΔτVdn = exp(-α * s_l + Δτ*μ)\n\n # Initialize spin-up and spin-down propagator matrix for the current time-slice l.\n if checkerboard && symmetric\n\n push!(Bup, jdqmcf.SymChkbrdPropagator(expnΔτVup, expnΔτ′K))\n push!(Bdn, jdqmcf.SymChkbrdPropagator(expnΔτVdn, expnΔτ′K))\n\n elseif checkerboard && !symmetric\n\n push!(Bup, jdqmcf.AsymChkbrdPropagator(expnΔτVup, expnΔτ′K))\n push!(Bdn, jdqmcf.AsymChkbrdPropagator(expnΔτVdn, expnΔτ′K))\n\n elseif !checkerboard && symmetric\n\n push!(Bup, jdqmcf.SymExactPropagator(expnΔτVup, expnΔτ′K, exppΔτ′K))\n push!(Bdn, jdqmcf.SymExactPropagator(expnΔτVdn, expnΔτ′K, exppΔτ′K))\n\n elseif !checkerboard && !symmetric\n\n push!(Bup, jdqmcf.AsymExactPropagator(expnΔτVup, expnΔτ′K, exppΔτ′K))\n push!(Bdn, jdqmcf.AsymExactPropagator(expnΔτVdn, expnΔτ′K, exppΔτ′K))\n end\nend","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now we instantiate two instances for the FermionGreensCalculator type, one for each spin species, spin up and spin down. This object enables the efficient and numerically stable calculation of the Green's functions behind-the-scenes, so that we do not need to concern ourselves with implementing numerical stablization routines ourselves.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Initialize a FermionGreensCalculator for both spin up and down electrons.\nfermion_greens_calc_up = jdqmcf.FermionGreensCalculator(Bup, β, Δτ, n_stab)\nfermion_greens_calc_dn = jdqmcf.FermionGreensCalculator(Bdn, β, Δτ, n_stab);\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Next we calculate the equal-time Green's function matrices","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"G_sigma(00) = 1 + B_sigma(beta0)^-1 = 1 + B_sigmaL_tau dots B_sigma1^-1","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"for both electron spin species, sigma = (uparrow downarrow)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Calculate spin-up equal-time Green's function matrix.\nGup = zeros(typeof(t), N, N)\nlogdetGup, sgndetGup = jdqmcf.calculate_equaltime_greens!(Gup, fermion_greens_calc_up)\n\n# Calculate spin-down equal-time Green's function matrix.\nGdn = zeros(typeof(t), N, N)\nlogdetGdn, sgndetGdn = jdqmcf.calculate_equaltime_greens!(Gdn, fermion_greens_calc_dn);\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"In order to perform the DQMC simulation all we need are the equal-time Green's function matrices G_sigma(00) calculated above. However, in order to make time-displaced correlation function measurements we also need to initialize six more matrices, which correspond to G_sigma(tautau) G_sigma(tau0) and G_sigma(0tau)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Allcoate time-displaced Green's functions.\nGup_τ0 = zero(Gup) # Gup(τ,0)\nGup_0τ = zero(Gup) # Gup(0,τ)\nGup_ττ = zero(Gup) # Gup(τ,τ)\nGdn_τ0 = zero(Gdn) # Gdn(τ,0)\nGdn_0τ = zero(Gdn) # Gdn(0,τ)\nGdn_ττ = zero(Gdn); # Gdn(τ,τ)\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now we will allocate arrays to contain the various measurements we will make during the simulation, including various correlation functions. Note that the definition for each measurement will be supplied later in the tutorial when we begin processing the data to calculate the final statistics for each measured observable.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Vector to contain binned average sign measurement.\navg_sign = zeros(eltype(Gup), N_bins)\n\n# Vector to contain binned density measurement.\ndensity = zeros(eltype(Gup), N_bins)\n\n# Vector to contain binned double occupancy measurement.\ndouble_occ = zeros(eltype(Gup), N_bins)\n\n# Array to contain binned position-space time-displaced Green's function measurements.\nC_greens = zeros(Complex{Float64}, N_bins, L, L, Lτ+1)\n\n# Array to contain binned position-space time-displaced Spin-Z correlation function measurements.\nC_spinz = zeros(Complex{Float64}, N_bins, L, L, Lτ+1)\n\n# Array to contain binned position-space time-displaced density correlation function measurements.\nC_density = zeros(Complex{Float64}, N_bins, L, L, Lτ+1)\n\n# Array to contain binned position-space local s-wave pair correlation function.\nC_loc_swave = zeros(Complex{Float64}, N_bins, L, L, Lτ+1)\n\n# Array to contain binned position-space extended s-wave pair correlation function.\nC_ext_swave = zeros(Complex{Float64}, N_bins, L, L, Lτ+1)\n\n# Array to contain binned position-space d-wave pair correlation function.\nC_dwave = zeros(Complex{Float64}, N_bins, L, L, Lτ+1)\n\n# Array to contain binned momentum-space d-wave pair susceptibility.\nP_d_q = zeros(Complex{Float64}, N_bins, L, L);\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Below we implement a function that sweeps through all time-slices and sites in the lattice, attempting an update to each Ising HS field s_il.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Function to perform local updates to all Ising HS fields.\nfunction local_update!(\n Gup::Matrix{T}, logdetGup, sgndetGup, Bup, fermion_greens_calc_up,\n Gdn::Matrix{T}, logdetGdn, sgndetGdn, Bdn, fermion_greens_calc_dn,\n s, μ, α, Δτ, δG, rng\n) where {T<:Number}\n\n # Length of imaginary time axis.\n Lτ = length(Bup)\n\n # Number of sites in lattice.\n N = size(Gup,1)\n\n # Allocate temporary arrays that will be used to avoid dynamic memory allocation.\n A = zeros(T, N, N)\n u = zeros(T, N)\n v = zeros(T, N)\n\n # Allocate vector of integers to contain random permutation specifying the order in which\n # sites are iterated over at each imaginary time slice when performing local updates.\n perm = collect(1:size(Gup,1))\n\n # Variable to keep track of the acceptance rate.\n acceptance_rate = 0.0\n\n # Iterate over imaginary time slices.\n for l in fermion_greens_calc_up\n\n # Propagate equal-time Green's function matrix to current imaginary time\n # G(τ±Δτ,τ±Δτ) ==> G(τ,τ) depending on whether iterating over imaginary\n # time in the forward or reverse direction\n jdqmcf.propagate_equaltime_greens!(Gup, fermion_greens_calc_up, Bup)\n jdqmcf.propagate_equaltime_greens!(Gdn, fermion_greens_calc_dn, Bdn)\n\n # If using symmetric propagator definition (symmetric = true), then apply\n # the transformation G ==> G̃ = exp{+Δτ⋅K/2}⋅G⋅exp{-Δτ⋅K/2}.\n # If asymmetric propagator definition is used (symmetric = false),\n # then this does nothing.\n jdqmcf.partially_wrap_greens_forward!(Gup, Bup[l], A)\n jdqmcf.partially_wrap_greens_forward!(Gdn, Bdn[l], A)\n\n # Get the HS fields associated with the current imaginary time-slice.\n s_l = @view s[:,l]\n\n # Perform local updates HS fields associated with the current imaginary time slice.\n (logdetGup, sgndetGup, logdetGdn, sgndetGdn, acceptance_rate_l) = _local_update!(\n Gup, logdetGup, sgndetGup, Bup[l], Gdn, logdetGdn, sgndetGdn, Bdn[l],\n s_l, μ, α, Δτ, rng, perm, u, v\n )\n\n # Record the acceptance rate\n acceptance_rate += acceptance_rate_l / Lτ\n\n # If using symmetric propagator definition (symmetric = true), then apply\n # the transformation G̃ ==> G = exp{-Δτ⋅K/2}⋅G̃⋅exp{+Δτ⋅K/2}.\n # If asymmetric propagator definition is used (symmetric = false),\n # then this does nothing.\n jdqmcf.partially_wrap_greens_reverse!(Gup, Bup[l], A)\n jdqmcf.partially_wrap_greens_reverse!(Gdn, Bdn[l], A)\n\n # Periodically re-calculate the Green's function matrix for numerical stability.\n logdetGup, sgndetGup, δGup, δθup = jdqmcf.stabilize_equaltime_greens!(\n Gup, logdetGup, sgndetGup, fermion_greens_calc_up, Bup, update_B̄ = true\n )\n logdetGdn, sgndetGdn, δGdn, δθdn = jdqmcf.stabilize_equaltime_greens!(\n Gdn, logdetGdn, sgndetGdn, fermion_greens_calc_dn, Bdn, update_B̄ = true\n )\n\n # Record largest numerical error corrected by numerical stabilization.\n δG = max(δG, δGup, δGdn)\n\n # Keep up and down spin Green's functions synchronized as iterating over imaginary time.\n iterate(fermion_greens_calc_dn, fermion_greens_calc_up.forward)\n end\n\n return logdetGup, sgndetGup, logdetGdn, sgndetGdn, δG, acceptance_rate\nend\n\n# Iterate over all sites for single imaginary time-slice, attempting a local\n# update to each corresponding Ising HS field.\nfunction _local_update!(\n Gup, logdetGup, sgndetGup, Bup, Gdn, logdetGdn, sgndetGdn, Bdn,\n s, μ, α, Δτ, rng, perm, u, v\n)\n\n # Randomize the order in which the sites are iterated over.\n shuffle!(rng, perm)\n\n # Counter for number of accepted updates.\n accepted = 0\n\n # Iterate over sites in lattice.\n for i in perm\n\n # Calculate the new value of the diagonal potential energy matrix element\n # assuming the sign of the Ising HS field is changed.\n Vup′ = -α/Δτ * (-s[i]) - μ\n Vdn′ = +α/Δτ * (-s[i]) - μ\n\n # Calculate the determinant ratio associated with the proposed update.\n Rup, Δup = jdqmcf.local_update_det_ratio(Gup, Bup, Vup′, i, Δτ)\n Rdn, Δdn = jdqmcf.local_update_det_ratio(Gdn, Bdn, Vdn′, i, Δτ)\n\n # Calculate the acceptance probability based on the Metropolis accept/reject criteria.\n P = min(1.0, abs(Rup * Rdn))\n\n # Randomly Accept or reject the proposed update with the specified probability.\n if rand(rng) < P\n\n # Increment the accepted update counter.\n accepted += 1\n\n # Flip the appropriate Ising HS field.\n s[i] = -s[i]\n\n # Update the Green's function matrices.\n logdetGup, sgndetGup = jdqmcf.local_update_greens!(\n Gup, logdetGup, sgndetGup, Bup, Rup, Δup, i, u, v\n )\n logdetGdn, sgndetGdn = jdqmcf.local_update_greens!(\n Gdn, logdetGdn, sgndetGdn, Bdn, Rdn, Δdn, i, u, v\n )\n end\n end\n\n # Calculate the acceptance rate.\n acceptance_rate = accepted / N\n\n return logdetGup, sgndetGup, logdetGdn, sgndetGdn, acceptance_rate\nend;\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Next we implement a function to make measurements during the simulation, including time-displaced measurements. Note that if we want to calculate the expectation value for some observable langle mathcalO rangle, then during the simulation we actually measure langle mathcalS O rangle_mathcalW, where langle bullet rangle_mathcalW denotes an average with respect to states sampled according to the DQMC weights","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"mathcalW = det G_uparrow^-1 det G_downarrow^-1 ","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"such that","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"mathcalS = textsign(det G_uparrow^-1 det G_downarrow^-1)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"is the sign associated with each state. The reweighting method is then used at the end of a simulation to recover the correct expectation value according to","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"langle mathcalO rangle = frac langle mathcalSO rangle_mathcalW langle mathcalS rangle_mathcalW ","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"where langle mathcalS rangle_mathcalW is the average sign measured over the course of the simulation.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Make measurements.\nfunction make_measurements!(\n Gup, logdetGup, sgndetGup, Gup_ττ, Gup_τ0, Gup_0τ, Bup, fermion_greens_calc_up,\n Gdn, logdetGdn, sgndetGdn, Gdn_ττ, Gdn_τ0, Gdn_0τ, Bdn, fermion_greens_calc_dn,\n unit_cell, lattice, bond_trivial, bond_px, bond_nx, bond_py, bond_ny,\n bin, avg_sign, density, double_occ, C_greens, C_spinz, C_density,\n C_loc_swave, C_ext_swave, C_dwave\n)\n\n\n # Initialize time-displaced Green's function matrices for both spin species:\n # G(τ=0,τ=0) = G(0,0)\n # G(τ=0,0) = G(0,0)\n # G(0,τ=0) = -(I-G(0,0))\n jdqmcf.initialize_unequaltime_greens!(Gup_τ0, Gup_0τ, Gup_ττ, Gup)\n jdqmcf.initialize_unequaltime_greens!(Gdn_τ0, Gdn_0τ, Gdn_ττ, Gdn)\n\n # Calculate the current sign.\n sgn = sign(sgndetGup * sgndetGdn)\n\n # Measure the average sign.\n avg_sign[bin] += sgn\n\n # Measure the density.\n nup = jdqmcm.measure_n(Gup)\n ndn = jdqmcm.measure_n(Gdn)\n density[bin] += sgn * (nup + ndn)\n\n # Measure the double occupancy.\n double_occ[bin] += sgn * jdqmcm.measure_double_occ(Gup, Gdn)\n\n # Measure equal-time correlation functions.\n make_correlation_measurements!(\n Gup, Gup_ττ, Gup_τ0, Gup_0τ, Gdn, Gdn_ττ, Gdn_τ0, Gdn_0τ,\n unit_cell, lattice, bond_trivial, bond_px, bond_nx, bond_py, bond_ny,\n bin, 0, sgn, C_greens, C_spinz, C_density, C_loc_swave, C_ext_swave, C_dwave\n )\n\n # Iterate over imaginary time slices.\n for l in fermion_greens_calc_up\n\n # Propagate equal-time Green's function matrix to current imaginary time\n # G(τ±Δτ,τ±Δτ) ==> G(τ,τ) depending on whether iterating over imaginary\n # time in the forward or reverse direction\n jdqmcf.propagate_unequaltime_greens!(Gup_τ0, Gup_0τ, Gup_ττ, fermion_greens_calc_up, Bup)\n jdqmcf.propagate_unequaltime_greens!(Gdn_τ0, Gdn_0τ, Gdn_ττ, fermion_greens_calc_dn, Bdn)\n\n # Measure time-displaced correlation function measurements for τ = l⋅Δτ.\n make_correlation_measurements!(\n Gup, Gup_ττ, Gup_τ0, Gup_0τ, Gdn, Gdn_ττ, Gdn_τ0, Gdn_0τ,\n unit_cell, lattice, bond_trivial, bond_px, bond_nx, bond_py, bond_ny,\n bin, l, sgn, C_greens, C_spinz, C_density, C_loc_swave, C_ext_swave, C_dwave,\n )\n\n # Periodically re-calculate the Green's function matrix for numerical stability.\n logdetGup, sgndetGup, δGup, δθup = jdqmcf.stabilize_unequaltime_greens!(\n Gup_τ0, Gup_0τ, Gup_ττ, logdetGup, sgndetGup, fermion_greens_calc_up, Bup, update_B̄=false\n )\n logdetGdn, sgndetGdn, δGdn, δθdn = jdqmcf.stabilize_unequaltime_greens!(\n Gdn_τ0, Gdn_0τ, Gdn_ττ, logdetGdn, sgndetGdn, fermion_greens_calc_dn, Bdn, update_B̄=false\n )\n\n # Keep up and down spin Green's functions synchronized as iterating over imaginary time.\n iterate(fermion_greens_calc_dn, fermion_greens_calc_up.forward)\n end\n\n return nothing\nend\n\n# Make time-displaced measurements.\nfunction make_correlation_measurements!(\n Gup, Gup_ττ, Gup_τ0, Gup_0τ, Gdn, Gdn_ττ, Gdn_τ0, Gdn_0τ,\n unit_cell, lattice, bond_trivial, bond_px, bond_nx, bond_py, bond_ny,\n bin, l, sgn, C_greens, C_spinz, C_density, C_loc_swave, C_ext_swave, C_dwave,\n tmp = zeros(eltype(C_greens), lattice.L...)\n)\n\n # Get a view into the arrays accumulating the correlation measurements\n # for the current imaginary time-slice and bin.\n C_greens_bin_l = @view C_greens[bin,:,:,l+1]\n C_spinz_bin_l = @view C_spinz[bin,:,:,l+1]\n C_density_bin_l = @view C_density[bin,:,:,l+1]\n C_loc_swave_bin_l = @view C_loc_swave[bin,:,:,l+1]\n C_ext_swave_bin_l = @view C_ext_swave[bin,:,:,l+1]\n C_dwave_bin_l = @view C_dwave[bin,:,:,l+1]\n\n # Measure Green's function for both spin-up and spin-down.\n jdqmcm.greens!(C_greens_bin_l, 1, 1, unit_cell, lattice, Gup_τ0, sgn)\n jdqmcm.greens!(C_greens_bin_l, 1, 1, unit_cell, lattice, Gdn_τ0, sgn)\n\n # Measure spin-z spin-spin correlation.\n jdqmcm.spin_z_correlation!(\n C_spinz_bin_l, 1, 1, unit_cell, lattice,\n Gup_τ0, Gup_0τ, Gup_ττ, Gup, Gdn_τ0, Gdn_0τ, Gdn_ττ, Gdn, sgn\n )\n\n # Measure density-density correlation.\n jdqmcm.density_correlation!(\n C_density_bin_l, 1, 1, unit_cell, lattice,\n Gup_τ0, Gup_0τ, Gup_ττ, Gup, Gdn_τ0, Gdn_0τ, Gdn_ττ, Gdn, sgn\n )\n\n # Measure local s-wave correlation measurement.\n jdqmcm.pair_correlation!(\n C_loc_swave_bin_l, bond_trivial, bond_trivial, unit_cell, lattice, Gup_τ0, Gdn_τ0, sgn\n )\n\n # Group the nearest-neighbor bonds together.\n bonds = (bond_px, bond_nx, bond_py, bond_ny)\n\n # d-wave correlation phases.\n dwave_phases = (+1, +1, -1, -1)\n\n # Iterate over all pairs of nearest-neigbbor bonds.\n for i in eachindex(bonds)\n for j in eachindex(bonds)\n # Measure pair correlation associated with bond pair.\n fill!(tmp, 0)\n jdqmcm.pair_correlation!(\n tmp, bonds[i], bonds[j], unit_cell, lattice, Gup_τ0, Gdn_τ0, sgn\n )\n # Add contribution to extended s-wave and d-wave pair correlation.\n @. C_ext_swave_bin_l += tmp / 4\n @. C_dwave_bin_l += dwave_phases[i] * dwave_phases[j] * tmp / 4\n end\n end\n\n return nothing\nend;\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now we will write a top-level function to run the simulation, including both the thermalization and measurement portions of the simulation.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# High-level function to run the DQMC simulation.\nfunction run_simulation!(\n s, μ, α, Δτ, rng, N_burnin, N_bins, N_binsize, N_sweeps,\n Gup, logdetGup, sgndetGup, Gup_ττ, Gup_τ0, Gup_0τ, Bup, fermion_greens_calc_up,\n Gdn, logdetGdn, sgndetGdn, Gdn_ττ, Gdn_τ0, Gdn_0τ, Bdn, fermion_greens_calc_dn,\n unit_cell, lattice, bond_trivial, bond_px, bond_nx, bond_py, bond_ny,\n avg_sign, density, double_occ, C_greens, C_spinz, C_density,\n C_loc_swave, C_ext_swave, C_dwave\n)\n\n # Initialize variable to keep track of largest corrected numerical error.\n δG = 0.0\n\n # The acceptance rate on local updates.\n acceptance_rate = 0.0\n\n\n # Perform burnin updates to thermalize system.\n for n in 1:N_burnin\n\n # Attempt local update to every Ising HS field.\n (logdetGup, sgndetGup, logdetGdn, sgndetGdn, δG′, ac) = local_update!(\n Gup, logdetGup, sgndetGup, Bup, fermion_greens_calc_up,\n Gdn, logdetGdn, sgndetGdn, Bdn, fermion_greens_calc_dn,\n s, μ, α, Δτ, δG, rng\n )\n\n # Record max numerical error.\n δG = max(δG, δG′)\n\n # Update acceptance rate.\n acceptance_rate += ac\n end\n\n\n # Iterate over measurement bins.\n for bin in 1:N_bins\n\n # Iterate over updates and measurements in bin.\n for n in 1:N_binsize\n\n # Iterate over number of local update sweeps per measurement.\n for sweep in 1:N_sweeps\n # Attempt local update to every Ising HS field.\n (logdetGup, sgndetGup, logdetGdn, sgndetGdn, δG′, ac) = local_update!(\n Gup, logdetGup, sgndetGup, Bup, fermion_greens_calc_up,\n Gdn, logdetGdn, sgndetGdn, Bdn, fermion_greens_calc_dn,\n s, μ, α, Δτ, δG, rng\n )\n\n # Record max numerical error.\n δG = max(δG, δG′)\n\n # Update acceptance rate.\n acceptance_rate += ac\n end\n\n # Make measurements.\n make_measurements!(\n Gup, logdetGup, sgndetGup, Gup_ττ, Gup_τ0, Gup_0τ, Bup, fermion_greens_calc_up,\n Gdn, logdetGdn, sgndetGdn, Gdn_ττ, Gdn_τ0, Gdn_0τ, Bdn, fermion_greens_calc_dn,\n unit_cell, lattice, bond_trivial, bond_px, bond_nx, bond_py, bond_ny,\n bin, avg_sign, density, double_occ, C_greens, C_spinz, C_density,\n C_loc_swave, C_ext_swave, C_dwave\n )\n end\n\n # Normalize accumulated measurements by the bin size.\n avg_sign[bin] /= N_binsize\n density[bin] /= N_binsize\n double_occ[bin] /= N_binsize\n C_greens[bin,:,:,:] /= (2 * N_binsize)\n C_spinz[bin,:,:,:] /= N_binsize\n C_density[bin,:,:,:] /= N_binsize\n C_loc_swave[bin,:,:,:] /= N_binsize\n C_ext_swave[bin,:,:,:] /= N_binsize\n C_dwave[bin,:,:,:] /= N_binsize\n end\n\n # Calculate the final acceptance rate for local updates.\n acceptance_rate /= (N_burnin + N_bins * N_binsize * N_sweeps)\n\n\n return acceptance_rate, δG\nend;\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now let us run our DQMC simulation.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Run the DQMC simulation.\nacceptance_rate, δG = run_simulation!(\n s, μ, α, Δτ, rng, N_burnin, N_bins, N_binsize, N_sweeps,\n Gup, logdetGup, sgndetGup, Gup_ττ, Gup_τ0, Gup_0τ, Bup, fermion_greens_calc_up,\n Gdn, logdetGdn, sgndetGdn, Gdn_ττ, Gdn_τ0, Gdn_0τ, Bdn, fermion_greens_calc_dn,\n unit_cell, lattice, bond_trivial, bond_px, bond_nx, bond_py, bond_ny,\n avg_sign, density, double_occ, C_greens, C_spinz, C_density,\n C_loc_swave, C_ext_swave, C_dwave\n)\nprintln(\"Acceptance Rate = \", acceptance_rate)\nprintln(\"Largest Numerical Error = \", δG)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Having completed the DQMC simulation, the next step is the analyze the results, calculating the mean and error for various measuremed observables. We will first calculate the relevant global measurements, including the average density langle n rangle = langle n_uparrow + n_downarrow rangle and double occupancy langle n_uparrow n_downarrow rangle Note that the binning method is used to calculate the error bar for the correlated data. The Jackknife algorithm is also used to propagate error and correct for bias when evaluating","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"langle mathcalO rangle = frac langle mathcalS O rangle_mathcalW langle mathcalS rangle_mathcalW ","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"to account for the sign problem.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Calculate the average sign for the simulation.\nsign_avg, sign_std = jdqmcm.jackknife(identity, avg_sign)\nprintln(\"Avg Sign, S = \", sign_avg, \" +/- \", sign_std)\n\n# Calculate the average density.\ndensity_avg, density_std = jdqmcm.jackknife(/, density, avg_sign)\nprintln(\"Density, n = \", density_avg, \" +/- \", density_std)\n\n# Calculate the average double occupancy.\ndouble_occ_avg, double_occ_std = jdqmcm.jackknife(/, double_occ, avg_sign)\nprintln(\"Double occupancy, nup_ndn = \", double_occ_avg, \" +/- \", double_occ_std)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now we move onto processing the measured correlation function data. We define two functions to assist with this process. The first function integrates the binned time-displaced correlation function data over the imaginary time axis in order to generate binned susceptibility data. Note that the integration over the imaginary time axis is performed using Simpson's rule, which is accurate to order mathcalO(Deltatau^4).","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Given the binned time-displaced correlation function/structure factor data,\n# calculate and return the corresponding binned susceptibility data.\nfunction susceptibility(S::AbstractArray{T}, Δτ) where {T<:Number}\n\n # Allocate array to contain susceptibility.\n χ = zeros(T, size(S)[1:3])\n\n # Iterate over bins.\n for bin in axes(S,1)\n\n # Calculate the susceptibility for the current bin by integrating the correlation\n # data over the imaginary time axis using Simpson's rule.\n S_bin = @view S[bin,:,:,:]\n χ_bin = @view χ[bin,:,:]\n jdqmcm.susceptibility!(χ_bin, S_bin, Δτ, 3)\n end\n\n return χ\nend","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"We also define a function to calculate the average and error of a correlation function measurement based on the input binned correlation function data.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Calculate average correlation function values based on binned data.\nfunction correlation_stats(\n S::AbstractArray{Complex{T}},\n avg_sign::Vector{T}\n) where {T<:AbstractFloat}\n\n # Allocate arrays to contain the mean and standard deviation of\n # measured correlation function.\n S_avg = zeros(Complex{T}, size(S)[2:end])\n S_std = zeros(T, size(S)[2:end])\n\n # Number of bins.\n N_bins = length(avg_sign)\n\n # Preallocate arrays to make the jackknife error analysis faster.\n jackknife_samples = (zeros(Complex{T}, N_bins), zeros(T, N_bins))\n jackknife_g = zeros(Complex{T}, N_bins)\n\n # Iterate over correlation functions.\n for n in CartesianIndices(S_avg)\n # Use the jackknife method to calculage average and error.\n vals = @view S[:,n]\n S_avg[n], S_std[n] = jdqmcm.jackknife(\n /, vals, avg_sign,\n jackknife_samples = jackknife_samples,\n jackknife_g = jackknife_g\n )\n end\n\n return S_avg, S_std\nend","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"First, let us compute the average and error for the time-displaced electron Green's function","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"G_sigma(mathbfrtau) = langle hatc^phantom dagger_sigmamathbfi+mathbfr(tau) hatc^dagger_sigmamathbfi(0) rangle","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"in position space, and","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"G_sigma(mathbfktau) = langle hatc^phantom dagger_sigmamathbfk(tau) hatc^dagger_sigmamathbfk(0) rangle","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"in momentum space, where tau in 0 Deltatau dots beta-Deltatau beta","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Fourier transform Green's function from position to momentum space.\nS_greens = copy(C_greens)\njdqmcm.fourier_transform!(S_greens, 1, 1, (1,4), unit_cell, lattice)\n\n# Calculate average Green's function in position space.\nC_greens_avg, C_greens_std = correlation_stats(C_greens, avg_sign)\n\n# Calculate average Green's function in momentum space.\nS_greens_avg, S_greens_std = correlation_stats(S_greens, avg_sign)\n\n# Verify that the position space G(r=0,τ=0) measurement agrees with the\n# average density measurement.\nagreement = (2*(1-C_greens_avg[1,1,1]) ≈ density_avg)\nprintln(\"(2*[1-G(r=0,tau=0)] == ) = \", agreement)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now we will calculate the spin susceptibility","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"chi_z(mathbfq) = int_0^beta S_z(mathbfqtau) dtau","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"where the time-displaced spin structure","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"S_z(mathbfqtau) = sum_mathbfr e^-rm i mathbfqcdotmathbfr C_z(mathbfrtau)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"is given by the fourier transform of the spin-z correlation function","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"C_z(mathbfrtau) = frac1N sum_mathbfi langle hatS_zmathbfi+mathbfr(tau) hatS_zmathbfi(0) rangle","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"in position space. Then we report the spin-suscpetibility chi_rm afm = chi_z(pipi) corresponding to antiferromagnetism.","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Fourier transform the binned Cz(r,τ) position space spin-z correlation function\n# data to get the binned Sz(q,τ) spin-z structure factor data.\nS_spinz = copy(C_spinz)\njdqmcm.fourier_transform!(S_spinz, 1, 1, (1,4), unit_cell, lattice)\n\n# Integrate the binned Sz(q,τ) spin-z structure factor data over the imaginary\n# time axis to get the binned χz(q) spin susceptibility.\nχ_spinz = susceptibility(S_spinz, Δτ)\n\n# Calculate the average spin correlation functions in position space.\nC_spinz_avg, C_spinz_std = correlation_stats(C_spinz, avg_sign)\n\n# Calculate the average spin structure factor in momentum space.\nS_spinz_avg, S_spinz_std = correlation_stats(S_spinz, avg_sign)\n\n# Calculate the average spin susceptibility for all scattering momentum q.\nχ_spinz_avg, χ_spinz_std = correlation_stats(χ_spinz, avg_sign)\n\n# Report the spin susceptibility χafm = χz(π,π) corresponding to antiferromagnetism.\nχafm_avg = real(χ_spinz_avg[L÷2+1, L÷2+1])\nχafm_std = χ_spinz_std[L÷2+1, L÷2+1]\nprintln(\"Antiferromagentic Spin Susceptibility, chi_afm = \", χafm_avg, \" +/- \", χafm_std)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Given the measured time-displaced density correlation function","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"C_rho(mathbfrtau) = sum_mathbfi\n langle hatn_mathbfi+mathbfr(tau) hatn_mathbfi(0) rangle","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"where hatn_mathbfi = (hatn_mathbfi uparrow + hatn_mathbfi downarrow) we can compute the time-displaced charge structure factor","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"S_rho(mathbfqtau) = sum_mathbfr e^-rm imathbfqcdotmathbfr C_rho(mathbfrtau)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"and corresponding charge susceptibility","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"chi_rho(mathbfq) int_0^beta S_rho(mathbfqtau) dtau","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Fourier transform the binned Cρ(r,τ) position space density correlation\n# data to get the time-dispaced charge structure factor Sρ(q,τ) in\n# momentum space.\nS_density = copy(C_density)\njdqmcm.fourier_transform!(S_density, 1, 1, (1,4), unit_cell, lattice)\n\n# Integrate the binned Sρ(q,τ) density structure factor data over the imaginary\n# time axis to get the binned χρ(q) density susceptibility.\nχ_density = susceptibility(S_density, Δτ)\n\n# Calculate the average charge correlation functions in position space.\nC_density_avg, C_density_std = correlation_stats(C_density, avg_sign)\n\n# Calculate the average charge structure factor in momentum space.\nS_density_avg, S_density_std = correlation_stats(S_density, avg_sign)\n\n# Calculate the average charge susceptibility for all scattering momentum q.\nχ_density_avg, χ_density_std = correlation_stats(χ_spinz, avg_sign);\nnothing #hide","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Now we calculate the local s-wave pair susceptibility","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"P_s = frac1N int_0^beta langle hatDelta_s(tau) hatDelta_s(0) rangle dtau","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"where hatDelta_s = sum_mathbfi hatc_downarrowmathbfi hatc_uparrowmathbfi","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Fourier transform binned position space local s-wave correlation function data to get\n# the binned momentum space local s-wave structure factor data.\nS_loc_swave = copy(C_loc_swave)\njdqmcm.fourier_transform!(S_loc_swave, 1, 1, (1,4), unit_cell, lattice)\n\n# Integrate the binned local s-wave structure factor data to get the\n# binned local s-wave pair susceptibility data.\nP_loc_swave = susceptibility(S_loc_swave, Δτ)\n\n# Calculate the average local s-wave pair susceptibility for all scattering momentum q.\nP_loc_swave_avg, P_loc_swave_std = correlation_stats(P_loc_swave, avg_sign)\n\n# Report the local s-wave pair suspcetibility.\nPs_avg = real(P_loc_swave_avg[1,1])\nPs_std = P_loc_swave_std[1,1]\nprintln(\"Local s-wave pair susceptibility, P_s = \", Ps_avg, \" +/- \", Ps_std)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Next, we calculate the local s-wave pair susceptibility","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"P_textrmext-s = frac1N int_0^beta langle hatDelta_textrmext-s(tau) hatDelta_textrmext-s(0) rangle dtau","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"where","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"hatDelta_textrmext-s = frac12 sum_mathbfi\n (hatc_downarrowmathbfi+mathbfx\n +hatc_downarrowmathbfi-mathbfx\n +hatc_downarrowmathbfi+mathbfy\n +hatc_downarrowmathbfi-mathbfy)\n hatc_uparrowmathbfi","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Fourier transform binned position space extended s-wave correlation function data to get\n# the binned momentum space extended s-wave structure factor data.\nS_ext_swave = copy(C_ext_swave)\njdqmcm.fourier_transform!(S_ext_swave, 1, 1, (1,4), unit_cell, lattice)\n\n# Integrate the binned extended s-wave structure factor data to get the\n# binned extended s-wave pair susceptibility data.\nP_ext_swave = susceptibility(S_ext_swave, Δτ)\n\n# Calculate the average extended s-wave pair susceptibility for all scattering momentum q.\nP_ext_swave_avg, P_ext_swave_std = correlation_stats(P_ext_swave, avg_sign)\n\n# Report the local s-wave pair suspcetibility.\nPexts_avg = real(P_ext_swave_avg[1,1])\nPexts_std = P_ext_swave_std[1,1]\nprintln(\"Extended s-wave pair susceptibility, P_ext-s = \", Pexts_avg, \" +/- \", Pexts_std)","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"Lastly, we calculate the d-wave pair susceptibility","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"P_d = frac1N int_0^beta langle hatDelta_d(tau) hatDelta_d(0) rangle dtau","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"where","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"hatDelta_d = frac12 sum_mathbfi\n (hatc_downarrowmathbfi+mathbfx\n +hatc_downarrowmathbfi-mathbfx\n -hatc_downarrowmathbfi+mathbfy\n -hatc_downarrowmathbfi-mathbfy)\n hatc_uparrowmathbfi","category":"page"},{"location":"examples/square_hubbard/","page":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","title":"Tutorial 1: Square Lattice Hubbard Model DQMC Simulation","text":"# Fourier transform binned position space d-wave correlation function data to get\n# the binned momentum space d-wave structure factor data.\nS_dwave = copy(C_dwave)\njdqmcm.fourier_transform!(S_dwave, 1, 1, (1,4), unit_cell, lattice)\n\n# Integrate the binned d-wave structure factor data to get the\n# binned d-wave pair susceptibility data.\nP_dwave = susceptibility(S_dwave, Δτ)\n\n# Calculate the average d-wave pair susceptibility for all scattering momentum q.\nP_dwave_avg, P_dwave_std = correlation_stats(P_dwave, avg_sign)\n\n# Report the d-wave pair susceptibility.\nPd_avg = real(P_dwave_avg[1,1])\nPd_std = P_dwave_std[1,1]\nprintln(\"Extended s-wave pair susceptibility, P_d = \", Pd_avg, \" +/- \", Pd_std)","category":"page"},{"location":"","page":"Home","title":"Home","text":"CurrentModule = JDQMCFramework","category":"page"},{"location":"#JDQMCFramework.jl","page":"Home","title":"JDQMCFramework.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Documentation for JDQMCFramework. This is a utility package that exports a suite of types and routines to simplify the process of writing a DQMC code.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Matrix stabilization routines are supplied by the StableLinearAlgebra.jl package.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The checkerboard decomposition functionality supported here is provided by the Checkerboard.jl package.","category":"page"},{"location":"#Funding","page":"Home","title":"Funding","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"The development of this code was supported by the U.S. Department of Energy, Office of Science, Basic Energy Sciences, under Award Number DE-SC0022311.","category":"page"},{"location":"#Installation","page":"Home","title":"Installation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"To install JDQMCFramework.jl, simply open the Julia REPL and run the commands","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> ]\npkg> add JDQMCFramework","category":"page"},{"location":"","page":"Home","title":"Home","text":"or equivalently via Pkg do","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> using Pkg; Pkg.add(\"JDQMCFramework\")","category":"page"},{"location":"#Citation","page":"Home","title":"Citation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"If you found this library to be useful in the course of academic work, please consider citing us:","category":"page"},{"location":"","page":"Home","title":"Home","text":"@misc{SmoQyDQMC,\n title={SmoQyDQMC.jl: A flexible implementation of determinant quantum Monte Carlo for Hubbard and electron-phonon interactions}, \n author={Benjamin Cohen-Stead and Sohan Malkaruge Costa and James Neuhaus and Andy Tanjaroon Ly and Yutan Zhang and Richard Scalettar and Kipton Barros and Steven Johnston},\n year={2023},\n eprint={2311.09395},\n archivePrefix={arXiv},\n primaryClass={cond-mat.str-el},\n url={https://arxiv.org/abs/2311.09395}\n}","category":"page"},{"location":"#Formalism-and-Definitions","page":"Home","title":"Formalism and Definitions","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"This section describes the formalism and definitions adopted by the JDQMCFramework package. The following discussion assumes an existing familiarity with the determinant quantum Monte Carlo (DQMC) algorithm, a method for simulating systems of itinerant fermions on a lattice at finite temperature in the grand canonical ensemble. The DQMC formalism starts by representing the partition funciton as a path integral","category":"page"},{"location":"","page":"Home","title":"Home","text":"beginalign*\nZ= textrmTre^-betahatH=textrmTrleftprod_l=1^L_taue^-DeltatauhatHright\nendalign*","category":"page"},{"location":"","page":"Home","title":"Home","text":"in imaginary time tau=lcdotDeltatau, at inverse temperature beta=L_taucdotDeltatau. Next, the Suzuki-Trotter approximation is applied, and Hubbard-Stratonivich transformations are used as needed to render the Hamiltonian quadratic in fermion creation and annihilation operators. Lastly, the fermionic degrees of freedom are integrated out.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The resulting approximate expression for the partition function allows for the definition of Monte Carlo weights of the form","category":"page"},{"location":"","page":"Home","title":"Home","text":"W(mathbfx)=e^-S_Bprod_sigmadet M_sigma","category":"page"},{"location":"","page":"Home","title":"Home","text":"where mathbfx signifies all the relevant degrees of freedom that need to be sampled. While not written explicitly, the bosonic action S_B and each fermion determinant matrix M_sigma depend on mathbfx. In the absence of a mean field pairing term or some similarly exotic interaction, the index sigma typically corresponds to the fermion spin species. In the case of electrons this means sigma=uparrowdownarrow.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Each fermion determinant matrix is of the form","category":"page"},{"location":"","page":"Home","title":"Home","text":"beginalign*\nM_sigma(tau)= I+B_sigma(tau0)B_sigma(betatau)\n= I+B_sigmalB_sigmal-1dots B_sigma1B_sigmaL_taudots B_sigmal+2B_sigmal+1\nendalign*","category":"page"},{"location":"","page":"Home","title":"Home","text":"where","category":"page"},{"location":"","page":"Home","title":"Home","text":"B_sigma(tautau)=B_sigmalB_sigmal-1dots B_sigmal+1","category":"page"},{"location":"","page":"Home","title":"Home","text":"such that det M_sigma(tau)=det M_sigma(tau) for any pair (ll)in1L_tau.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Each propagator matrix B_sigmal=B_sigma(tautau-Deltatau) may be represented in either the symmetric form","category":"page"},{"location":"","page":"Home","title":"Home","text":"B_sigmal=e^-tfracDeltatau2K_l e^-Deltatau V_l e^-tfracDeltatau2K_l","category":"page"},{"location":"","page":"Home","title":"Home","text":"or the asymmetric form","category":"page"},{"location":"","page":"Home","title":"Home","text":"B_sigmal = e^-Deltatau V_l e^-Deltatau K_l","category":"page"},{"location":"","page":"Home","title":"Home","text":"where V_l is a diagonal matrix corresponding to the on-site energy for each site in the lattice, and K_l is the strictly off-diagonal hopping matrix.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The single-particle fermion Green's function is given by ","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigmaij(tautau)=langlehatmathcalThatc_sigmai(tau)hatc_sigmaj^dagger(tau)rangle=begincases\nlanglehatc_sigmai(tau)hatc_sigmaj^dagger(tau)rangle taugetau\n-langlehatc_sigmaj^dagger(tau)hatc_sigmai(tau)rangle tautau\nendcases","category":"page"},{"location":"","page":"Home","title":"Home","text":"where hatc_sigmai^dagger(hatc_sigmai) is the fermion creation (annihilation) operator for a fermion with spin sigma on site i on the lattice, and hatmathcalT is the time-ordering operator. The equal-time Green's function is related to the fermion determinant matrix by","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigmaij(tautau)=M_sigmaij^-1(tau)","category":"page"},{"location":"","page":"Home","title":"Home","text":"where again tau=lcdotDeltatau. The equal-time Green's function matrix can be advanced to the next imaginary time slice using the relationship","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigma(tau+Deltatautau+Deltatau)=B_sigmal+1G_sigma(tautau)B_sigmal+1^-1","category":"page"},{"location":"","page":"Home","title":"Home","text":"and","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigma(tau-Deltatautau-Deltatau)=B_sigmal^-1G_sigma(tautau)B_sigmal","category":"page"},{"location":"","page":"Home","title":"Home","text":"The unequal-time Green's function is accessible using the relations","category":"page"},{"location":"","page":"Home","title":"Home","text":"beginalign*\nG_sigma(tau0) = B_sigma(tau0)G_sigma(00)\n = B_sigma^-1(tau0) + B_sigma(betatau)^-1\nendalign*","category":"page"},{"location":"","page":"Home","title":"Home","text":"and","category":"page"},{"location":"","page":"Home","title":"Home","text":"beginalign*\nG_sigma(0tau) = -I-G_sigma(00) B_sigma^-1(tau0) \n = -B_sigma^-1(betatau) + B_sigma(tau0)^-1\nendalign*","category":"page"},{"location":"","page":"Home","title":"Home","text":"where the second relationship may be shown by applying the Woodbury matrix identity. These relationships also imply","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigma(tau0) = B_sigma^-1(tautau)G_sigma(tau0)","category":"page"},{"location":"","page":"Home","title":"Home","text":"and","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigma(0tau) = G_sigma(0tau) B_sigma(tautau)","category":"page"},{"location":"","page":"Home","title":"Home","text":"for tauin0beta-Deltatau and tautaubeta. By applying the anti-periodic boundary conditions of the single-particle Green's function in imaginary time it immediately follows that","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigma(beta0) = I-G_sigma(00)","category":"page"},{"location":"","page":"Home","title":"Home","text":"and","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigma(0beta) = -G_sigma(00)","category":"page"},{"location":"","page":"Home","title":"Home","text":"where","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigma(00)=I+B_sigma(beta0)^-1=I+B_sigmaL_taudots B_sigma1^-1","category":"page"},{"location":"","page":"Home","title":"Home","text":"subject to the boundary condition G_sigma(00)=G_sigma(betabeta).","category":"page"},{"location":"","page":"Home","title":"Home","text":"The DQMC method also requires periodic re-calculation of the fermion Green's function matrix as G_sigma(tautau) is propagated to later or ealier imaginary times to maintain numerical stability. Therefore, we introduce a parameter n_s which describes the frequency with which numerical stabilization needs to occur. The number of \"stabilization intervals\" in imaginary time is then given by N_s=leftlceil L_taun_sright rceil, and we introduce the notation","category":"page"},{"location":"","page":"Home","title":"Home","text":"barB_sigman=prod_l=(n-1)cdot n_s+1^min(ncdot n_sN_s)B_sigmal","category":"page"},{"location":"","page":"Home","title":"Home","text":"where nin1N_s, to represent the product of propagator matrices over a single stabilization interval. Using this definition we may express G_sigma(00) as","category":"page"},{"location":"","page":"Home","title":"Home","text":"G_sigma(00) = (I + B_sigmaL_tau B_sigmaL_tau-1 dots B_sigma 2 B_sigma1)^-1\n = (I + barB_sigmaN_s barB_sigmaN_s-1 dots barB_sigma 2 barB_sigma1)^-1","category":"page"},{"location":"#Basic-Usage","page":"Home","title":"Basic Usage","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"In this section we introduce some of the basics of using this package by setting up the framework for a DQMC simulations in the case of a simple non-interacting square lattice tight binding model, assuming two electron spin species, spin up and spin down. While this is a \"tivial\" example, it is instructive.","category":"page"},{"location":"","page":"Home","title":"Home","text":"using LinearAlgebra\nusing LatticeUtilities\nusing JDQMCFramework","category":"page"},{"location":"","page":"Home","title":"Home","text":"First let us define the relevant model parameters.","category":"page"},{"location":"","page":"Home","title":"Home","text":"# hopping amplitude\nt = 1.0\n\n# chemical potential\nμ = 0.0\n\n# lattice size\nL = 4\n\n# inverse temperature\nβ = 3.7\n\n# discretization in imaginary time\nΔτ = 0.1\n\n# frequency of numerical stabilization\nn_stab = 10\nnothing; # hide","category":"page"},{"location":"","page":"Home","title":"Home","text":"Next we calculate the length of the imaginary time axis L_tau using the eval_length_imaginary_axis method.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Lτ = eval_length_imaginary_axis(β, Δτ)","category":"page"},{"location":"","page":"Home","title":"Home","text":"Using functionality imported from the LatticeUtilities.jl package, we construct the neighbor table for a square lattice.","category":"page"},{"location":"","page":"Home","title":"Home","text":"# define unit cell\nunit_cell = UnitCell(lattice_vecs = [[1.,0.],[0.,1.]], basis_vecs = [[0.,0.]])\n\n# define size of lattice\nlattice = Lattice(L = [L,L], periodic = [true,true])\n\n# define bonds/hoppings in x and y directions\nbond_x = Bond(orbitals = (1,1), displacement = [1,0])\nbond_y = Bond(orbitals = (1,1), displacement = [0,1])\n\n# construct neighbor table\nneighbor_table = build_neighbor_table([bond_x, bond_y], unit_cell, lattice)\n\n# calculate number of sites in lattice\nN = nsites(unit_cell, lattice)\n\n# calculate number of bonds in lattice\nNbonds = size(neighbor_table, 2)\n\n(N, Nbonds)","category":"page"},{"location":"","page":"Home","title":"Home","text":"Next we construct the strictly off-diagonal hopping matrix K and a vector to represent the diagonal on-site energy matrix V","category":"page"},{"location":"","page":"Home","title":"Home","text":"# build hopping matrix\nK = zeros(typeof(t), N, N)\nbuild_hopping_matrix!(K, neighbor_table, fill(t, Nbonds))\n\n# build vector representing diagonal on-site energy matrix\nV = fill(-μ, N)","category":"page"},{"location":"","page":"Home","title":"Home","text":"Now we define a the propagator B_sigmal for each spin species sigma and imaginary time slice tau = Deltatau cdot l Of course, in the non-interacting limit considered here all the propagators matrices are identical. This will no longer be the case if interactions are introduced, in which case each B_sigmal matrix will in general be unique.","category":"page"},{"location":"","page":"Home","title":"Home","text":"expmΔτV = exp.(-Δτ*V)\nexpmΔτK = exp(-Δτ*K)\nexppΔτK = exp(+Δτ*K)\n\n# null vector spin up propagators to fill\nBup = AsymExactPropagator{eltype(expmΔτK),eltype(expmΔτV)}[]\n\n# null vecotr of spin down propagators to fill\nBdn = AsymExactPropagator{eltype(expmΔτK),eltype(expmΔτV)}[]\n\n# construct propagator for each spin species and append to appropriate vector\nfor l in 1:Lτ\n B_l = AsymExactPropagator(expmΔτV, expmΔτK, exppΔτK)\n push!(Bup, B_l)\n push!(Bdn, B_l)\nend","category":"page"},{"location":"","page":"Home","title":"Home","text":"In the above we chose to represent the propagator matrices using the AsymExactPropagator type, which assumes the B_l = e^-Deltatau K_l e^-Deltatau V_l definition, where the K_l hopping matrix is exactly exponentiated. This package includes the other possible definitions AsymChkbrdPropagator, SymExactPropagator and SymChkbrdPropagator.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Next we instantiate two instances of the FermionGreensCalculator type, one for each of the two electron spin species, spin up and spin down.","category":"page"},{"location":"","page":"Home","title":"Home","text":"fgc_up = FermionGreensCalculator(Bup, β, Δτ, n_stab)\nfgc_dn = FermionGreensCalculator(Bdn, β, Δτ, n_stab)","category":"page"},{"location":"","page":"Home","title":"Home","text":"Now we initialize the spin up and spin down equal time Green's function matrices G_uparrow(00) and G_downarrow(00)","category":"page"},{"location":"","page":"Home","title":"Home","text":"Gup = zeros(N,N)\nlogdetGup, sgndetGup = calculate_equaltime_greens!(Gup, fgc_up)\n\nGdn = zeros(N,N)\nlogdetGdn, sgndetGdn = calculate_equaltime_greens!(Gdn, fgc_dn)","category":"page"},{"location":"","page":"Home","title":"Home","text":"Now we will demonstrate how to synchronously iterate over the imaginary time slices for both the spin up and spin down sectors.","category":"page"},{"location":"","page":"Home","title":"Home","text":"# Iterate over imaginary time τ=Δτ⋅l.\nfor l in fgc_up\n\n # Propagate equal-time Green's function matrix to current imaginary time G(τ±Δτ,τ±Δτ) ==> G(τ,τ)\n # depending on whether iterating over imaginary time in the forward or reverse direction\n propagate_equaltime_greens!(Gup, fgc_up, Bup)\n propagate_equaltime_greens!(Gdn, fgc_dn, Bdn)\n\n # LOCAL UPDATES OR EVALUATION OF DERIVATIVE OF FERMIONIC ACTION FOR THE CURRENT\n # IMAGINARY TIME SLICE WOULD GO HERE\n\n # Periodically re-calculate the Green's function matrix for numerical stability.\n # Comment: if not performing updates, but just evaluating the derivative of the action, then\n # set update_B̄=false to avoid wasting cpu time re-computing B_barₙ matrices.\n logdetGup, sgndetGup, δGup, δθup = stabilize_equaltime_greens!(Gup, logdetGup, sgndetGup, fgc_up, Bup, update_B̄=true)\n logdetGdn, sgndetGdn, δGdn, δθdn = stabilize_equaltime_greens!(Gdn, logdetGdn, sgndetGdn, fgc_dn, Bdn, update_B̄=true)\n\n # Keep up and down spin Green's functions synchronized as iterating over imaginary time.\n iterate(fgc_dn, fgc_up.forward)\nend","category":"page"},{"location":"","page":"Home","title":"Home","text":"Note that if we iterate over imaginary time again, it will iterate in the opposite direction. This is expected behavior. Each time you iterate over imaginary time the direction of iteration reverses. While not immediately obvious, this allows for a reduction in the number of required matrix factorizations.","category":"page"},{"location":"","page":"Home","title":"Home","text":"This package also exports two routines, local_update_det_ratio and local_update_greens!, that are useful for implementing local updates in a DQMC simulation.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Lastly, we will will calculate the unequal-time Green's functions G_sigma(tau0) and G_sigma(0tau), and the equal-time Green's function G_sigma(tautau) for all imaginary time slices. This functionality is important ","category":"page"},{"location":"","page":"Home","title":"Home","text":"# initialize unequal-time Green's functions\nGup_τ0 = similar(Gdn) # G₊(τ,0)\nGup_0τ = similar(Gdn) # G₊(0,τ)\nGup_ττ = similar(Gdn) # G₊(τ,τ)\nGdn_τ0 = similar(Gdn) # G₋(τ,0)\nGdn_0τ = similar(Gdn) # G₋(0,τ)\nGdn_ττ = similar(Gdn) # G₋(τ,τ)\ninitialize_unequaltime_greens!(Gup_τ0, Gup_0τ, Gup_ττ, Gup)\ninitialize_unequaltime_greens!(Gdn_τ0, Gdn_0τ, Gdn_ττ, Gdn)\n\n# EQUAL-TIME CORRELATION MEASUREMENTS WOULD GO HERE\n\n# Iterate over imaginary time τ=Δτ⋅l.\nfor l in fgc_up\n\n # Propagate Green's function matrices to current imaginary time slice\n propagate_unequaltime_greens!(Gup_τ0, Gup_0τ, Gup_ττ, fgc_up, Bup)\n propagate_unequaltime_greens!(Gdn_τ0, Gdn_0τ, Gdn_ττ, fgc_dn, Bdn)\n\n # UNEQUAL-TIME CORRELATION FUNCTION MEASUREMENTS WOULD GO HERE\n\n # Periodically re-calculate the Green's function matrix for numerical stability.\n logdetGup, sgndetGup, δGup, δθup = stabilize_unequaltime_greens!(Gup_τ0, Gup_0τ, Gup_ττ, logdetGup, sgndetGup, fgc_up, Bup, update_B̄=false)\n logdetGdn, sgndetGdn, δGdn, δθdn = stabilize_unequaltime_greens!(Gdn_τ0, Gdn_0τ, Gdn_ττ, logdetGdn, sgndetGdn, fgc_dn, Bdn, update_B̄=false)\n\n # Keep up and down spin Green's functions synchronized as iterating over imaginary time.\n iterate(fgc_dn, fgc_up.forward)\nend","category":"page"}] }