Example of using the MPS library evolving a one-dimensional system, where the start state can either be a ground state or a product MPS. The product state, Hamiltonian that defines the ground state, and the Hamiltonian for time evolution are given in an initialisation file.
To run the file you may also have to set up certain environment variables. To do this edit then run ./set_tnt_vars.sh in the scripts directory.
You then need to create an initialisation file. See the examples ending in .m given in the 'inititialisation' directory and listed here, and the page initfiles. You would then call the function with arguments for the initialisation file and where to save the data e.g.
There are some pre-made initialisation files you can load in directly, all found in the initialisation directory and listed in the examples in this documentation (files ending in .m).
The program will output the expectation values specified in the initialisation file.
#include "tntMps.h"
unsigned checkParams(tntComplexArray *nntsc, tntComplexArray *ostsc, int tstep);
void setParams(tntComplexArray *nnparam, tntComplexArray *nntsc, tntComplexArray *nnpsc,
tntComplexArray *osparam, tntComplexArray *ostsc, tntComplexArray *ospsc, int tstep);
int main(int argc, char **argv)
{
char initfile[TNT_STRLEN];
char savename[TNT_STRLEN];
tntExOp ExOp;
tntNetwork wf_gs, wf_start, wf_ev;
tntNetwork H, mod, prop;
int chi, L;
int mod_renorm;
int calc_ol_gs, calc_ol_is;
int calc_energy;
int U1symm_dyn;
tntNodeArray nnl, nnr, os;
tntComplexArray nnparam, osparam;
tntComplexArray nntsc, ostsc;
tntComplexArray nnpsc, ospsc;
tntIntArray sitenum;
double err, precision, E, Eprev;
tntIntArray qn_tot;
int i, i_max;
tntNodeArray HeffL, HeffR;
tntIntArray modifypmpo;
char osnm[15], ospnm[15], snnm[15];
int numsteps, tbigstep;
int tstep = -1, bigstep = 0;
int changed_params;
double ol;
if (precision > 0.0) {
tntNodeArraysNamedLoad(initfile,nnl,"nnlg",nnr,"nnrg",os,"osg");
tntComplexArraysNamedLoad(initfile,nnparam,"nnparamg",osparam,"osparamg");
tntSysRandSeedSet(time(NULL));
} else {
}
tntMpsVarMinMpoInit(wf_gs, H, &HeffL, &HeffR);
for (i = 0; i < i_max; i++) {
Eprev = E;
tntPrintf(
"Calculating ground state, Delta E_%d is %3.3e\n", i, Eprev-E);
if ((Eprev - E < precision) && (Eprev - E > 0.0)) break;
}
}
}
err = 0;
for (i = 0; i < modifypmpo.sz; i++) {
sprintf(osnm,"osm_%d",i);
tntNodeArraysNamedLoad(initfile,os,osnm);
if (modifypmpo.vals[i]) {
sprintf(snnm,"snm_%d",i);
tntIntArraysNamedLoad(initfile,sitenum,snnm);
} else {
sprintf(ospnm,"osparamm_%d",i);
tntComplexArraysNamedLoad(initfile,osparam,ospnm);
}
tntPrintf(
"Applying operator O_%d to the starting base state\n",i+1);
}
err = 0; tstep = 0;
tntIntParamsLoad(initfile, numsteps, tbigstep, calc_ol_gs, calc_ol_is, calc_energy);
if (numsteps > 0) {
tntNodeArraysNamedLoad(initfile,nnl,"nnlt",nnr,"nnrt",os,"ost");
tntComplexArraysNamedLoad(initfile,nnparam,"nnparamt",osparam,"osparamt");
tntComplexArraysNamedLoad(initfile,nnpsc,"nnparamt",ospsc,"osparamt");
tntComplexArraysNamedLoad(initfile,nntsc,"nnparamt_time",ostsc,"osparamt_time");
err = 0.0;
for (tstep = 0; tstep <= numsteps; tstep++) {
if (checkParams(&nntsc, &ostsc, tstep)) {
setParams(&nnparam, &nntsc, &nnpsc, &osparam, &ostsc, &ospsc, tstep);
changed_params = 1;
}
if (0 == tstep%tbigstep || tstep == numsteps) {
tntPrintf(
"Calculating time evolution, %2.0f%% complete\n",(100.0*tstep)/(1.0*numsteps));
bigstep++;
if (calc_ol_gs) {
}
if (calc_ol_is) {
}
if (calc_energy) {
if (changed_params) {
changed_params = 0;
}
}
}
}
}
return 0;
}
unsigned checkParams(tntComplexArray *nntsc,
tntComplexArray *ostsc,
int tstep)
{
unsigned i;
double x1, x2, y1, y2;
if (0 == tstep) return 1;
if (nntsc->sz) {
for (i = 0; i < nntsc->numrows; i++) {
x1 = nntsc->vals[i + nntsc->numrows*(tstep-1)].re;
x2 = nntsc->vals[i + nntsc->numrows*tstep].re;
y1 = nntsc->vals[i + nntsc->numrows*(tstep-1)].im;
y2 = nntsc->vals[i + nntsc->numrows*tstep].im;
if (x1 != x2 || y1 != y2) return 1;
}
}
if (ostsc->sz) {
for (i = 0; i < ostsc->numrows; i++) {
x1 = ostsc->vals[i + ostsc->numrows*(tstep-1)].re;
x2 = ostsc->vals[i + ostsc->numrows*tstep].re;
y1 = ostsc->vals[i + ostsc->numrows*(tstep-1)].im;
y2 = ostsc->vals[i + ostsc->numrows*tstep].im;
if (x1 != x2 || y1 != y2) return 1;
}
}
return 0;
}
void setParams(tntComplexArray *nnparam,
tntComplexArray *nntsc,
tntComplexArray *nnpsc,
tntComplexArray *osparam,
tntComplexArray *ostsc,
tntComplexArray *ospsc,
int tstep)
{
unsigned i, j, M;
double x1, x2, y1, y2;
if (nntsc->sz && nnparam->sz) {
M = nnparam->numrows;
for (i = 0; i < M; i++) {
x1 = nntsc->vals[i + M*tstep].re;
y1 = nntsc->vals[i + M*tstep].im;
for (j = 0; j < nnparam->numcols; j++) {
x2 = nnparam->vals[i + M*j].re;
y2 = nnparam->vals[i + M*j].im;
nnpsc->vals[i + M*j].re = x1*x2 - y1*y2;
nnpsc->vals[i + M*j].im = x1*y2 + y1*x2;
}
}
}
if (ostsc->sz && osparam->sz) {
M = osparam->numrows;
for (i = 0; i < M; i++) {
x1 = ostsc->vals[i + M*tstep].re;
y1 = ostsc->vals[i + M*tstep].im;
for (j = 0; j < osparam->numcols; j++) {
x2 = osparam->vals[i + M*j].re;
y2 = osparam->vals[i + M*j].im;
ospsc->vals[i + M*j].re = x1*x2 - y1*y2;
ospsc->vals[i + M*j].im = x1*y2 + y1*x2;
}
}
}
}