Tensor Network Theory Library  Beta release 1.2.1 A library of routines for performing TNT-based operations
tntMps2sDmrg.c
1 /*
2  Authors: Sarah Al-Assam, Stephen Clark and Dieter Jaksch
3  Date: $LastChangedDate$
4  (c) University of Oxford 2013
5  */
6
11 /* Include the internal header for the TNT library */
12 #include "tntMpsInternal.h"
13
63 double tntMpsVarMinMpo2sSweep(tntNetwork mps,
64  tntLegLabel dir,
65  int chi,
66  tntNetwork mpo,
67  tntNodeArray *betas,
68  tntNodeArray *gammas,
69  double *err,
70  int start_site,
71  int end_site)
72 {
73  tntNode Al, Ar; /* The current pair of MPS nodes */
74  tntNode Ol, Or; /* The current pair of MPO nodes */
75  tntNode S, VT; /* The nodes returned from an SVD of the first or last node, or the singular values tensor for the local operation */
76  int L, j; /* number of sites and site index. Here j is chosen to always refer to the left-most node in the pair of nodes being updated. */
77  double errc = 0.0; /* Error returned from each SVD */
78  double eigv; /* The real part of the eigenvalue */
79
80  /* Find the length of the MPS */
81  L = tntMpsLength(mps);
82
83  if ('R' == dir[0]) {
84  /* Set the current tensor equal to the start tensor */
85  Al = tntNodeFindFirst(mps);
86  Ol = tntNodeFindFirst(mpo);
87  for (j = 0; j < start_site; j++) {
88  Al = tntNodeFindConn(Al,"R");
89  Ol = tntNodeFindConn(Ol,"R");
90  }
91
92  for (j = start_site; j < end_site-1; j++) {
93  /* the next MPS and MPO node along */
94  Ar = tntNodeFindConn(Al, "R");
95  Or = tntNodeFindConn(Ol, "R");
96
97  /* Perform local contractions and minimisation */
98  S = tntDmrg2sLocalOps(Al, Ar, Ol, Or, betas->vals[j], gammas->vals[j+1], chi, err, &eigv);
99
100  /* Update the node for beta with the new value of Al */
101  tntMpsVarMinMpoUpdate(tntNodeFindConn(S,"L"), Ol, "R", j, betas);
102
103  /* Contract S with the node to the right of it: this tensor will contain the orthogonality twist and be the new left-most site */
104  Al = tntNodeContract(S, tntNodeFindConn(S,"R"));
105
106  /* Move operator along one site right */
107  Ol = Or;
108  }
109
110  /* Move the orthogonality centre to the next site */
111  Ar = tntNodeFindConn(Al, "R");
112
113  /* Take SVD of Al, assigning U back to Al */
114  Al = tntNodeSVD(Al, "LD", "R", "L", "R", "L", chi, &errc);
115  *err += errc;
116
117  /* Update the node for beta with the new value of Al */
118  tntMpsVarMinMpoUpdate(Al, Ol, "R", end_site-1, betas);
119
120  /* Find S and VT by moving along the network */
121  S = tntNodeFindConn(Al,"R");
122  VT = tntNodeFindConn(S,"R");
123
124  /* Contract S and VT with A2 to reform A2: this tensor will now contain the orthogonality twist */
125  Ar = tntNodeListContract(NULL, S, VT, Ar);
126
127  } else {
128  /* Set the current tensor equal to the start tensor */
129  Ar = tntNodeFindLast(mps);
130  Or = tntNodeFindLast(mpo);
131  for (j = L-1; j > start_site; j--) {
132  Ar = tntNodeFindConn(Ar,"L");
133  Or = tntNodeFindConn(Or,"L");
134  }
135
136  for (j = start_site; j > end_site+1; j--) {
137  /* the next MPS and MPO node along */
138  Al = tntNodeFindConn(Ar, "L");
139  Ol = tntNodeFindConn(Or, "L");
140
141  /* Perform local contractions and minimisation */
142  S = tntDmrg2sLocalOps(Al, Ar, Ol, Or, betas->vals[j-1], gammas->vals[j], chi, err, &eigv);
143
144  /* Update the node for gamma with the new value of Ar */
145  tntMpsVarMinMpoUpdate(tntNodeFindConn(S,"R"), Or, "L", j, gammas);
146
147  /* Contract S with the node to the left of it: this tensor will contain the orthogonality twist and be the new right-most site */
148  Ar = tntNodeContract(S, tntNodeFindConn(S,"L"));
149
150  /* Move operator along one site left */
151  Or = Ol;
152  }
153  /* the end site */
154  Al = tntNodeFindConn(Ar, "L");
155
156  /* Take SVD of Ar, assigning U back to Ar */
157  Ar = tntNodeSVD(Ar, "RD", "L", "R", "L", "R", chi, &errc);
158  *err += errc;
159
160  /* Update the node for gamma with the new value of Ar */
161  tntMpsVarMinMpoUpdate(Ar, Or, "L", end_site+1, gammas);
162
163  /* Find S and VT by moving along the network */
164  S = tntNodeFindConn(Ar,"L");
165  VT = tntNodeFindConn(S,"L");
166
167  /* Contract S and VT with A1 to reform A1: this tensor will now contain the orthogonality twist */
168  Al = tntNodeListContract(NULL, S, VT, Al);
169
170  }
171  return eigv;
172 }
173
174
184 tntNode tntDmrg2sLocalOps(tntNode Al,
185  tntNode Ar,
186  tntNode Ol,
187  tntNode Or,
188  tntNode beta,
189  tntNode gamma,
190  int chi,
191  double *errp,
192  double *eigvp)
193 {
194
195  tntNetwork Oeff; /* The network representing the effective operator for the current site */
196  tntNode Olc, Orc, O; /* Copies of operators and the reulst of their contraction */
197  tntNode theta, theta_eig; /* Result of contracting two MPS nodes */
198  tntNode S; /* The nodes of singular values returned from an SVD of theta */
199  double errc = 0.0; /* Error returned from each SVD */
200  tntComplex E_eig; /* The eigenvalue */
201
202  /* Contract Al and Ar to find theta */
203  theta = tntNodeContract(Al,Ar,NULL,"D=E");
204
205  /* Make copies of the operators to be contracted */
206  Olc = tntNodeCopy(Ol);
207  Orc = tntNodeCopy(Or);
208
209  /* Join the operators, then contract to form a two site operator */
210  tntNodeJoin(Olc,"R",Orc,"L");
211  O = tntNodeContract(Olc,Orc,NULL,"UD=VE");
212
213  /* Build the network representing the effective operator for the two sites to be updated */
214  Oeff = tntMpsVarMinMpo2sBuild(beta,gamma,theta,O);
215
216  /* The eigenvector of the Operator Oeff with the smallest eigenvalue is found */
217  theta_eig = tntNetworkMinSite(theta, &Oeff, 1, &tntMpsVarMinMpo2sContract, NULL, &E_eig);
218  *eigvp = E_eig.re;
219
220  /* Replace theta_eig in the network */
221  tntNodeReplace(theta,theta_eig);
222
223  /* take the svd of the theta node found, to reform two tensors in the MPS form. */
224  Al = tntNodeSVD(theta_eig, "LD", "R", "L", "R", "L", chi, &errc, "E=D");
225
226  /* Find S by moving along the network and return */
227  S = tntNodeFindConn(Al,"R");
228
229  /* Free the networks and nodes no longer needed */
230  tntNodeFree(&theta);
231  tntNetworkFree(&Oeff);
232  tntNodeFree(&O);
233
234  /* add to the total error and return S */
235  *errp += errc;
236  return S;
237 }
238
282 #ifdef MAKINGPUBLICDOCS
283 double tntMpsVarMinMpo2sStep(tntNetwork mps,
284 #else
285 double tntMpsVarMinMpo2sStep_(tntNetwork mps,
286 #endif
287  int chi,
288  tntNetwork mpo,
289  tntNodeArray *HeffL,
290  tntNodeArray *HeffR,
291  double *err,
292  unsigned start_site)
293 {
294
295  double E, errstep;
296  unsigned L = tntMpsLength(mps);
297
298
299  if (L-1 != start_site) E = tntMpsVarMinMpo2sSweep(mps, "R", chi, mpo, HeffL, HeffR, err, start_site, L-1);
300  E = tntMpsVarMinMpo2sSweep(mps, "L", chi, mpo, HeffL, HeffR, &errstep, L-1, 0);
301  if (0 != start_site) E = tntMpsVarMinMpo2sSweep(mps, "R", chi, mpo, HeffL, HeffR, err, 0, start_site);
302  *err += errstep;
303
304  return E;
305
306 }
tntNode tntNodeCopy(tntNode A)
Definition: tntNodeUtil.c:304
tntNode tntMpsVarMinMpo2sContract(tntNode theta, tntNetwork nwMV)
void tntNetworkFree(tntNetwork *nwp)
Definition: tntNetwork.c:118
void tntNodeJoin(tntNode A, tntLegLabel legA, tntNode B, tntLegLabel legB)
Definition: tntNodeConn.c:52
tntNode tntNodeFindLast(tntNetwork nw)
Definition: tntNodeInfo.c:68
double tntMpsVarMinMpo2sSweep(tntNetwork mps, tntLegLabel dir, int chi, tntNetwork mpo, tntNodeArray *betas, tntNodeArray *gammas, double *err, int start_site, int end_site)
Definition: tntMps2sDmrg.c:63
void tntNodeReplace(tntNode A, tntNode B)
Definition: tntNodeConn.c:145
tntNetwork tntMpsVarMinMpo2sBuild(tntNode beta, tntNode gamma, tntNode theta, tntNode tno)
tntNode tntNodeSVD(tntNode A, tntLegLabel Ulegs, tntLegLabel legUS, tntLegLabel legSU, tntLegLabel legSV, tntLegLabel legVS, int chi, double *err, tntLegLabel legmap)
void tntNodeFree(tntNode *A)
Definition: tntNodeUtil.c:275
unsigned tntMpsLength(tntNetwork wf)
Definition: tntMpsUtil.c:17
Definition: tnt.h:65
tntNode tntDmrg2sLocalOps(tntNode Al, tntNode Ar, tntNode Ol, tntNode Or, tntNode beta, tntNode gamma, int chi, double *errp, double *eigvp)
Definition: tntMps2sDmrg.c:184
tntNode tntNetworkMinSite(tntNode V, tntNetwork *nwMV, unsigned NM, tntNode(*eig_contract)(tntNode, tntNetwork), void(*eig_prep)(tntNode, tntNetwork), tntComplex *eigval)
Definition: tntNetwork.c:153
tntNode tntNodeFindConn(tntNode A, tntLegLabel legA)
Definition: tntNodeInfo.c:29
tntNode tntNodeContract(tntNode A, tntNode B, tntLegLabel legMapAC, tntLegLabel legMapBC)
double re
Definition: tnt.h:66
tntNode tntNodeFindFirst(tntNetwork nw)
Definition: tntNodeInfo.c:50
void tntMpsVarMinMpoUpdate(tntNode tnA, tntNode tno, tntLegLabel dir, unsigned j, tntNodeArray *Heff)
double tntMpsVarMinMpo2sStep(tntNetwork mps, int chi, tntNetwork mpo, tntNodeArray *HeffL, tntNodeArray *HeffR, double *err, unsigned start_site)
Definition: tntMps2sDmrg.c:283