Code Monkey home page Code Monkey logo

edkit.jl's Introduction

EDKit.jl

Julia package for general many-body exact diagonalization calculation. The package provides a general Hamiltonian constructing routine for specific symmetry sectors. The functionalities can be extended with user-defined bases.

Installation

Run the following script in the Julia Pkg REPL environment:

pkg> add EDKit

Alternatively, you can install EDKit directly from GitHub using the following script.

pkg> add https://github.com/jayren3996/EDKit.jl

This is useful if you want to access the latest version of EDKit, which includes new features not yet registered in the Julia Pkg system but may also contain bugs.

Examples

Instead of providing documentation, I have chosen to introduce the functionality of this package through practical calculation examples. You can find a collection of Jupyter notebooks in the examples folder, each showcasing various computations.

Here are a few basic examples:

XXZ Model with Random Field

Consider the Hamiltonian

$$H = \sum_i\left(\sigma_i^x \sigma^x_{i+1} + \sigma^y_i\sigma^y_{i+1} + h_i \sigma^z_i\sigma^z_{i+1}\right).$$

We choose the system size to be L=10. The Hamiltonian needs 3 pieces of information:

  1. Local operators represented by matrices;
  2. Site indices where each local operator acts on;
  3. Basis, if using the default tensor-product basis, only need to provide the system size.

The following script generates the information we need to generate XXZ Hamiltonian:

L = 10
mats = [
    fill(spin("XX"), L);
    fill(spin("YY"), L);
    [randn() * spin("ZZ") for i=1:L]
]
inds = [
    [[i, mod(i, L)+1] for i=1:L];
    [[i, mod(i, L)+1] for i=1:L];
    [[i, mod(i, L)+1] for i=1:L]
]
H = operator(mats, inds, L)

Then we can use the constructor operator to create Hamiltonian:

julia> H = operator(mats, inds, L)
Operator of size (1024, 1024) with 10 terms.

The constructor returns an Operator object, a linear operator that can act on vector/ matrix. For example, we can act H on a random state:

ψ = normalize(rand(2^L))
ψ2 = H * ψ

If we need a matrix representation of the Hamitonian, we can convert H to julia array by:

julia> Array(H)
1024×1024 Matrix{Float64}:
 -1.55617  0.0       0.0       0.0        0.0      0.0       0.0
  0.0      4.18381   2.0       0.0         0.0      0.0       0.0
  0.0      2.0      -1.42438   0.0         0.0      0.0       0.0
  0.0      0.0       0.0      -1.5901      0.0      0.0       0.0
  0.0      0.0       2.0       0.0         0.0      0.0       0.0
  0.0      0.0       0.0       2.0        0.0      0.0       0.0
                                                           
  0.0      0.0       0.0       0.0         0.0      0.0       0.0
  0.0      0.0       0.0       0.0         2.0      0.0       0.0
  0.0      0.0       0.0       0.0        0.0      0.0       0.0
  0.0      0.0       0.0       0.0        -1.42438  2.0       0.0
  0.0      0.0       0.0       0.0         2.0      4.18381   0.0
  0.0      0.0       0.0       0.0         0.0      0.0      -1.55617

Or use the function sparse to create the sparse matrix (requires the module SparseArrays being imported):

julia> sparse(H)
1024×1024 SparseMatrixCSC{Float64, Int64} with 6144 stored entries:
⠻⣦⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠳⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢹⡻⣮⡳⠄⢠⡀⠀⠀⠀⠀⠀⠀⠈⠳⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠙⠎⢿⣷⡀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠈⠳⣄⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠲⣄⠈⠻⣦⣄⠙⠀⠀⠀⢦⡀⠀⠀⠀⠈⠳⣄⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠈⠳⣄⠙⡻⣮⡳⡄⠀⠀⠙⢦⡀⠀⠀⠀⠈⠳⣄⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠙⠮⢻⣶⡄⠀⠀⠀⠙⢦⡀⠀⠀⠀⠈⠳⣄⠀
⢤⡀⠀⠀⠀⠀⠠⣄⠀⠀⠀⠉⠛⣤⣀⠀⠀⠀⠙⠂⠀⠀⠀⠀⠈⠓
⠀⠙⢦⡀⠀⠀⠀⠈⠳⣄⠀⠀⠀⠘⠿⣧⡲⣄⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠙⢦⡀⠀⠀⠀⠈⠳⣄⠀⠀⠘⢮⡻⣮⣄⠙⢦⡀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠈⠳⠀⠀⠀⣄⠙⠻⣦⡀⠙⠦⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠈⠳⣄⠈⢿⣷⡰⣄⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀⠀⠀⠈⠃⠐⢮⡻⣮⣇⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠙⠻⣦

Solving AKLT Model Using Symmetries

Consider the AKLT model

$$H = \sum_i\left[\vec S_i \cdot \vec S_{i+1} + \frac{1}{3}\left(\vec S_i \cdot \vec S_{i+1}\right)^2\right],$$

with the system size chosen to be L=8. The Hamiltonian operator for this translational-invariant Hamiltonian can be constructed using the trans_inv_operator function:

L = 8
SS = spin((1, "xx"), (1, "yy"), (1, "zz"), D=3)
mat = SS + 1/3 * SS^2
H = trans_inv_operator(mat, 1:2, L)

The second input specifies the indices the operators act on.

Because of the translational symmetry, we can simplify the problem by considering the symmetry. We construct a translational-symmetric basis by:

B = TranslationalBasis(L=8, k=0, base=3)

Here, L is the length of the system, and k labels the momentum k = 0,...,L-1 (integer multiplies of 2π/L). The function TranslationalBasis returns a basis object containing 834 states. We can obtain the Hamiltonian in this sector by:

julia> H = trans_inv_operator(mat, 1:2, B)
Operator of size (834, 834) with 8 terms.

In addition, we can take into account the total S^z conservation, by constructing the basis

B = TranslationalBasis(L=8, N=8, k=0, base=3)

where the N is the filling number with respect to the all-spin-down state. N=L means we select those states whose total Sz equals 0 (note that we use 0,1,2 to label the Sz=1,0,-1 states). This gives a further reduced Hamiltonian matrix:

julia> H = trans_inv_operator(mat, 1:2, B)
Operator of size (142, 142) with 8 terms.

We can go one step further by considering the spatial reflection symmetry.

B = TranslationParityBasis(L=8, N=0, k=0, p=1, base=3)

where the p argument is the parity p = ±1.

julia> H = trans_inv_operator(mat, 1:2, B)
Operator of size (84, 84) with 8 terms.

PXP Model and Entanglement Entropy

Consider the PXP model

$$H = \sum_i \left(P^0_{i-1} \sigma^x_i P^0_{i+1}\right).$$

Note that the model is defined on the Hilbert space where there is no local |↑↑⟩ configuration. We can use the following function to check whether a product state is in the constraint subspace:

function pxpf(v::Vector{<:Integer})
    for i in eachindex(v)
        iszero(v[i]) && iszero(v[mod(i, length(v))+1]) && return false
    end
    return true
end

For system size L=20 and in sector k=0,p=+1, the Hamiltonian is constructed by:

mat = begin
    P = [0 0; 0 1]
    kron(P, spin("X"), P)
end
basis = TranslationParityBasis(L=20, f=pxpf, k=0, p=1)
H = trans_inv_operator(mat, 3, basis)

where f argument is the selection function for the basis state that can be user-defined. We can then diagonalize the Hamiltonian. The bipartite entanglement entropy for each eigenstate can be computed by

vals, vecs = Array(H) |> Hermitian |> eigen
EE = [ent_S(vecs[:,i], 1:L÷2, basis) for i=1:size(basis,1)]

edkit.jl's People

Contributors

jayren3996 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

phyjswang

edkit.jl's Issues

Entanglement entropy of the diamond chain

Dear Jie,

I would like to investigate the bipartite entanglement entropy of the spin-1 diamond chain in the absence of the magnetic field when conserved total sz and k=0 are assumed.
I have encountered some issues and I would be grateful to you if help me to solve them.
I extended the code as:

# Hamiltonian parameters:
J1 = 1.0
J2 = J1
J3 = 2.8
J4 = J1
J5 = J1
L = 2
N = 3*L
sz_min = 0
sz_max = 2*N
# -------------------------------------------------------
all_energies = []
EntEntropy_arr = []
Size_EigVals = []
Size_EntEnt = []
mun_EigVals = 0
for i in sz_min:sz_max
    Size_EigVals_k = 0
    Size_EntEnt_k = 0
        # onsite Hamiltonian matrix
        O1 = spin((J1, "xx1"), (J1, "yy1"), (J1, "zz1"), D=3)
        O2 = spin((J2, "x1x"), (J2, "y1y"), (J2, "z1z"), D=3)
        O3 = spin((J3, "1xx"), (J3, "1yy"), (J3, "1zz"), D=3)
        h1 = O1 + O2 + O3
        C1 = spin((J4, "1x1x11"), (J4, "1y1y11"), (J4, "1z1z11"), D=3)
        C2 = spin((J5, "11xx11"), (J5, "11yy11"), (J5, "11zz11"), D=3)
        h2 = C1 + C2
        Nj = diag( spin((1,"z11"), (1,"1z1"), (1,"11z"), D=3) + 3*I )
        total_z(s) = sum(Nj[sj+1] for sj in s)
        basis = TranslationalBasis(L=L, f = s -> total_z(s) == i, k=0, base=3^3)
        H = trans_inv_operator(h1, 1:1, basis) + trans_inv_operator(h2, 1:2, basis)
        vals, vecs = Array(H) |> Hermitian |> eigen
        EE = [ent_S(vecs[:,i], 1:2, basis) for i=1:size(basis,1)]
        Size_EigVals_k += size(vals, 1)
        Size_EntEnt_k += size(EE, 1)
        for sublist in vals
            for element in sublist
                push!(all_energies, element)
            end
        end
        for sublist in EE
            for element in sublist
                push!(EntEntropy_arr, element)
            end
        end
    push!(Size_EigVals, Size_EigVals_k)
    push!(Size_EntEnt, Size_EntEnt_k)
end
  1. After running the code, for all values of the total sz I get correct eigenenergies, but all entropy values are zero.
  2. I can not compute bipartite EE for 1:3 or 1:4 and so on. The code gives only bipartite EE for the case 1:2.

As I understood, the above code gives EE between two neighboring blocks 1 and 2 not two spins, right? If so, how can I compute EE of arbitrary pairs of spins?

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

If you'd like for me to do this for you, comment TagBot fix on this issue.
I'll open a PR within a few hours, please be patient!

Lanczos algorithm + EDKit

Dear Jie,

Thank you for your excellent package.

I have successfully solved the problem with a spin-1 diamond chain up to 12 spins.
Now, I aim to increase the number of spins to 18 while conserving SzT by applying TranslationalBasis.
I have 64 GB of RAM, and the code gets terminated when the total Sz exceeds sector 6.
To address this issue, I need to utilize the Lanczos algorithm. Here is the code I have managed:

using EDKit, LinearAlgebra
using DelimitedFiles
using KrylovKit
# Hamiltonian parameters:
J1 = 1.0
J2 = J1
J3 = 2.8
J4 = J1
J5 = J1
L = 6
N = 3*L
k=0
sz_min = 0
sz_max = N
B_min = 0
B_max = 0
uB = 0.01
# -------------------------------------------------------
all_energies = []
Size_EigVals = []
for i in sz_min:sz_max
        # onsite Hamiltonian matrix
        O1 = spin((J1, "xx1"), (J1, "yy1"), (J1, "zz1"), D=3)
        O2 = spin((J2, "x1x"), (J2, "y1y"), (J2, "z1z"), D=3)
        O3 = spin((J3, "1xx"), (J3, "1yy"), (J3, "1zz"), D=3)
        # hz = spin((ha, "z11"), (hb, "1z1"), (hc, "11z"), D=3)
        h1 = O1 + O2 + O3
        C1 = spin((J4, "1x1x11"), (J4, "1y1y11"), (J4, "1z1z11"), D=3)
        C2 = spin((J5, "11xx11"), (J5, "11yy11"), (J5, "11zz11"), D=3)
        h2 = C1 + C2
        Nj = diag( spin((1,"z11"), (1,"1z1"), (1,"11z"), D=3) + 3*I )
        total_z(s) = sum(Nj[sj+1] for sj in s)
        basis = TranslationalBasis(L=L, f = s -> total_z(s) == i, k=k, base=3^3)
        H = trans_inv_operator(h1, 1:1, basis) + trans_inv_operator(h2, 1:2, basis)
        if i <= 6
           energy = eigvals(Hermitian(H))
        else
           energy = eigsolve(H, ones(size(H, 1)), howmany=20, which=:SM, T=Float64)
        end
        println("size Eigenvalues = ", size(energy, 1))
        push!(Size_EigVals, size(energy, 1))
        for sublist in energy
            for element in sublist
                push!(all_energies, element)
            end
        end
    println("*************************************************************")
    println("-------------- Finished job: SzT = ", i, "--------------------")
    println("*************************************************************")
end

open("Energies_DiamondS1_cSzT_k0_EDKit_EnDig_J$(J3)_N$(N).txt", "w") do io
    for energies in all_energies
        for En in energies
            writedlm(io, En, '\n')
        end
    end
end

open("Size_EigVals_J$(J3)_N$(N).txt", "w") do io
           writedlm(io, [Size_EigVals], '\t')
end

But I get following error:

LoadError: Tuple field type cannot be Union{}
Stacktrace:
 [1] eigsolve(f::EDKit.Operator{Float64, TranslationalBasis{Int64, Float64}}, x₀::Vector{Float64}, howmany::Int64, which::Symbol; kwargs::@Kwargs{howmany::Int64, which::Symbol, T::DataType})
   @ KrylovKit ~/.julia/packages/KrylovKit/diNbc/src/eigsolve/eigsolve.jl:183
 [2] top-level scope
   @ ~/DiamondS1/EDKit_DiamondS1_FTLM.jl:38
in expression starting at /home/DiamondS1/EDKit_DiamondS1_FTLM.jl:21

It seems that eigsolve is unable to recognize the Hamiltonian matrix, whether it's the full Hamiltonian or the reduced Hamiltonian after applying TranslationalBasis.

I would appreciate your comments and suggestions on this issue.

Fermionic systems

Hi Jei,
This looks like an interesting package and I was wondering how i can go about constructing a user basis for a system of three fermions with a hubbard like interaction between them? I was thinking of starting with local hilbert space dimension of 8 and defining my operators as 8x8 matrices, but I can't seem to figure out how to define the basis.
Any help is appreciated! TIA

Eigenvalues of spin S-1 chain

Dear EDKit developer(s),

I am writing to seek assistance regarding the computation of eigenvalues for a spin-1 diamond-like chain featuring two distinct exchange couplings in the presence of an external magnetic field along the z-axis, as depicted in the figure below.

Diamond_Cahin

I tried following code:

using EDKit
using LinearAlgebra

L = 12
for Bz=0:0.1:8
       mat = spin((1, "xx"), (1, "yy"), (1, "zz"), (1, "z"), D=3)
       mats = fill(mat, L)
       inds = [
                     [[i, mod(i+1, L)] for i=1:3:L];    # J_1 exchange coupling
                     [[i, mod(i+1, L)] for i=1:3:L];    # J_1 exchange coupling
                     [[i, mod(i+1, L)] for i=1:3:L];    # J_1 exchange coupling
                     [[i, mod(i+2, L)] for i=1:3:L];    # J_1 exchange coupling
                     [[i, mod(i+2, L)] for i=1:3:L];    # J_1 exchange coupling
                     [[i, mod(i+2, L)] for i=1:3:L];    # J_1 exchange coupling
                     [[i, mod(i+1, L)] for i=2:3:L];    # J_2 exchange coupling
                     [[i, mod(i+1, L)] for i=2:3:L];    # J_2 exchange coupling
                     [[i, mod(i+1, L)] for i=2:3:L];    # J_2 exchange coupling
                     [[i, mod(i+2, L)] for i=2:3:L];    # J_1 exchange coupling
                     [[i, mod(i+2, L)] for i=2:3:L];    # J_1 exchange coupling
                     [[i, mod(i+2, L)] for i=2:3:L];    # J_1 exchange coupling
                     [[i, mod(i+1, L)] for i=3:3:L];    # J_1 exchange coupling
                     [[i, mod(i+1, L)] for i=3:3:L];    # J_1 exchange coupling
                     [[i, mod(i+1, L)] for i=3:3:L];    # J_1 exchange coupling
                     [i for i=1:L]                        # Bz magnetic field
                   ]
       B = TranslationalBasis(L=L, N=L, base=3)
       H = operator(mats, inds, B)
      vals, vecs = Array(H) |> Hermitian |> eigen
      println(vals)

end

In my calculations, I have considered the conservation of SzT (N=L). However, I have encountered several challenges in proceeding with the calculations. Despite consulting the examples provided in your documentation, I have been unable to resolve these issues. I would greatly appreciate it if you could address the following concerns:

  1. How can I incorporate an onsite magnetic field along the z-direction? I attempted methods such as (1, "z") and [spin("Z") for i=1:L], but encountered errors.
  2. What approach should I take to introduce distinct exchange interactions J_1 and J_2 into the model?
  3. I am interested in obtaining the eigenenergies of the Hamiltonian for this model at various values of the magnetic field within the interval 0<=B_z<=8 (specifically, for B_z=0:0.1:8). Could you please provide guidance on modifying the code to achieve this?

Your assistance in resolving these issues would be greatly appreciated.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.