Heisenberg model for four spins

The goal of this exercise is to build a Hamiltonian for the four spin system, and calculate its ground state. The difference with the previous exercise is that we will use the same setup as for the DMRG algorithm. This means that we will build a chain as a block-site-site-block system, where the left-most spin will be the left block, the two central spins will be the single sites, and the right-most spin will be the right block.

Again, the Hamiltonian that we will build is the antiferromagnetic Heisenberg model:

H=\sum_{i}\vec{S}_{i}\cdot\vec{S}_{i+1}=
\sum_{i}\left[S^{z}_{i}S^{z}_{i+1}+
\frac{1}{2}\left(S^{\dagger}_{i}S^{-}_{i+1}+
S^{-}_{i}S^{\dagger}_{i+1}\right)\right]

where \vec{S}_{i}=\vec{\sigma}_{i}/2 are the spin operators, \sigma_{i} are the Pauli matrices, and S^{\pm}_{i}=S^{x}_{i}\pm i S^{y}_{i}.

Exercise

Calculate the ground state (energy and wavefunction) of the antiferromagnetic Heisenberg model for a system of four spins one-half.

Solution

You can use the System class to create the four spin chain, and set the system Hamiltonian to the antiferromagnetic Heisenberg model. To do that you add the terms to the system Hamiltonian, and to add a term you just have to specify which operator acts in each of the parts: left block, left site, right site, and right block, using the name of the operator. You can specify a parameter if you need to with a fifth optional argument. This function does that:

def set_hamiltonian_to_AF_Heisenberg(system):
    """Sets a system Hamiltonian to the AF Heisenberg Hamiltonian.

    Does exactly this. If the system hamiltonian has some other terms on
    it, there are not touched. So be sure to use this function only in
    newly created `System` objects.

    Parameters
    ----------
    system : a System.
        The System you want to set the Hamiltonain for.
    """
    system.add_to_hamiltonian('id', 'id', 's_z', 's_z')
    system.add_to_hamiltonian('id', 'id', 's_p', 's_m', .5)
    system.add_to_hamiltonian('id', 'id', 's_m', 's_p', .5)
    system.add_to_hamiltonian('id', 's_z', 's_z', 'id')
    system.add_to_hamiltonian('id', 's_p', 's_m', 'id', .5)
    system.add_to_hamiltonian('id', 's_m', 's_p', 'id', .5)
    system.add_to_hamiltonian('s_z', 's_z', 'id', 'id')
    system.add_to_hamiltonian('s_p', 's_m', 'id', 'id', .5)
    system.add_to_hamiltonian('s_m', 's_p', 'id', 'id', .5)

The remaining is calling again to the Lanczos solver to get the ground state energy and wavefunction. You can use a convenience function in the System class. Putting everything together you end up with something like this:

def main():
    # 
    # create a system object with spin one-half sites and blocks.
    #
    spin_one_half_site = SpinOneHalfSite()
    system = System(spin_one_half_site)
    #
    # build the Hamiltonian, and solve it using Lanczos.
    #
    set_hamiltonian_to_AF_Heisenberg(system)
    ground_state_energy, ground_state_wf = system.calculate_ground_state()
    #
    # print results
    #
    print "The ground state energy is %8.6f." %ground_state_energy
    print "The ground state wavefunction is :"
    print ground_state_wf.as_matrix

See a full implementation of the above code. If you run that code you should get:

$ ./solutions/heisenberg_for_four_spins.py
The ground state energy is -1.616025.
The ground state wavefunction is:
[[ ...