Skip to content
ED-01 Sparse Diagonalization

ED-01 Sparse Diagonalization

In this tutorial we will learn how to use the sparse diagonalization program sparsediag, which finds the lowest eigenstates of a quantum Hamiltonian by the iterative Lanczos algorithm, and how to read out arbitrary observables on the resulting eigenstates.

Measurements on a 1-dimensional Heisenberg chain

As a first example we consider the isotropic antiferromagnetic Heisenberg chain for spin S=1,

H=Ji,jSiSj,J>0, H = J \sum_{\langle i,j \rangle} \mathbf{S}_i \cdot \mathbf{S}_j , \qquad J>0 ,

where the sum runs over nearest-neighbour bonds on a periodic chain. This model is the paradigmatic example of an integer-spin antiferromagnet: Haldane predicted, and numerics have since confirmed, that it has a unique, gapped ground state with exponentially decaying spin correlations and short-range antiferromagnetic order peaked at momentum q=πq=\pi (F.D.M. Haldane, Phys. Rev. Lett. 50, 1153 (1983)). Exact diagonalization gives us direct access to the ground-state wavefunction of a finite chain, from which we can compute any correlation function or structure factor exactly — this tutorial shows how to request such measurements from sparsediag. The finite-size gap itself is the subject of the next tutorial, ED-02.

Parameters

ParameterMeaningValue
LATTICEbuilt-in periodic 1D latticechain lattice
MODELquantum spin modelspin
local_Sspin quantum number per site1
Jnearest-neighbour Heisenberg coupling1
Lnumber of sites4
CONSERVED_QUANTUMNUMBERSsymmetries used to block-diagonalize the HamiltonianSz
MEASURE_CORRELATIONS[...]requests SizSjz\langle S^z_iS^z_j\rangle and Si+Sj\langle S^+_iS^-_j\rangle on every computed eigenstatesee below
MEASURE_STRUCTURE_FACTOR[...]requests the Fourier transform of a correlation functionSzS^z

Lattice

The chain lattice is one of the built-in geometries of the ALPS lattice library; it places L sites on a ring connected by periodic nearest-neighbour bonds of strength J:

      J     J     J
  o-------o-------o-------o
  0       1       2       3
  |___________________________|
              J   (bond 3-0, periodic)

Method

The S=1 chain with L=4 sites has Hilbert space dimension 34=813^4=81, which splits into an Sz=0S_z=0 sector of dimension 19 once the Sz quantum number is used. Since we only need the ground state (and, for the structure factor and correlations below, no other eigenstates), the iterative Lanczos algorithm implemented by sparsediag is the natural choice: it converges the lowest eigenpair of a sparse Hamiltonian in a handful of matrix-vector multiplications, without ever constructing or diagonalizing the full 81×8181\times 81 matrix.

Using the command line

The parameter file parm1a sets up an exact diagonalization of the quantum mechanical S=1 chain with 4 sites:

MODEL="spin"
LATTICE="chain lattice"
CONSERVED_QUANTUMNUMBERS="Sz"
MEASURE_STRUCTURE_FACTOR[Structure Factor Sz]=Sz
MEASURE_CORRELATIONS[Diagonal spin correlations]=Sz
MEASURE_CORRELATIONS[Offdiagonal spin correlations]="Splus:Sminus"
local_S=1
J=1
{L=4;}

New here compared to other codes are the measurement parameters specifying which operator averages, local values, correlations and structure factors should be measured. More details about these custom measurements are available here. Using the standard sequence of commands you can first convert the input parameters to XML and then run the application sparsediag (Note that you will find these executables in the bin directory of your ALPS installation, you can add this directory to your PATH to make working with ALPS easier):

parameter2xml parm1a
sparsediag --write-xml parm1a.in.xml

The lowest eigenvalues and eigenstates are calculated in each sector (Sz,P) where P denotes the total momentum. The output file parm1a.task1.out.xml contains all the computed quantities and can be viewed with a standard internet browser. In our case the ground state lies in the Sz=0, P=0 sector. The corresponding diagonal spin correlations, shown in the XML file, look like

Diagonal spin correlations[( 0 ) -- ( 0 )]    (0.666667,0)
Diagonal spin correlations[( 0 ) -- ( 1 )]    (-0.5,0)
Diagonal spin correlations[( 0 ) -- ( 2 )]    (0.333333,0)
Diagonal spin correlations[( 0 ) -- ( 3 )]    (-0.5,0)

The numbers [( a ) – ( b )] in the above brackets refer to site indices, i.e., Sz(a)*Sz(b). In the right column one can read off the (complex) value of the correlation function. The output for the Sz structure factor for this state looks like

Structure Factor Sz[( 0 )]                    5.551115123125783e-17
Structure Factor Sz[( 1.570796326794897 )]    0.333333333333333
Structure Factor Sz[( 3.141592653589793 )]    2
Structure Factor Sz[( -1.5707963267948966 )]    0.3333333333333329

where the number in the brackets [(q)] denotes the wave number. One can limit the Sz sector explicitly by adding the following line to the parameter file:

Sz_total=0

Using Python

To set up and run the simulation in Python we use the script tutorial1a.py. The first parts of this script imports the required module pyalps, prepares the input files as a list of Python dictionaries, writes the input files and runs the application

import pyalps
parms = [{ 
        'LATTICE'                   : "chain lattice", 
        'MODEL'                     : "spin",
        'local_S'                   : 1,
        'J'                         : 1,
        'L'                         : 4,
        'CONSERVED_QUANTUMNUMBERS'  : 'Sz',
        'MEASURE_STRUCTURE_FACTOR[Structure Factor Sz]'       : 'Sz',
        'MEASURE_CORRELATIONS[Diagonal spin correlations]='   : 'Sz',
        'MEASURE_CORRELATIONS[Offdiagonal spin correlations]' : 'Splus:Sminus'
    }]

input_file = pyalps.writeInputFiles('parm1a',parms)
res = pyalps.runApplication('sparsediag',input_file)

Now you can launch your Python to run the script tutorial1a.py. We will have the same output files as in the command line version. We next load the measurements for each of the calculated eigenstates:

data = pyalps.loadEigenstateMeasurements(pyalps.getResultFiles(prefix='parm1a'))

and then print the results just for the ground state:

for sector in data[0]:
    print '\nSector with Sz =', sector[0].props['Sz'], 
    print 'and k =', sector[0].props['TOTAL_MOMENTUM']
    for s in sector:
        if pyalps.size(s.y[0])==1:
            print s.props['observable'], ' : ', s.y[0]
        else:
            for (x,y) in zip(s.x,s.y[0]):
                print  s.props['observable'], '(', x, ') : ', y

Summary

For the L=4 S=1 chain, the ground state lies in the (Sz,P)=(0,0)(S_z,P)=(0,0) sector and shows short-ranged antiferromagnetic diagonal correlations that alternate in sign with distance and decay with separation, and a static structure factor that is strongly peaked at q=πq=\pi (value 2, versus 0.33\approx 0.33 at the neighbouring momenta) — the expected signature of the short-range Néel-like order of a gapped Haldane chain, already visible on this very small system.

Questions

  • Why does Diagonal spin correlations[( 0 ) -- ( b )] alternate in sign as bb increases from 0 to 3?
  • The structure factor peak at q=πq=\pi has a finite value (2) rather than diverging. Would you expect this peak to grow, shrink, or stay the same as LL is increased? (Compare with the finite-size gap you will compute in ED-02.)
  • Add MEASURE_AVERAGE[Energy per bond]=bond_energy (or read off the total energy directly) and check that it is consistent with the diagonal and offdiagonal correlations printed above, using SiSj=SizSjz+12(Si+Sj+SiSj+)\mathbf{S}_i\cdot\mathbf{S}_j = S^z_iS^z_j + \tfrac12(S^+_iS^-_j+S^-_iS^+_j).