Tensor Network Theory Library  Beta release 1.2.1 A library of routines for performing TNT-based operations
tntMpsDmrgBlocks.c
1 /*
2  Authors: Sarah Al-Assam, Stephen Clark and Dieter Jaksch
3  Date: $LastChangedDate$
4  (c) University of Oxford 2013-2014
5  */
6
11 /* Include the header for the TNT MPS library */
12 #include "tntMpsInternal.h"
13
38 void tntMpsVarMinMpoUpdate(tntNode A,
39  tntNode O,
40  tntLegLabel dir,
41  unsigned j,
42  tntNodeArray *Oeff)
43 {
44
45  tntNode Af; /* The flipped (hermitian conjugate) of the current node A */
46  tntNode beta, gamma; /* The node that is the results of all previously contracted nodes from the right or left */
47
48  /* Make copies of the nodes for contracting */
49  A = tntNodeCopy(A);
50  O = tntNodeCopy(O);
51  Af = tntNodeCopy(A,1); /* Taking complex conjugate for the flipped node */
52
53  /* Set the correct site numbers and directions, depending on the direction of the update */
54  if ('L' == dir[0]) {
55
56  /* Free the node that is currently in place */
57  tntNodeFree(Oeff->vals+j-1);
58
59  /* Set gamma to be a copy the previous precontracted node */
60  gamma = tntNodeCopy(Oeff->vals[j]);
61
62  /* Now connect up these nodes to the relevant beta node */
63  tntNodeJoin(gamma,"L",A,"R"); /* Join it to the MPO node */
64  tntNodeJoin(gamma,"M",O,"R"); /* Join it to the MPO node */
65  tntNodeJoin(gamma,"N",Af,"R"); /* Join it to the flipped MPS node */
66
67  /* Connect up these nodes along the vertical direction */
68  tntNodeJoin(A,"D",O,"U");
69  tntNodeJoin(O,"D",Af,"D");
70
71  /* Now contract all these nodes and put the resulting new node in the array */
72  Oeff->vals[j-1] = tntNodeListContract("LMNRST",A,O,Af,gamma);
73
74  } else {
75
76  /* Free the node that is currently in the array */
77  tntNodeFree(Oeff->vals+j+1);
78
79  /* Set beta to be a copy the previous precontracted node */
80  beta = tntNodeCopy(Oeff->vals[j]);
81
82  /* Now connect up these nodes to the relevant beta node */
83  tntNodeJoin(beta,"R",A,"L"); /* Join it to the MPO node */
84  tntNodeJoin(beta,"S",O,"L"); /* Join it to the MPO node */
85  tntNodeJoin(beta,"T",Af,"L"); /* Join it to the flipped MPS node */
86
87  /* Connect up these nodes along the vertical direction */
88  tntNodeJoin(A,"D",O,"U");
89  tntNodeJoin(O,"D",Af,"D");
90
91  /* Now contract all these nodes:*/
92
93  /* Contract beta with all these nodes and put the resulting new node in the array */
94  Oeff->vals[j+1] = tntNodeListContract("LMNRST",beta,A,O,Af);
95  }
96 }
97
110 tntNetwork tntMpsVarMinMpo2sBuild(tntNode beta,
111  tntNode gamma,
112  tntNode theta,
113  tntNode O)
114 {
115
116  tntNetwork Oeff; /* Network representing the effective Hamiltonian */
117
118  /* Create the new network */
119  Oeff = tntNetworkCreate();
120
121  /* Assign all the pointers to copies of the nodes that they currently point to */
122  beta = tntNodeCopy(beta);
123  gamma = tntNodeCopy(gamma);
124  theta = tntNodeCopy(theta);
125  O = tntNodeCopy(O);
126
127  /* Insert the theta node in the network */
128  tntNodeInsertAtStart(theta, "L", "R", Oeff);
129
130  /* Insert the beta node at the start of the network */
131  tntNodeInsertAtStart(beta, "L", "R", Oeff);
132
133  /* Insert the gamma node at the end of the network */
134  tntNodeInsertAtEnd(gamma, "L", "R", Oeff);
135
136  /* Join O to theta on both physical legs*/
137  tntNodeJoin(theta, "D", O, "U");
138  tntNodeJoin(theta, "E", O, "V");
139
140  /* Join the left internal leg of O to the right middle leg of beta */
141  tntNodeJoin(O, "L", beta, "S");
142
143  /* Join the left internal leg of O to the left middle leg of gamma */
144  tntNodeJoin(O, "R", gamma, "M");
145
146  /* return the network */
147  return Oeff;
148
149 }
150
151
164 tntNetwork tntMpsVarMinMpo1sBuild(tntNode beta,
165  tntNode gamma,
166  tntNode A,
167  tntNode O)
168 {
169
170  tntNetwork Oeff; /* Network representing the effective Hamiltonian */
171
172  /* Create the new network */
173  Oeff = tntNetworkCreate();
174
175  /* Assign all the pointers to copies of the nodes that they currently point to */
176  beta = tntNodeCopy(beta);
177  gamma = tntNodeCopy(gamma);
178  A = tntNodeCopy(A);
179  O = tntNodeCopy(O);
180
181  /* Insert the theta node in the network */
182  tntNodeInsertAtStart(A, "L", "R", Oeff);
183
184  /* Insert the beta node at the start of the network */
185  tntNodeInsertAtStart(beta, "L", "R", Oeff);
186
187  /* Insert the gamma node at the end of the network */
188  tntNodeInsertAtEnd(gamma, "L", "R", Oeff);
189
190  /* Join O to theta */
191  tntNodeJoin(A, "D", O, "U");
192
193  /* Join the left internal leg of O to the right middle leg of beta */
194  tntNodeJoin(O, "L", beta, "S");
195
196  /* Join the left internal leg of O to the left middle leg of gamma */
197  tntNodeJoin(O, "R", gamma, "M");
198
199  /* return the network */
200  return Oeff;
201
202 }
203
204
219 tntNode tntMpsVarMinMpo2sContract(tntNode theta,
220  tntNetwork nwMV)
221 {
222  tntNetwork nwMVc; /* Copy of the network */
223  tntNode theta_o; /* The original node in the MPS */
224  tntNode theta_up; /* The updated node */
225  tntNode beta, gamma; /* The nodes that are the result of all previously contracted nodes from the left or right respectively */
226  tntNode O; /* The nodes representing the operator for these two sites in the Hamiltonian. */
227
228  /* Use a copy of the original network, so that the original network is unchanged by the function */
229  nwMVc = tntNetworkCopy(nwMV);
230
231  /* Indentify the first node and the last node */
232  beta = tntNodeFindFirst(nwMVc);
233  gamma = tntNodeFindLast(nwMVc);
234
235  /* Turn the network to a group of nodes, do not strip connections as they may store QN info */
236  tntNetworkToNodeGroup(&nwMVc, 0);
237
238  /* Get rid of the singleton legs on beta and gamma */
239  tntNodeSqueeze(beta,"LMN");
240  tntNodeSqueeze(gamma,"RST");
241
242  /* Find the other nodes required */
243  theta_o = tntNodeFindConn(beta,"R");
244  O = tntNodeFindConn(theta_o, "D");
245
246  /* Make a copy of node to contract with Oeff */
247  theta_up = tntNodeCopy(theta);
248
249  /* Replace this in the network to be contracted */
250  tntNodeReplace(theta_o,theta_up);
251
252  /* Delete the original node */
253  tntNodeFree(&theta_o);
254
255  /* Contract the nodes in the network */
256  theta_o = tntNodeListContract("LRDE", beta, gamma, O, theta_up);
257
258  /* Return the updated node */
259  return theta_o;
260
261 }
262
277 tntNode tntMpsVarMinMpo1sContract(tntNode A,
278  tntNetwork nwMV)
279 {
280  tntNetwork nwMVc; /* Copy of the network */
281  tntNode A_o; /* The original node in the MPS */
282  tntNode A_up; /* The updated node */
283  tntNode beta, gamma; /* The nodes that are the result of all previously contracted nodes from the left or right respectively */
284  tntNode O; /* The nodes representing the operator for these two sites in the Hamiltonian. */
285
286  /* Use a copy of the original network, so that the original network is unchanged by the function */
287  nwMVc = tntNetworkCopy(nwMV);
288
289  /* Indentify the first node and the last node */
290  beta = tntNodeFindFirst(nwMVc);
291  gamma = tntNodeFindLast(nwMVc);
292
293  /* Turn the network to a group of nodes, do not strip connections as they may store QN info */
294  tntNetworkToNodeGroup(&nwMVc, 0);
295
296  /* Get rid of the singleton legs on beta and gamma */
297  tntNodeSqueeze(beta,"LMN");
298  tntNodeSqueeze(gamma,"RST");
299
300  /* Find the other nodes required */
301  A_o = tntNodeFindConn(beta,"R");
302  O = tntNodeFindConn(A_o, "D");
303
304  /* Make a copy of node to contract with Oeff */
305  A_up = tntNodeCopy(A);
306
307  /* Replace this in the network to be contracted */
308  tntNodeReplace(A_o,A_up);
309
310  /* Delete the original node */
311  tntNodeFree(&A_o);
312
313  /* Contract the nodes in the network */
314  A_o = tntNodeListContract("LRD", beta, gamma, O, A_up);
315
316  /* Return the updated node */
317  return A_o;
318
319 }
320
324 double tntMpsVarMinMpo1sFullContract(tntNode beta,
325  tntNode gamma,
326  tntNode A,
327  tntNode O)
328 {
329  double E; /* Result of the contraction */
330  tntNode Ac; /* Conjugate of A */
331
332  /* Take copies */
333  A = tntNodeCopy(A);
334  Ac = tntNodeCopyConj(A, 1);
335  O = tntNodeCopy(O);
336  beta = tntNodeCopy(beta);
337  gamma = tntNodeCopy(gamma);
338
339  /* First contract */
340  tntNodeJoin(beta,"R", A, "L");
341  tntNodeJoin(beta,"S", O, "L");
342  tntNodeJoin(beta,"T", Ac, "L");
343  tntNodeJoin(A,"D", O, "U");
344  tntNodeJoin(Ac,"D", O, "D");
345  beta = tntNodeListContract("LMNRST", beta, A, O, Ac);
346
347  /* Second contract */
348  tntNodeJoin(beta,"RST",gamma,"LMN");
349  beta = tntNodeContract(beta,gamma);
350
351  /* Get the remaining element */
353
354  tntNodeFree(&beta);
355
356  return E;
357 }
double tntComplexToReal(tntComplex var)
Definition: tntUtil.c:108
tntNode tntNodeCopy(tntNode A)
Definition: tntNodeUtil.c:304
tntNode tntMpsVarMinMpo2sContract(tntNode theta, tntNetwork nwMV)
void tntNodeJoin(tntNode A, tntLegLabel legA, tntNode B, tntLegLabel legB)
Definition: tntNodeConn.c:52
tntNetwork tntNetworkCreate(void)
Definition: tntNetwork.c:92
tntNode tntNodeFindLast(tntNetwork nw)
Definition: tntNodeInfo.c:68
void tntNodeSqueeze(tntNode A, tntLegLabel squeezeLegs)
Definition: tntNodeConn.c:292
tntNetwork tntMpsVarMinMpo1sBuild(tntNode beta, tntNode gamma, tntNode A, tntNode O)
void tntNodeInsertAtEnd(tntNode I, tntLegLabel legIlast, tntLegLabel legInwend, tntNetwork nw)
Definition: tntNodeConn.c:252
void tntNodeReplace(tntNode A, tntNode B)
Definition: tntNodeConn.c:145
tntNetwork tntMpsVarMinMpo2sBuild(tntNode beta, tntNode gamma, tntNode theta, tntNode O)
void tntNodeFree(tntNode *A)
Definition: tntNodeUtil.c:275
tntNode tntMpsVarMinMpo1sContract(tntNode A, tntNetwork nwMV)
tntNode tntNodeCopyConj(tntNode A, int conj)
Definition: tntNodeUtil.c:319
tntNode tntNodeFindConn(tntNode A, tntLegLabel legA)
Definition: tntNodeInfo.c:29
tntNode tntNodeContract(tntNode A, tntNode B, tntLegLabel legMapAC, tntLegLabel legMapBC)
tntNode tntNodeFindFirst(tntNetwork nw)
Definition: tntNodeInfo.c:50
void tntNodeInsertAtStart(tntNode I, tntLegLabel legInwstart, tntLegLabel legIfirst, tntNetwork nw)
Definition: tntNodeConn.c:213
tntNetwork tntNetworkCopy(tntNetwork nw)
Definition: tntNetwork.c:56
void tntMpsVarMinMpoUpdate(tntNode A, tntNode O, tntLegLabel dir, unsigned j, tntNodeArray *Oeff)
double tntMpsVarMinMpo1sFullContract(tntNode beta, tntNode gamma, tntNode A, tntNode O)
tntComplex tntNodeGetFirstEl(tntNode A)
Definition: tntNodeInfo.c:86
void tntNetworkToNodeGroup(tntNetwork *nwp, int strip_connections)
Definition: tntNetwork.c:268