# MPS Applet

### Site Tools

en:implementation

# Implementation

## DMRG

In this section the implementation of the relevant Java classes of the applet is explained. Though the applet just implements a spin-$\frac{1}{2}$-chain, all classes will have a variable number of local parameters.

### Matrix

The class “Matrix” implements the basic routines for matrices as two-dimensional arrays and furthermore is the wrapper for the following jlapack-functions 1)2):

• DGEMM - matrixmultiplication (mult), matrixaddition (add), matrixsubtraction (sub) and transpose (trans)
• DGESVD - Single value decomposition (svd)
• DSYEV - exact diagonalisation (Eigen)

Furthermore it is possible to merge matrices vertically or horizontally (merge). The files to split the matrices again (split), will be saved within the class, but note: It will just split the last merge.

### MatrixMatrix

The class is the implementation for matrices of matrices, as needed for the MPO for the $\hat W^{\left[i\right]}$ (See here). There is no implementation for the SVD or exact diagonalization for this class (This does not make sense).

### Mps

In this class the MPS are implemented. It includes three two-dimensional arrays for the M-, A- or B-matrices and for the R- and L-matrices. There are two different constructors for the MPS, one fills the matrices with random values, the other one constructs a MPS from a given quantum state. This state has to be given via an one-dimension array, that contains the coefficients of the quantum state. Both constructors will give back a left-normalized state and also create the R-matrices. Therefore the Hamiltonian must also be given as an MPO.

public void BuildR(Mpo H, int N)
{
Matrix Eins = new Matrix(1,1); Eins.SetContent(0,0,1);
for (int a=0; a<this.A[N+1][0].GetSize()[0];a++)
{
this.R[N][a] = new Matrix(H.W[N+1][0][0].GetSize()[0], this.A[N+1][0].GetSize()[0]);
for (int j=0; j<this.states; j++)
for (int k=0; k<this.states; k++)
for (int l=0; l<this.A[N+1][0].GetSize()[1]; l++)
if (N>this.N-2)
for (int m=0; m<this.A[N+1][j].GetSize()[0]; m++)
for (int o=0; o<H.W[N+1][j][k].GetSize()[0]; o++)
this.R[N][a].SetContent(o,m, this.R[N][a].GetContent(o,m)+this.A[N+1][j].GetContent(0,m)*H.W[N+1][j][k].GetContent(0,o)*this.A[N+1][k].GetContent(0,a));
else
this.R[N][a] = new Matrix(this.R[N][a].add(H.W[N+1][j][k].mult(this.R[N+1][l].trans()).mult(this.A[N+1][k].trans()).mult(this.A[N+1][j].GetContent(l,a)).trans()));
}
}

One also has to give the MPO for every “Sweep-Step” as the L- and R-matrices have to be updated.

public Matrix DoLeftSweepStep(int j, Mpo op)
{
Matrix AAllStates = new Matrix(this.A[j][0]);
for (int k=1; k<this.states; k++)
AAllStates.merge(this.A[j][k], false);

Matrix u=new Matrix();
Matrix vt=new Matrix();
Matrix s=AAllStates.svd(u, vt);

for (int i=vt.Merges.length;i>=0;i--)
this.A[j][i]=vt.split();
for (int i=0; i<this.states; i++)
this.A[j-1][i]=(this.A[j-1][i].mult(u).mult(s));
this.BuildR(op, j-1);
return s;
}

The scalar product is also implemented in this class:

public double ScalarProd(Mps b)
{
if (this.N != b.N)
return 0.0;
Matrix out = new Matrix();
Matrix pre_out = new Matrix();
pre_out = this.A[0][0].trans().mult(b.A[0][0]);
for (int s=1; s<this.states;s++)
out = new Matrix(pre_out);
for (int i=1;i<this.N;i++)
{
pre_out = this.A[i][0].trans().mult(out).mult(b.A[i][0]);
for ( int s=1; s<this.states;s++)
out = new Matrix(pre_out);
}
return out.GetContent(0,0);
}

### Mpo

This class implement the Mpo by using a three dimensional matrix-matrix-array. There are two different constructors: One constructor needs all $\hat W^{\left[i\right]}$ for every site, the other one just needs one $\hat W^{\left[i\right]}$ and takes this one for all sites (The special matrices for the last and first site will be created from the related row and column).

The application of a Mpo on a Mps - as described in here - is given by the function mult:

public Mps mult(Mps b)
{
Mps out = new Mps(this.N, b.d*this.W[0][0][0].GetSize()[1], b.d_max*this.W[this.N/2][0][0].GetSize()[1], this.states);
for (int l=0; l<this.N; l++)
for (int i=0; i<this.states; i++)
for (int j=0; j<this.states; j++)
for (int m=0; m<b.A[l][i].GetSize()[0];m++)
for (int o=0; o<b.A[l][i].GetSize()[1];o++)
for (int q=0; q<this.W[l][i][j].GetSize()[0];q++)
for (int r=0; r<this.W[l][i][j].GetSize()[1];r++)
out.A[l][i].SetContent(r*b.A[l][i].GetSize()[1]+o, q*b.A[l][i].GetSize()[0]+m, out.A[l][i].GetContent(r*b.A[l][i].GetSize()[1]+o, q*b.A[l][i].GetSize()[0]+m)+this.W[l][i][j].GetContent(r, q)*b.A[l][j].GetContent(o, m));
return out;
}

### Dmrg

The class “Dmrg” contains the Hamiltonian as a Mpo and the wavefunction as a Mps and implements the DMRG-algorithm and is also the interface to the gui. The four main function are:

• DoNextStep

This function is the only one that can be used outside the class (with the constructor). It will automatically do a DMRG step in the correct direction.

• DoRightStep

Here a complete right-sweep-step is implemented. At first we have to setup the effective Hamiltonian $H_{\text{Eff}}$. Then we have to solve the eigenvalue problem. Finally we have to update the new MPS-matrix with the values from the eigenvector and right-normalize the matrix. At last we save all the results for the gui.

public void DoRightStep(int N)
{
Matrix H = this.BuildHeff(N);
double[] EigenValue = H.Eigen();
Matrix[] M = new Matrix[this.state.states];
for (int i=0; i<this.state.states; i++)
{
M[i] = new Matrix(this.state.A[N][0].GetSize()[1], this.state.A[N][0].GetSize()[0]);
for (int m=0; m<this.state.A[N][0].GetSize()[0]; m++)
for (int o=0; o<this.state.A[N][0].GetSize()[1]; o++)
M[i].SetContent(o, m, H.GetContent(0, (i*this.state.A[N][0].GetSize()[0]*this.state.A[N][0].GetSize()[1])+(m*this.state.A[N][0].GetSize()[1])+o));
this.state.A[N][i] = new Matrix(M[i]);
}
this.CalcSxSz();
Matrix s = this.state.DoRightSweepStep(N, this.operator);
s = s.mult(s);
this.CurrentDm = new double[s.GetSize()[0]];
for (int i = 0; i<this.CurrentDm.length; i++)
this.CurrentDm[i] = s.GetContent(i,i);
this.CurrentEnergy = EigenValue[0];
}
• DoLeftStep

This function is implemented analogously to the function DoRightStep, but going right and left-normalizing.

• BuildHeff

In order to create $H_{\text{Eff}}$, we will setup an auxiliary object $LWR^{[\sigma][\sigma^\prime][a_l][a_{l-1}]}$. The construction follows the calculation described here. Finally we will sort all values into $H_{\text{Eff}}$.

public Matrix BuildHeff(int N)
{
int Size = this.state.states*this.state.A[N][0].GetSize()[0]*this.state.A[N][0].GetSize()[1];
Matrix H = new Matrix(Size, Size);
Matrix[][][][] LWR = new Matrix[this.state.states][this.state.states][this.state.A[N][0].GetSize()[0]][this.state.A[N][0].GetSize()[1]];
for (int i=0; i<this.state.states; i++)
for (int j=0; j<this.state.states; j++)
for (int m=0; m<this.state.A[N][0].GetSize()[0]; m++)
for (int o=0; o<this.state.A[N][0].GetSize()[1]; o++)
if (N-1 < 0)
LWR[i][j][m][o] = new Matrix((this.operator.W[N][i][j].mult(this.state.R[N][o].trans())));
else
LWR[i][j][m][o] = new Matrix(this.state.L[N-1][m].mult(this.operator.W[N][i][j].mult(this.state.R[N][o].trans())));

for (int i=0; i<this.state.states; i++)
for (int j=0; j<this.state.states; j++)
for (int m=0; m<this.state.A[N][0].GetSize()[0]; m++)
for (int n=0; n<this.state.A[N][0].GetSize()[0]; n++)
for (int o=0; o<this.state.A[N][0].GetSize()[1]; o++)
for (int p=0; p<this.state.A[N][0].GetSize()[1]; p++)
H.SetContent((j*this.state.A[N][0].GetSize()[0]*this.state.A[N][0].GetSize()[1])+(n*this.state.A[N][0].GetSize()[1])+p, (i*this.state.A[N][0].GetSize()[0]*this.state.A[N][0].GetSize()[1])+(m*this.state.A[N][0].GetSize()[1])+o, LWR[i][j][m][o].GetContent(p,n));
return H;
}

## Applet

Here we describe all classe and libraries needed for the gui.

### DmrgCollector

This class is derived from the jchart2D-class “ADataCollector” and adds data to the single charts. In order to have parallel usage of the applet to the computation, this class implements the interface “Runnable” 3). This ensures that the class is executed in a single thread. The complete computation will be started by the function “collectData”. At first it will be tested if the sweep-limit is fulfilled:

// Max number of sweeps reached? ==> Stop
if (this.visuRef.DmrgRef.CurrentSweep == this.visuRef.Sweeps)
this.visuRef.stopData();

Then the sweep will be executed and the new energy will be added to the energy-chart:

// create new data
int y = this.visuRef.DmrgRef.DoNextStep();

Then the trace of the density matrix will be updated:

// Update trace of dm
this.visuRef.getDmTrace().removeAllPoints();
for (int i = 0; i<this.visuRef.DmrgRef.CurrentDm.length; i++)
this.visuRef.getDmTrace().addPoint(i, this.visuRef.DmrgRef.CurrentDm[i]);

Next the expectation values will be calculated. Here we use the Operator-class, which just supports single-site-operators:

// Aktualisieren der Erwartungswerte für Sx und Sz
for (int i=0; i<this.visuRef.Site; i++)
{
}		

Finally we will calculate the entanglement entropy.

//Calc entanglement entropy
double enen = 0.0;
for (int i = 0; i<this.visuRef.DmrgRef.CurrentDm.length; i++)
enen = enen + this.visuRef.DmrgRef.CurrentDm[i]*(Math.log(this.visuRef.DmrgRef.CurrentDm[i])/Math.log(2.0));
this.visuRef.getEeTrace().addPoint(y+0.5*(this.visuRef.DmrgRef.Direction==false?1:-1),-enen);

### visu

The class visu contains the main-function and the complete gui. All objects will be initiated and the control parameters are saved within this class.

Graphs are displayed using the JChart2D library 4).

©: This site was created by Piet Dargel and Thomas Köhler

1)
Anderson, E. ; Bai, Z. ; Bischof, C. ; Blackford, S. ; Demmel, J. ; Dongarra, J. ; Du Croz, J. ; Greenbaum, A. ; Hammarling, S. ; McKenney, A. ; Sorensen, D.: LAPACK Users’ Guide. Third. Philadelphia, PA : Society for Industrial and Applied Mathematics, 1999. – ISBN 0-89871-447-8 (paperback)
2)
Doolin, David M. ; Dongarra, Jack ; Seymour, Keith: JLAPACK - compiling LAPACK Fortran to Java. In: Sci. Program. 7 (1999), April, S. 111–138. – URL http://portal.acm.org/citation.cfm?id=1239860.1239868. – ISSN 1058-9244
en/implementation.txt · Last modified: 2019/06/04 21:39 by thomas