Giter Club home page Giter Club logo

joselado / dmrgpy Goto Github PK

View Code? Open in Web Editor NEW
78.0 9.0 19.0 42.68 MB

DMRGPy is a Python library to compute quasi-one-dimensional spin chains and fermionic systems using matrix product states with DMRG as implemented in ITensor. Most of the computations can be performed both with DMRG and exact diagonalization for small systems, which allows one to benchmark the results.

License: GNU General Public License v3.0

Shell 0.02% Python 16.63% Makefile 1.03% C 7.55% C++ 74.19% Fortran 0.02% Julia 0.57%
spinchains matrix-product-states itensor dmrg-algorithm fermionchains parafermions kernel-polynomial-method many-body-excitations

dmrgpy's Introduction

DMRGPY

Summary

This is a Python library to compute quasi-one-dimensional spin chains and fermionic systems using matrix product states with the density matrix renormalization group as implemented in ITensor (C++ and Julia versions). Most of the computations can be performed both with DMRG and exact diagonalization for small systems, which allows to benchmark the results.

Several examples can be found in the examples folder.

Disclaimer

This library is still under heavy development.

How to install

Linux and Mac

Execute the script

python install.py 

and it will compile both ITensor and a C++ program that uses it.

If your default C++ compiler is not g++ (version 6 or higher), execute the installation script providing the specific compiler to use (g++-6 for example)

python install.py gpp=g++-6 

Alternatively, in case you just want to use the Julia version, execute the script

python install_julia.py

The installation scripts will also add dmrgpy to the PYTHONPATH of the python interpreter you used to execute them. Compiling the C++ program requires having installed LAPACK and BLAS in your system.

Afterwards you can import the dmrgpy sublibrary that you want, for example

from dmrgpy import spinchain

Windows

For using this program in Windows, the easiest solution is to create a virtual machine using Virtual Box, installing a version of Ubuntu in that virtual machine, and following the previous instructions.

Capabilities

  • Possible models include spinless fermions, spinful fermions, spins, parafermions and bosons
  • Ground state energy
  • Ground state wavefunction
  • Excitation energies
  • Excited wavefunctions
  • Arbitrary expectation values, including static correlation functions
  • Time evolution of arbitrary states
  • MPS algebra: sum of MPS, application of operators, exponential and inverse
  • MPO algebra: sums, products, trace, trace of inverse for generic operators
  • Dynamical correlation functions computed with the Kernel polynomial method
  • Dynamical correlation functions with time dependent DMRG
  • Generic operator distributions computed with the Kernel polynomial method
  • Iterative MPS Hermitian and non-Hermitian diagonalization solvers
  • Hermitian and non-Hermitian degeneracy detection

Examples

Ground state energy of an S=1/2 spin chain

from dmrgpy import spinchain
spins = ["S=1/2" for i in range(30)] # spins in each site
sc = spinchain.Spin_Chain(spins) # create spin chain object
h = 0 # initialize Hamiltonian
for i in range(len(spins)-1): 
  h = h + sc.Sx[i]*sc.Sx[i+1]
  h = h + sc.Sy[i]*sc.Sy[i+1]
  h = h + sc.Sz[i]*sc.Sz[i+1]
sc.set_hamiltonian(h) # create the Hamiltonian
print("Ground state energy",sc.gs_energy())

Static correlator of an S=1/2 spin chain

from dmrgpy import spinchain
n = 30
spins = ["S=1/2" for i in range(n)] # S=1 in each site
sc = spinchain.Spin_Chain(spins) # create spin chain object
h = 0 # initialize Hamiltonian
for i in range(len(spins)-1):
  h = h + sc.Sx[i]*sc.Sx[i+1]
  h = h + sc.Sy[i]*sc.Sy[i+1]
  h = h + sc.Sz[i]*sc.Sz[i+1]
sc.set_hamiltonian(h) # create the Hamiltonian
cs = [sc.vev(sc.Sz[0]*sc.Sz[i]).real for i in range(n)]

Alt text

Static correlator of an S=1 spin chain

from dmrgpy import spinchain
n = 30
spins = ["S=1" for i in range(n)] # S=1 in each site
sc = spinchain.Spin_Chain(spins) # create spin chain object
h = 0 # initialize Hamiltonian
for i in range(len(spins)-1): 
  h = h + sc.Sx[i]*sc.Sx[i+1]
  h = h + sc.Sy[i]*sc.Sy[i+1]
  h = h + sc.Sz[i]*sc.Sz[i+1]
sc.set_hamiltonian(h) # create the Hamiltonian
cs = [sc.vev(sc.Sz[0]*sc.Sz[i]).real for i in range(n)]

Alt text

Conformal field theory central charge of a critical Ising model

from dmrgpy import spinchain
n = 100 # number of sites
spins = ["S=1/2" for i in range(n)] # spin 1/2 heisenberg chain
sc = spinchain.Spin_Chain(spins) # create the spin chain
h = 0 # initialize
for i in range(n-1): h = h + sc.Sz[i]*sc.Sz[i+1] # Ising coupling
for i in range(n): h = h + 0.5*sc.Sx[i] # transverse field
sc.set_hamiltonian(h) # set the Hamiltonian
sc.maxm = 200 # increase bond dimension for a critical system
wf = sc.get_gs() # compute ground state
print("Central charge",wf.get_CFT_central_charge()) # compute central charge

Ground state energy of a bilinear-biquadratic Hamiltonian

from dmrgpy import spinchain
ns = 6 # number of sites in the spin chain
spins = ["S=1" for i in range(ns)] # S=1 chain
sc = spinchain.Spin_Chain(spins) # create spin chain object
h = 0 # initialize Hamiltonian
Si = [sc.Sx,sc.Sy,sc.Sz] # store the three components
for i in range(ns-1): # loop 
    for S in Si: h = h + S[i]*S[i+1]  # bilinear
    for S in Si: h = h + 1./3.*S[i]*S[i+1]*S[i]*S[i+1]  # biquadratic
sc.set_hamiltonian(h) # create the Hamiltonian
print("Energy with DMRG",sc.gs_energy(mode="DMRG"))
print("Energy with ED",sc.gs_energy(mode="ED"))

Magnetization of an S=1 spin chain with an edge magnetic field

from dmrgpy import spinchain
n = 40
spins = ["S=1" for i in range(n)] # S=1 chain
sc = spinchain.Spin_Chain(spins) # create spin chain object
h = 0 # initialize Hamiltonian
for i in range(len(spins)-1): 
  h = h + sc.Sx[i]*sc.Sx[i+1]
  h = h + sc.Sy[i]*sc.Sy[i+1]
  h = h + sc.Sz[i]*sc.Sz[i+1]
h = h + sc.Sz[0]*0.1 # edge magnetic field
sc.set_hamiltonian(h) # create the Hamiltonian
mz = [sc.vev(sc.Sz[i]).real for i in range(n)]
print("Mz",mz)

Bond dimension energy convergence for an S=1/2 Heisenberg chain

from dmrgpy import spinchain
import numpy as np
n= 30 # size of the chain
spins = ["S=1/2" for i in range(n)] # S=1/2 chain
sc = spinchain.Spin_Chain(spins) # create spin chain object
h = 0 # initialize Hamiltonian
for i in range(len(spins)-1):
  h = h + sc.Sx[i]*sc.Sx[i+1]
  h = h + sc.Sy[i]*sc.Sy[i+1]
  h = h + sc.Sz[i]*sc.Sz[i+1]
bds = range(3,20,2) # bond dimension
es,des = [],[] # storage of energies and fluctuations
for maxm in bds: # loop over bond dimension
  sc.set_hamiltonian(h) # create the Hamiltonian
  sc.maxm = maxm # set the bond dimension
  e = sc.gs_energy() # get the ground state energy
  wf = sc.get_gs() ; de = wf.dot(h*(h*wf)) # Energy square
  de = np.sqrt(np.abs(de-e**2)) # energy fluctuation
  es.append(e/n) # store energy
  des.append(de/n) # energy fluctuation

Alt text

Excited states with DMRG and ED

from dmrgpy import spinchain
spins = ["S=1/2" for i in range(12)] # 2*S+1=2 for S=1/2
sc = spinchain.Spin_Chain(spins) # create spin chain object
h = 0 # initialize Hamiltonian
for i in range(len(spins)-1): 
  h = h + sc.Sx[i]*sc.Sx[i+1]
  h = h + sc.Sy[i]*sc.Sy[i+1]
  h = h + sc.Sz[i]*sc.Sz[i+1]
sc.set_hamiltonian(h)
es1 = sc.get_excited(n=6,mode="DMRG")
es2 = sc.get_excited(n=6,mode="ED")
print("Excited states with DMRG",es1)
print("Excited states with ED",es2)

Singlet-triplet gap of the Haldane Heisenberg S=1 spin chain

from dmrgpy import spinchain
# Haldane chain with S=1/2 on the edge to remove the topological modes
spins = ["S=1/2"]+["S=1" for i in range(40)]+["S=1/2"]
sc = spinchain.Spin_Chain(spins) # create spin chain object
h = 0 # initialize Hamiltonian
for i in range(len(spins)-1): 
  h = h + sc.Sx[i]*sc.Sx[i+1]
  h = h + sc.Sy[i]*sc.Sy[i+1]
  h = h + sc.Sz[i]*sc.Sz[i+1]
sc.set_hamiltonian(h)
es = sc.get_excited(n=2,mode="DMRG")
gap = es[1]-es[0] # compute gap
print("Gap of the Haldane chain",gap)

Local dynamical spin correlator of an S=1/2 chain

import numpy as np
from dmrgpy import spinchain
n = 40
# create an S=1/2 spin chain
spins = ["S=1/2" for i in range(n)] # spin 1/2 heisenberg chain
# create first neighbor exchange
sc = spinchain.Spin_Chain(spins) # create the spin chain
h = 0
for i in range(n-1):
    h = h + sc.Sx[i]*sc.Sx[i+1]
    h = h + sc.Sy[i]*sc.Sy[i+1]
    h = h + sc.Sz[i]*sc.Sz[i+1]
sc.set_hamiltonian(h)
zs = [] # empty list
for i in range(n): # loop over sites
  name = (sc.Sz[i],sc.Sz[i])
  (e,s) = sc.get_dynamical_correlator(mode="DMRG",name=name,
          es=np.linspace(-0.5,4.0,200),delta=0.05)
  zs.append(s) # store

Alt text

Local dynamical spin correlator of an S=1 chain

import numpy as np
from dmrgpy import spinchain
n = 40
# create an S=1/2 spin chain
spins = ["S=1" for i in range(n)] # spin 1/2 heisenberg chain
# create first neighbor exchange
sc = spinchain.Spin_Chain(spins) # create the spin chain
h = 0
for i in range(n-1):
    h = h + sc.Sx[i]*sc.Sx[i+1]
    h = h + sc.Sy[i]*sc.Sy[i+1]
    h = h + sc.Sz[i]*sc.Sz[i+1]
sc.set_hamiltonian(h)
zs = [] # empty list
for i in range(n): # loop over sites
  name = (sc.Sz[i],sc.Sz[i])
  (e,s) = sc.get_dynamical_correlator(mode="DMRG",name=name,
          es=np.linspace(-0.5,4.0,200),delta=0.05)
  zs.append(s) # store

Alt text

Local dynamical spin correlator of an S=1/2 chain with a S=1 impurity

import numpy as np
from dmrgpy import spinchain
spins = ["S=1/2" for i in range(14)] # spin 1/2 heisenberg chain
spins = spins + ["S=1"] + spins # put S=1 in the middle
n = len(spins) # total number of spins
# create first neighbor exchange
sc = spinchain.Spin_Chain(spins) # create the spin chain
h = 0
for i in range(n-1):
    h = h + sc.Sx[i]*sc.Sx[i+1]
    h = h + sc.Sy[i]*sc.Sy[i+1]
    h = h + sc.Sz[i]*sc.Sz[i+1]
sc.set_hamiltonian(h)
zs = [] # empty list
for i in range(n): # loop over sites
  name = (sc.Sz[i],sc.Sz[i])
  (e,s) = sc.get_dynamical_correlator(mode="DMRG",name=name,
          es=np.linspace(-0.5,4.0,200),delta=0.05)
  zs.append(s.real) # store

Alt text

Non-local dynamical spin correlator of an S=1/2 chain

import numpy as np
from dmrgpy import spinchain
n = 10
# create an S=1/2 spin chain
spins = ["S=1/2" for i in range(n)] # spin 1/2 heisenberg chain
# create first neighbor exchange
sc = spinchain.Spin_Chain(spins) # create the spin chain
h = 0
for i in range(n-1):
    h = h + sc.Sx[i]*sc.Sx[i+1]
    h = h + sc.Sy[i]*sc.Sy[i+1]
    h = h + sc.Sz[i]*sc.Sz[i+1]
sc.set_hamiltonian(h)
xs = [] # empty list
ys = [] # empty list
zs = [] # empty list
for i in range(n): # loop over sites
  name = (sc.Sz[0],sc.Sz[i])
  (e,s) = sc.get_dynamical_correlator(mode="DMRG",name=name,
          es=np.linspace(-0.5,4.0,200),delta=0.05)
  zs.append(s) # store

Alt text

Bulk and edge dynamical correlator of a Haldane chain

from dmrgpy import spinchain
n = 20 ; spins = ["S=1" for i in range(n)] # S=1 chain
sc = spinchain.Spin_Chain(spins) # create spin chain object
h = 0 # initialize Hamiltonian
for i in range(len(spins)-1):
  h = h + sc.Sx[i]*sc.Sx[i+1]
  h = h + sc.Sy[i]*sc.Sy[i+1]
  h = h + sc.Sz[i]*sc.Sz[i+1]
sc.set_hamiltonian(h)
(e0,d0) = sc.get_dynamical_correlator(name=(sc.Sz[0],sc.Sz[0]))
(eb,db) = sc.get_dynamical_correlator(name=(sc.Sz[n//2],sc.Sz[n//2]))

Alt text

Spin and charge correlator of the 1D Hubbard model

from dmrgpy import fermionchain
n = 20 # number of sites
fc = fermionchain.Spinful_Fermionic_Chain(n)
# first neighbor hopping
h = 0
for i in range(n-1):
  h = h + fc.Cdagup[i]*fc.Cup[i+1]
  h = h + fc.Cdagdn[i]*fc.Cdn[i+1]
h = h + h.get_dagger() # Make Hermitian
# Hubbard term
for i in range(n):
  h = h + 4.*(fc.Nup[i]-.5)*(fc.Ndn[i]-.5)
fc.set_hamiltonian(h) # initialize the Hamiltonian
# compute the two correlators
zz = [fc.vev(fc.Sz[0]*fc.Sz[i]).real for i in range(n)]
cc = [fc.vev(fc.Cdagup[0]*fc.Cup[i]).real for i in range(n)]

Alt text

Spin correlator in the Hubbard model as function of the interaction

from dmrgpy import fermionchain
import numpy as np
n = 14 # number of sites
fc = fermionchain.Spinful_Fermionic_Chain(n)
# first neighbor hopping
h = 0
for i in range(n-1):
  h = h + fc.Cdagup[i]*fc.Cup[i+1]
  h = h + fc.Cdagdn[i]*fc.Cdn[i+1]
h = h + h.get_dagger() # Make Hermitian
# Hubbard term
hU = 0
for i in range(n):
  hU = hU + (fc.Nup[i]-.5)*(fc.Ndn[i]-.5)

zzs = [] # storage for correlators
Us = np.linspace(0.,4.,6) # Hubbard Us 
for U in Us:
  fc.set_hamiltonian(h+U*hU) # initialize the Hamiltonian
  zz = [fc.vev(fc.Sz[0]*fc.Sz[i]).real for i in range(n)]
  zzs.append(zz) # store zz correlator

Alt text

Generic interacting fermionic Hamiltonian

import numpy as np
from dmrgpy import fermionchain
n = 6 # number of different spinless fermionic orbitals
# fc is an object that contains the information of the many body system
fc = fermionchain.Fermionic_Chain(n) # create the object
h = 0
# create random hoppings
for i in range(n):
  for j in range(i):
    h = h + fc.Cdag[i]*fc.C[j]*np.random.random()
# create random density interactions
for i in range(n):
  for j in range(i):
    h = h + fc.N[i]*fc.N[j]*np.random.random()
h = h + h.get_dagger() # make the Hamiltonian Hermitian
fc.set_hamiltonian(h) # set the Hamiltonian in the object
print("GS energy with ED",fc.gs_energy(mode="ED")) # energy with exact diag
print("GS energy with DMRG",fc.gs_energy(mode="DMRG")) # energy with DMRG

Choosing between the C++ and Julia backend

The library uses ITensor in the background. Currently dmrgpy allows to choose between ITensor2 (C++), or ITensors (Julia). The default version executed is the the C++ v2 version, if you want to instead use the Julia version execute the method ".setup_julia()", for example

from dmrgpy import spinchain
spins = ["S=1/2" for i in range(30)] # spins in each site
sc = spinchain.Spin_Chain(spins) # create spin chain object
sc.setup_julia()

and all the subsequent computations will be performed with Julia

dmrgpy's People

Contributors

joselado avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dmrgpy's Issues

New folder in dmrgpy

Dear Jose,

I installed your great package dmrgpy in ubuntu 2022. It works when I run the predefined python scripts in folder examples in dmrgpy.
However, I need to simulate the magnetization of Heisenberg chains and ladders for different values of exchange interactions so I need to create separated folder for each one to have their source codes.
Hence, I created a separated folder with a different name in dmrgpy folder that includes a main.py (for test, I just copied your script from folder 1dIsing) . But whenever I run the code I get below error:

Traceback (most recent call last): File "/home/hamid/dmrgpy/examples/DSL Project_dmrgpy/DSL_dmrgpy_Delta1J1_S40/main.py", line 9, in <module> sc = spinchain.Spin_Chain(spins) # create the spin chain File "/home/hamid/anaconda3/lib/python3.9/site-packages/dmrgpy/spinchain.py", line 52, in __init__ Many_Body_Chain.__init__(self,sites) File "/home/hamid/anaconda3/lib/python3.9/site-packages/dmrgpy/manybodychain.py", line 88, in __init__ self.initialize() File "/home/hamid/anaconda3/lib/python3.9/site-packages/dmrgpy/manybodychain.py", line 93, in initialize self.execute(lambda: write_sites(self)) # write the different sites File "/home/hamid/anaconda3/lib/python3.9/site-packages/dmrgpy/manybodychain.py", line 415, in execute self.to_folder() # go to folder File "/home/hamid/anaconda3/lib/python3.9/site-packages/dmrgpy/manybodychain.py", line 113, in to_folder os.chdir(self.path) # go to calculation folder FileNotFoundError: [Errno 2] No such file or directory: '/home/hamid/dmrgpy/examples/DSL Project_dmrgpy/DSL_dmrgpy_Delta1J1_S40/.mpsfolder/'
While, the same main.py script in folder 1dIsing and also other folders runs normally.
What should I do to have my own folder in dmrgpy folder?

Repeated calculation of gs when evaluating vev

Hi Jose. Thanks for your awesome package! It helped me very much.
I am trying to get the vacuum expectation value (vev) of many operators on the ground state. However, I found that the DMRG (or ED) calculations are carried out again and again if I use sc.vev(). I am wondering whether there is a way to reuse the calculated wavefunction?

NameError: name 'jlsession' is not defined

Dear Jose

After installing your dmrgpy, and try to run the first example given in README, I encounter the following error:

$ python test.py
C++ backend not found, trying to run with Julia version
Julia cannot be executed
Traceback (most recent call last):
  File "/home/jw-ubu/Github/dmrgpy/test.py", line 3, in <module>
    sc = spinchain.Spin_Chain(spins) # create spin chain object
  File "/home/jw-ubu/miniconda3/envs/quantum/lib/python3.9/site-packages/dmrgpy/spinchain.py", line 45, in __init__
    Many_Body_Chain.__init__(self,sites)
  File "/home/jw-ubu/miniconda3/envs/quantum/lib/python3.9/site-packages/dmrgpy/manybodychain.py", line 86, in __init__
    self.initialize()
  File "/home/jw-ubu/miniconda3/envs/quantum/lib/python3.9/site-packages/dmrgpy/manybodychain.py", line 92, in initialize
    self.run() # run the calculation
  File "/home/jw-ubu/miniconda3/envs/quantum/lib/python3.9/site-packages/dmrgpy/manybodychain.py", line 273, in run
    self.setup_julia() # turn to Julia
  File "/home/jw-ubu/miniconda3/envs/quantum/lib/python3.9/site-packages/dmrgpy/manybodychain.py", line 97, in setup_julia
    self.initialize()
  File "/home/jw-ubu/miniconda3/envs/quantum/lib/python3.9/site-packages/dmrgpy/manybodychain.py", line 92, in initialize
    self.run() # run the calculation
  File "/home/jw-ubu/miniconda3/envs/quantum/lib/python3.9/site-packages/dmrgpy/manybodychain.py", line 268, in run
    juliarun.run(self)
  File "/home/jw-ubu/miniconda3/envs/quantum/lib/python3.9/site-packages/dmrgpy/juliarun.py", line 29, in run
    self.execute(lambda: jlsession.eval(c)) # evaluate Julia
  File "/home/jw-ubu/miniconda3/envs/quantum/lib/python3.9/site-packages/dmrgpy/manybodychain.py", line 403, in execute
    out = f()
  File "/home/jw-ubu/miniconda3/envs/quantum/lib/python3.9/site-packages/dmrgpy/juliarun.py", line 29, in <lambda>
    self.execute(lambda: jlsession.eval(c)) # evaluate Julia
NameError: name 'jlsession' is not defined

Intest.py, I simply copied your example:

from dmrgpy import spinchain
spins = ["S=1/2" for i in range(30)] # spins in each site
sc = spinchain.Spin_Chain(spins) # create spin chain object
h = 0 # initialize Hamiltonian
for i in range(len(spins)-1): 
  h = h + sc.Sx[i]*sc.Sx[i+1]
  h = h + sc.Sy[i]*sc.Sy[i+1]
  h = h + sc.Sz[i]*sc.Sz[i+1]
sc.set_hamiltonian(h) # create the Hamiltonian
print("Ground state energy",sc.gs_energy())

So why the error?
Also, why "C++ backend not found", since I should have installed it using python install.py successfully.
BTW, ITensor works fine inside julia.

Best,
Junsen

Inconsistency between result of dmrgpy and ITensor.jl

Dear Jose,

I would like to report an inconsistency between results obtained for the ground-state energy of a four-site cluster Hubbard chain using dmrgpy and Itensor.jl. The Hubbard model includes two different hopping term t=1 (intra-chain), and tp=0.06t (inter-chain).

Four-SIte cluster model

The code that I used is as follows:

Nfst = 6 # number of four-site cells

t = 1             # intra-chain hopping term: t=1 -> energy in units of t
tp = 0.06     # inter-chain hopping term
U = 1             # Hubbard term
mu = 0.5      # Chemical potential

B = 0.1      # Zeeman term 

Ne = 4 * Nfst   # total number of sites

fc = fermionchain.Spinful_Fermionic_Chain(Ne)  # create the chain

h = 0    # Hamiltonian 

for unit in range(Nfst):   # intra-chain hopping terms
    h -= t * fc.Cdagup[4 * unit + 2] * fc.Cup[4 * unit]
    h -= t * fc.Cdagdn[4 * unit + 2] * fc.Cdn[4 * unit]
    h -= t * fc.Cdagup[4 * unit + 2] * fc.Cup[4 * unit + 1]
    h -= t * fc.Cdagdn[4 * unit + 2] * fc.Cdn[4 * unit + 1]
    h -= t * fc.Cdagup[4 * unit + 2] * fc.Cup[4 * unit + 3]
    h -= t * fc.Cdagdn[4 * unit + 2] * fc.Cdn[4 * unit + 3]

for unit in range(Nfst-1):    # inter-chain hopping term
    h -= tp * fc.Cdagup[4 * unit + 3] * fc.Cup[4 * unit + 4]
    h -= tp * fc.Cdagdn[4 * unit + 3] * fc.Cdn[4 * unit + 4]
    h += mu * (fc.Nup[4 * unit + 3] + fc.Ndn[4 * unit + 3])   
    h -= mu * (fc.Nup[4 * unit + 4] + fc.Ndn[4 * unit + 4])

h = h + h.get_dagger()

for i in range(4*Nfst):
    h -= B * fc.Sz[i]                    # Field term
    h += U*(fc.Nup[i]-0.5)*(fc.Ndn[i]-0.5)     # Hubbard term

fc.set_hamiltonian(h)                       # set the Hamiltonian to the object
wf = fc.get_gs()                                  # compute ground state
Mz = [fc.vev(Szi) for Szi in fc.Sz]      # magnetization per site

Sz_cluster = np.zeros(Nfst)              # total magnetization per unit block (four-site clusters)

nbt = [-2, -1, 0, +1]                           # sites per cluster
for unit in np.arange(0, Nfst):
    for i in nbt:
        Sz_cluster[unit] += wf.dot(fc.Sz[4 * unit + 2 + i]*wf).real

After spending much time, I understood that When I consider tp <0.35, I get a large discrepancy for the results of Itensor.jl.
To remove all degeneracies I added a finite Zeeman term and also a chemical potential to fix the total quantum number as I wish. In fact, I need to have ground state |S, S_zT> = |1, +1> in half-filling. Everything seems to be fine when tp>0.35, but when I take tp<0.35 I loss the consistency between dmrgpy and Itensor.jl results.

Have you any idea to address this problem?

Magnetization of an arbitrary 1D chain

Dear Jose,

I am an ALPS package user. Recently, I have decided to work with DMRG to simulate 1D branched chains, two-leg and three-leg ladders. I found your dmrgpy package that seems to be nice to use in my future projects.
I have a question regarding an arbitrary lattice chain.
ALPS package allows one to construct any lattice for 1D models (lattice.xml) whose sites may have more than one adjacent spins that are interacted with.
Does dmrgny have this option? Or it just supports 1D linear chains.
For example, I would like to compute the total magnetization and local magnetization per site for a branched chain as shown in below

Threeside_Chain

or for a 3-leg ladder shown in below graph

ThreeLegLadder

Can I employ dmrgpy package to do these simulations?
If so, please let me know how can I introduce my own 1D lattice to dmrgpy?

As far as I understood, dmrgpy is more efficient rather than ALPS, since it covers more subjects of many-body problem (dynamical properties of 1D models) and is faster to calculate the problems.
Am I right?

finite_temperature_ground_state

Dear Jose,

I am investigating the magnetization of a transverse field Ising model at low temperature by using dmrg form dmrgpy.
I found two folders in examples of dmrgpy package.
I have some questions and I appreciate if you reply.

  • You considered mode="ED", can I switch the mode to mode="dmrg"?
  • If I consider T = 0.1, should I multiply this value with some number to get the input temperature value of the dmrg calculations? Or the considered temperature value (T = 0.1) is the same as the input temperature of dmrg calculations?
    For example, in main.py file in folder "finite_temperature_dynamical_correlator" you considered T=0.0005 for dmrg calculations (line 30), while for plotting the dynamical correlators you nominated the temperature as T = 0.1 (line 50).
    On the other hand, in main.py file in folder "finite_temperature_ground_state", you considered the temperature as T = 0.01 (line 24).

Mixed boson-spin models

Dear Jose,

I would like to know how to use dmrgpy to calculate the otoc of a mixed boson-spin models (the rightmost side of the spin chain is coupled with a boson chain) , but i have no idea. Can you give me some hint?

Thank you.

NameError: name 'jlsession' is not defined

Hi!

I'm very happy to find a DMRG package that uses Python. I've cloned your repo to my Jupyter Notebook and when I run any of your example codes I get this error message:
NameError: name 'jlsession' is not defined

It seems like the only common error for all examples. I don't know what it is or how to fix it. Can you please help?

Here's the full error:

C++ backend not found, trying to run with Julia version

NameError Traceback (most recent call last)
in
3 n = 6 # number of different spinless fermionic orbitals
4 # fc is an object that contains the information of the many body system
----> 5 fc = fermionchain.Fermionic_Chain(n) # create the object
6 # h = 0
7 # create random hoppings

~/dmrgpy/examples/s12_chain/../../src/dmrgpy/fermionchain.py in init(self, n)
19 # self.N = [self.Cdag[i]*self.C[i] for i in range(n)]
20 self.Id = self.get_operator("Id",1)
---> 21 Many_Body_Chain.init(self,[0 for i in range(n)])
22 self.fermionic = True
23 self.use_ampo_hamiltonian = True # use ampo

~/dmrgpy/examples/s12_chain/../../src/dmrgpy/manybodychain.py in init(self, sites)
83 self.kpm_extrapolate_mode = "plain" # mode of the extrapolation
84 os.system("mkdir -p "+self.path) # create folder for the calculations
---> 85 self.initialize()
86 # and initialize the sites
87 def initialize(self):

~/dmrgpy/examples/s12_chain/../../src/dmrgpy/manybodychain.py in initialize(self)
89 self.task = {"write_sites":"true"}
90 self.execute(lambda: write_sites(self)) # write the different sites
---> 91 self.run() # run the calculation
92 self.sites_from_file = True
93 def setup_julia(self):

~/dmrgpy/examples/s12_chain/../../src/dmrgpy/manybodychain.py in run(self, automatic)
270 if not os.path.isfile(mpscpp): # mpscpp.x not found, rerun with julia
271 print("C++ backend not found, trying to run with Julia version")
--> 272 self.setup_julia() # turn to Julia
273 return self.run() # rerun with julia
274 from . import cpprun

~/dmrgpy/examples/s12_chain/../../src/dmrgpy/manybodychain.py in setup_julia(self)
94 """Setup the Julia mode"""
95 self.itensor_version = "julia"
---> 96 self.initialize()
97 def setup_cpp(self):
98 """Setup the Julia mode"""

~/dmrgpy/examples/s12_chain/../../src/dmrgpy/manybodychain.py in initialize(self)
89 self.task = {"write_sites":"true"}
90 self.execute(lambda: write_sites(self)) # write the different sites
---> 91 self.run() # run the calculation
92 self.sites_from_file = True
93 def setup_julia(self):

~/dmrgpy/examples/s12_chain/../../src/dmrgpy/manybodychain.py in run(self, automatic)
265 elif self.itensor_version in ["julia","Julia","jl"]:
266 from . import juliarun
--> 267 juliarun.run(self)
268 return
269 else: raise

~/dmrgpy/examples/s12_chain/../../src/dmrgpy/juliarun.py in run(self)
27 import contextlib
28 c = "@suppress_out include(""+dmrgpath+"/mpsjulia/mpsjulia.jl");"
---> 29 self.execute(lambda: jlsession.eval(c)) # evaluate Julia
30
31

~/dmrgpy/examples/s12_chain/../../src/dmrgpy/fermionchain.py in execute(self, f)
129 from . import multioperator
130 multioperator.use_jordan_wigner = False
--> 131 return Many_Body_Chain.execute(self,f)
132
133

~/dmrgpy/examples/s12_chain/../../src/dmrgpy/manybodychain.py in execute(self, f)
399 """Execute function in the folder"""
400 self.to_folder() # go to folder
--> 401 out = f()
402 self.to_origin() # go back
403 return out # return result

~/dmrgpy/examples/s12_chain/../../src/dmrgpy/juliarun.py in ()
27 import contextlib
28 c = "@suppress_out include(""+dmrgpath+"/mpsjulia/mpsjulia.jl");"
---> 29 self.execute(lambda: jlsession.eval(c)) # evaluate Julia
30
31

NameError: name 'jlsession' is not defined

sc.exponential() raises error and other questions

Hi Jose,
This is an amazing package and I have made it a point to let all my collaborators know about it. Kudos for making such nicely constructed !! I have a couple of questions which are appended below. I must say that i do not have much experience in DMRG but I am just beginning to find my way through.

  1. I am interested in computing String correlation function for S=1 Haldane chains. I am using the exponential attribute for an sc object as given in example (https://github.com/joselado/dmrgpy/blob/master/examples/exponential_EV/main.py). My code is as follows
#String correlator
#******************
def String_correlation_fn(self):
         String_correlator=[]
         item='z'
         Op_S={'x':sc.Sx, 'y':sc.Sy, 'z':sc.Sz}
         ground_st = (sc.get_gs(mode=self.mode)).normalize()   

         def String_sum(index, item):
               op_string = Op_S[item][1]
               for k in np.arange(2, index):
                   op_string += Op_S[item][k]
               return op_string 
               
          if item in Op_S.keys():
                     
                 for i in np.arange(self.no_spins):
                      if i in [0,1]:
                          String_correlator.append(ground_st.dot(Op_S[item][0]*Op_S[item][i]*ground_st))
                      else:    
                          String_correlator.append(ground_st.dot(Op_S[item][0]*sc.exponential(1j*np.pi*String_sum(i, item), Op_S[item][i]*ground_st, mode=self.mode))) 

I can produce the results for N=4, 6 spins but the code returns an error saying " No active exception to re-raise" for N>6 onwards. It has to do with maxsize in algebra.py. Do you have any suggestions?

  1. Is it possible to get excited state wavefunctions (say the first or second excited state) like we have access to ground state through the attribute sc.get_gs()? I dont yet see any examples doing that hence the question.

  2. Is it possible to get the overlap of the wavefunction (both ground and excited state of choice) over the constituent basis states. Say for example for N=4 , S=1 case I would want the contribution of the basis (0,+1, -1, 0)^T in the ground singlet state etc from DMRG and ED? What is the way to do that. One option would be to use the sc.overlap () attribute but the basis vector of choice ([0, +1, -1, 0)^T here) would then have to be defined as an sc object externally by the user . What is protocol to do it ?

  3. For smaller N (<10) it is possible to get the Hamiltonian matrix ? Right now sc.set_hamiltonian() produces an object with an address pointer . Can it be converted to a dense matrix object ? For example the way one does with scipy etc ? like scipy. sparse.csr_matrix.todense() for a sparse csr_matrix

  4. I havent yet tried time evolution but I am going to soon with superposition of DMRG eigenstates . Do the imaginary_evolution() attribute as given in example https://github.com/joselado/dmrgpy/blob/master/examples/evolve_wavefunction/main.py has any restriction on size of N (spins) as the sc.exponential() attribute in point 1). I am talking about S=1 case for close to N=10-25 spins

It would be extremely beneficial if you have any suggestions about the aforementioned queries ?
Thanks a lot in advance and also for the excellently written package.

Installtion issue

Hi, my name sadaf i am new to python and coding.
I am using jupyter notebook.
How I install DMRGpy using pip?
I am also using window10.
Thanks

Sample Example to Calculate the various Quantum Entanglement Measures at Zero T, Finite Temperature

Hi Joselado,

I appreciate your library. It helps us in learning and understanding the spin systems.

I have a request for you.

I want to do some calculations on Quantum Entanglement Measures (Temperature dependent also) such as Concurrence.
It would be be nice to see some sample example for 1D spin chain, It will great if you can add, suggest some piece of code for doing such calculations.

Thanks.

confusing example in README.md

Let me just start by saying that I RALLY like the package, nice interface to DMRG!

I think the example "Spin and charge correlator of the 1D Hubbard model
" in the README.md has some typos.
specifically, I think it should be
I noted corrections with NOTE

from dmrgpy import fermionchain
n = 20 # number of sites
fc = fermionchain.Spinful_Fermionic_Chain(n)
# first neighbor hopping
h = 0
for i in range(n-1):
  h = h+fc.Cdagup[i]*fc.Cup[i+1]            # NOTE  h = h+... instead just h = ...
  h = h+fc.Cdagdn[i]*fc.Cdn[i+1]
h = h.get_dagger() # Make Hermitian
# Hubbard term
for i in range(n):  # NOTE  range should go for all sites
  h = 2.*(fc.Nup[i]-.5)*(fc.Ndn[i]-.5)    # NOTE Ndn instead of Cup[i+1]
fc.set_hamiltonian(h) # initialize the Hamiltonian
pairs = [(0,i) for i in range(n)]
# compute the two correlators
zz = [fc,vev(fc.Sz[0]*fc.Sz[i]).real for i in range(n)]
cc = [fc,vev(fc.Cdagup[0]*fc.Cup[i]).real for i in range(n)]
print("Spin correlators",zz)
print("Site correlators",cc)

Am I correct? I was not sure if this warranted a pull request.. :)

Specify half-filling

Hi Jose!

I'm trying to write a simulation following the "Generic interacting fermionic Hamiltonian" example.

I notice the fermionchain.Fermionic_Chain(n) only take the number of sites as argument, so I'm wondering if I am to simulate a 1-D Hubbard-like system, say with 20 atomic sites and 10 spinless electrons, is there a way to do that with your code?

Installation&general question

Hello,
Could you please answer my question:
Is it true that 'dmrgpy' can carry out any calculation that Itensor can do? So, can one use it in research problems?

Could you also help to install the 'dmrgpy'?
I use Windows10 and installed Itensor via Cygwin64.
In Anaconda Prompt I typed git clone https://github.com/joselado/dmrgpy
What should I do next?

Thank you.

Spectrum with ED

Hello Joselado!!
Can I get the full spectrum of a given Hamiltonian using "Dmrgpy" with ED mode?

Specify half-filling fermionchain.Spinful_Fermionic_Chain

Hi Jose!

I realized that how it is possible to tune the total number of spinless particles in your sample code:
https://github.com/joselado/dmrgpy/blob/master/examples/total_particle_number/main.py

Is the procedure of finding the total number of spinless electrons described in above code applicable for the case: fermionchain.Spinful_Fermionic_Chain, when I want to have the Hubbard model in half-filling such that there is an imbalance term|N_up - N_dn| = 2? that means <gs|Sz_total|gs> = 1.

In your code at sufficiently low values of the chemical potential (mu < -3.5) the total number of spinless fermions reaches its highest value ne = 4 that means in half filling case we have ne = 2. For the case spinful fermionic chain I found that the total number of electrons for i in range(L): Nop = Nop + fc.N[i] gives one-quarter number of total particles. However, it needs to take into account the sum of total number of particles with spin up (N_up) and those with spins down (N_dn) all together to get the total number of particles N_total in half-filling. Is that right?

excited energy

Hi Professor,

Thanks for the resource, I find it very useful. I am trying to use DMRG to calculate excited energy of a spin system. When I used sc.get_excited(mode="DMRG"), it does not give me the full spectrum (all eigenvalues of the system). I am wondering how I could get all the excited energy eigenvalues? Thanks.

Spin model

Hello,

I am working on Heisenberg spin chain, I am wondering if there is a way to get the spectrum in a particular total spin sector, i.e. (select from the full spectrum where the corresponding eigenstates give a particular total spin)? Another question I have how to calculate expectation value of an operator in excited states using "sc.vev"? Thank you.

Poor dmrg for large N spin chains

Hi Jose,
Recently I used your library for finding the GS magnetization of a spin chain using dmrg implementation '(mode="DMRG")'.
I get a smooth curve for small sizes (lets say up to 16), but for higher spin let's 50 or 100, I get a noisy, not so smooth curve. Can you help me in this ?

Also where we can specify the sweeps and max-dimension for truncation in your spin chain program for magnetization. I see only mode=DMRG is defined in that.

Thanks.

'Spin_Chain' object has no attribute 'get_dos'

Hello.
I need help in computing the density of state of a spin chain.

I tried to run the example name: "dos_spin_chain". But I got the following error:

AttributeError: 'Spin_Chain' object has no attribute 'get_dos'

How can I solve this problem?

Query: Regarding Energy gap calculation

In the following your code for calculation of energy gap of 1D Transverse Ising model, Could you please tell/explain me the purpose of line No. 17: return abs(sc.vev(sc.Sz[0])) ? Result is different when I don't use this line.

 # Add the root path of the dmrgpy library
 import os ; import sys ; sys.path.append(os.getcwd()+'/../../src')
 import numpy as np
 from dmrgpy import spinchain
 # This example shows the quantum phase transition in the trnasverse Ising model
 # generate a 1D Ising chain
 def get_gap(bx):
    """
    Compute the gap of the 1D Ising model with DMRG
    """
    print("Computing B_x = ",bx)
    sc = spinchain.Spin_Chain([2 for i in range(30)]) # create 
    h = 0
    for i in range(sc.ns-1): h = h + sc.Sz[i]*sc.Sz[i+1]
    for i in range(sc.ns): h = h + bx*sc.Sx[i]
    sc.set_hamiltonian(h)
    return abs(sc.vev(sc.Sz[0]))
    es = sc.get_excited(mode="DMRG",n=2) # compute the first two energies
    return es[1] - es[0] # return the gap
bs = np.linspace(0.,1.,30) # list of fields
gs = [get_gap(b) for b in bs] # list of gaps
import matplotlib.pyplot as plt
plt.plot(bs,gs,marker="o")
plt.xlabel("Bx")
plt.ylabel("Gap")
plt.show()

Thanks and Regards

how to set the particle number fixed ?

Hi, Jose

Great work!

Recently, I am learning to use Itensor.
I happened to find your excellent code package dmrgpy.

I finally get dmrgpy package installed on the computer.
The example code runs successfully!

Here I have a small question on the example code  "spinless_fermions".

In main.py, I see that  "n "  can be taken a lattice size.
and my question is,
(1) can we set the number of the spinless fermions?
(2) If it is yes, how to set value of the particle number?

Thank your for supplying such a good code package!
It helps a lot
Wonderful wok!

WL

import errors

hello,
after installation of dmrgpy , i ran one of the given codes ( ground state energy of 1d heisenberg hamiltonian ) in examples .
but there is always some import error regrding numpy and different libraries.
i also ran some other given codes but still got the 'import errors'.
why it is not working.

Thanks
best
sadaf

Human readable mps.MPS structures

Hey Joselado,

I really appreciate you creating this package, it's so helpful!
I was wondering and trying to figure out how can one convert the output of the dmrgpy.mps.MPS class into say a list of matrices? The .mps built in function reads the binary .mps files generated from sims into bytes: b'\x03\x00\x00\x00\x00...', but I am not sure how to convert this to human readable. I've tried struct.unpack, but it typically results in nonsense.

Thanks for your time.

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.