Tensor Network Theory Library  Beta release 1.2.1
A library of routines for performing TNT-based operations
 All Data Structures Functions Variables Groups Pages
tntMpsMpoMps.c
1 /*
2 Authors: Sarah Al-Assam, Stephen Clark and Dieter Jaksch
3 Date: $LastChangedDate$
4 (c) University of Oxford 2014
5 */
6 
7 
8 /* Include the internal header for the TNT library */
9 #include "tntMpsInternal.h"
10 
11 
25 tntNetwork tntMpsMpoMpsConnect(tntNetwork mps,
26  tntNetwork mpo)
27 {
28 
29  tntNetwork sandwich; /* The network representing MPS-MPO-MPS */
30  tntNode A, Af; /* The current node A of the MPS and the flipped (hermitian conjugate) of the current node Af */
31  tntNode O, Oc, O_prev=NULL; /* The current and previous operator O in the the MPO */
32  unsigned L; /* Length of system */
33 
34  /* First check that the MPS and the MPO have the same number of terms */
35  L = tntMpsLength(mps);
36 
37  if (tntMpsLength(mpo) != L) {
38  tntErrorPrint("Cannot connect the MPS to the MPO as there are not the same number of nodes in the two networks|" /* NO_COVERAGE */
39  "MPS contains %d nodes, MPO contains %d nodes",L,tntMpsLength(mpo)); /* NO_COVERAGE */
40  } /* NO_COVERAGE */
41 
42  sandwich = tntNetworkCopy(mps); /* Set the network to be a copy of the original wave function */
43 
44  tntMpsMpsConnect(sandwich,sandwich); /* Connect the network to the complex conjugate of itself */
45 
46  /* Find the nodes corresponding to site 0 */
47  A = tntNodeFindFirst(sandwich);
48  O = tntNodeFindFirst(mpo);
49  Af = tntNodeFindConn(A, "D");
50 
51  /* Now loop through all sites, insterting a copy of the MPO term between the wave function and its complex conjugate */
52  while (1) {
53 
54  /* Make a copy of the relevant term */
55  Oc = tntNodeCopy(O);
56 
57  /* Insert the copy of the current term of the MPO in the network */
58  tntNodeInsert(Oc,"U","D",A,"D",Af,"U");
59 
60  /* Join to the previous MPO term, if it exists */
61  if (NULL != O_prev) {
62  tntNodeJoin(O_prev, "R", Oc, "L");
63  }
64 
65  /* Find the next group of sites if they exist, or exit the loop if the last site has been reached */
66  if (A == tntNodeFindLast(sandwich)) {
67  break;
68  } else {
69  A = tntNodeFindConn(A, "R");
70  Af = tntNodeFindConn(A, "D");
71  O = tntNodeFindConn(O, "R");
72 
73  /* Set the current MPO term in the new network to the previous term */
74  O_prev = Oc;
75  }
76  }
77 
78  return sandwich;
79 }
80 
94 tntComplex tntMpsMpoMpsContract(tntNetwork sandwich)
95 {
96  tntNode A, Af; /* The current node of the MPS and the flipped (hermitian conjugate) of the current node */
97  tntNode O; /* The node representing the operator tno on site j of the current term in the MPO */
98  tntNode beta; /* The node that is the results of all previously contracted nodes from the left */
99  tntComplex contracted; /* The scalar value of the contracted network */
100  unsigned L, j; /* The length of the MPS network, site counter */
101 
102  /* Find the length of the network */
103  L = tntMpsLength(sandwich);
104 
105  /* ------ contracting from the left to the right to result in one node remaining (which should have size 1) ---- */
106 
107  /* Find the nodes corresponding to site 0 */
108  A = tntNodeFindFirst(sandwich);
109  O = tntNodeFindConn(A, "D");
110  Af = tntNodeFindConn(O, "D");
111 
112  /* Contract these three nodes to find beta */
113  beta = tntNodeListContract("LRMSNT", A, O, Af);
114 
115  /* Now loop through the network from left to right performing contractions */
116  for (j = 1; j < L; j++) {
117 
118  /* Find the next nodes along */
119  A = tntNodeFindConn(beta, "R");
120  O = tntNodeFindConn(beta, "S");
121  Af = tntNodeFindConn(beta, "T");
122 
123  /* Contract beta with these three nodes */
124  beta = tntNodeListContract("LMNRST",beta,A,O,Af);
125 
126  }
127 
128  /* Get the value in the tensor */
129  contracted = tntNodeGetFirstEl(beta);
130 
131  /* Free the network */
132  tntNetworkFree(&sandwich);
133 
134  /* return the expectation value */
135  return contracted;
136 
137 }
138 
171 void tntMpsMpoMpsInitOrth(tntNetwork mps,
172  tntNetwork mpo,
173  tntNodeArray *betas,
174  tntNodeArray *gammas)
175 {
176  tntNetwork Ofull; /* The full MPS-MPO-MPS network */
177  tntNode A, Af; /* The current node A of the MPS and the flipped (hermitian conjugate) of the current node Af */
178  tntNode O; /* The current MPO node */
179  tntNode beta, gamma; /* The node that is the results of all previously contracted nodes from the right and left */
180  tntNode eye; /* Identity node having one element to act as terminating node */
181  tntComplexArray eyevals;/* Values for the identity node to act as termninating node */
182  int L, j; /* the length of the MPS network and variable used for looping */
183 
184 
185  /* Create the required identity node: it will have the same form as a beta or gamma node, but all legs will have dimension 1, and the value of it will be 1. */
186  eyevals = tntComplexArrayAlloc(1);
187  eyevals.vals[0].re = 1.0;
188  eye = tntNodeCreate(&eyevals, "LMNRST");
189  /* Free the array values */
190  tntComplexArrayFree(&eyevals);
191 
192  /* Find the length of the network */
193  L = (int) tntMpsLength(mps);
194 
195  /* ------ First start contracting from the left to the right to form the nodes required for beta ---- */
196 
197  if (NULL != betas) {
198  *betas = tntNodeArrayAlloc(L);
199 
200  /* Put the orthogonality centry on the last site */
201  tntMpsOrth(mps,L-1);
202 
203  /* Create the full network */
204  Ofull = tntMpsMpoMpsConnect(mps,mpo);
205 
206  /* Find the MPS node, operator and flipped node corresponding to site 0 */
207  A = tntNodeFindFirst(Ofull);
208  O = tntNodeFindConn(A, "D");
209  Af = tntNodeFindConn(O, "D");
210 
211  /* Let beta be equal to the identity node */
212  beta = tntNodeCopy(eye);
213 
214  /* ----------------- SETTING QN INFO HERE ---------------- */
215  /* Put quantum number info (all zeros) on the legs of the node */
216  if (tntSymmTypeGet()) {
217  /* Set the quantum numbers for the identity node. */
218  tntNodeSetQN(beta,"L",NULL,TNT_QN_IN);
219  tntNodeSetQN(beta,"M",NULL,TNT_QN_IN);
220  tntNodeSetQN(beta,"N",NULL,TNT_QN_IN);
221  tntNodeSetQN(beta,"R",NULL,TNT_QN_IN);
222  tntNodeSetQN(beta,"S",NULL,TNT_QN_IN);
223  tntNodeSetQN(beta,"T",NULL,TNT_QN_IN);
224  }
225  /* ----------------- END OF SETTING QN INFO ----------------- */
226 
227  /* Insert a copy of the identity node at the start of the network and join to the other nodes */
228  tntNodeInsertAtStart(beta,"L","R",Ofull);
229  tntNodeJoin(beta,"S",O,"L");
230  tntNodeJoin(beta,"T",Af,"L");
231 
232  /* Let beta be the first element in the array */
233  betas->vals[0] = tntNodeCopy(beta);
234 
235  /* Now loop through the network from left to right performing contractions */
236  for (j = 1; j < L; j++) {
237 
238  /* Contract beta with the MPS node, operator, and flipped MPS node corresponding to the next site */
239  beta = tntNodeListContract("LMNRST", beta, A, O, Af);
240 
241  /* Copy the resulting node to the array */
242  betas->vals[j] = tntNodeCopy(beta);
243 
244  /* Find the three nodes that belong to the next site along */
245  A = tntNodeFindConn(beta, "R");
246  O = tntNodeFindConn(beta, "S");
247  Af = tntNodeFindConn(beta, "T");
248 
249  }
250 
251  /* Free the network */
252  tntNetworkFree(&Ofull);
253  }
254 
255 
256  /* ------ Now contract from right to left to form the nodes required for gamma ---- */
257  /* Put the orthogonality centre on the first site */
258  tntMpsOrth(mps,0);
259 
260  if (NULL != gammas) {
261  *gammas = tntNodeArrayAlloc(L);
262 
263  /* Create the full network */
264  Ofull = tntMpsMpoMpsConnect(mps,mpo);
265 
266  /* Find the MPS node, operator and flipped MPS node corresponding to site L-1 */
267  A = tntNodeFindLast(Ofull);
268  O = tntNodeFindConn(A, "D");
269  Af = tntNodeFindConn(O, "D");
270 
271  /* Let gamma be equal to the identity node */
272  gamma = tntNodeCopy(eye);
273 
274  /* ----------------- SETTING QN INFO HERE ---------------- */
275  /* Put quantum number info (all zeros) on the legs of the node if they are present on the MPO and MPS */
276  if (tntSymmTypeGet()) {
277 
278  tntIntArray legqn; /* Contains the quantum number for the relevant leg */
279 
280  /* quantum numbers for the first two legs come from the last MPS */
281  legqn = tntNodeGetQN(A,"R");
282  if (legqn.sz > 0) {
283  tntNodeSetQN(gamma,"R",&legqn,tntNodeGetLegDir(A,"R"));
284  tntNodeSetQN(gamma,"L",&legqn,-1*tntNodeGetLegDir(A,"R"));
285  tntIntArrayFree(&legqn);
286  }
287 
288  /* quantum numbers for the first middle legs come from the last MPO */
289  legqn = tntNodeGetQN(O,"R");
290  if (legqn.sz > 0) {
291  tntNodeSetQN(gamma,"S",&legqn,tntNodeGetLegDir(O,"R"));
292  tntNodeSetQN(gamma,"M",&legqn,-1*tntNodeGetLegDir(O,"R"));
293  tntIntArrayFree(&legqn);
294  }
295 
296  /* quantum numbers for the last two legs come from the last flipped MPS */
297  legqn = tntNodeGetQN(Af,"R");
298  if (legqn.sz > 0) {
299  tntNodeSetQN(gamma,"T",&legqn,tntNodeGetLegDir(Af,"R"));
300  tntNodeSetQN(gamma,"N",&legqn,-1*tntNodeGetLegDir(Af,"R"));
301  tntIntArrayFree(&legqn);
302  }
303  }
304  /* ----------------- END OF SETTING QN INFO ----------------- */
305 
306  /* Insert a copy of the identity node at the end of the network */
307  tntNodeInsertAtEnd(gamma,"L","R",Ofull); /* insert between terminating node and first MPS node */
308  tntNodeJoin(gamma,"M",O,"R"); /* Join it to the MPO node */
309  tntNodeJoin(gamma,"N",Af,"R"); /* Join it to the flipped MPS node */
310 
311  /* Let gamma be the last element in the array */
312  gammas->vals[L-1] = tntNodeCopy(gamma);
313 
314  /* Now loop through the network from right to left performing contractions */
315  for (j = L-2; j >= 0; j--) {
316 
317  /* Contract beta with the MPS node, operator, and flipped MPS node corresponding to the next site left */
318  gamma = tntNodeListContract("RSTLMN", gamma, A, O, Af);
319 
320  /* Copy the resulting node to the array */
321  gammas->vals[j] = tntNodeCopy(gamma);
322 
323  /* Find the next three nodes belonging to the site to the left */
324  A = tntNodeFindConn(gamma, "L");
325  O = tntNodeFindConn(gamma, "M");
326  Af = tntNodeFindConn(gamma, "N");
327  }
328 
329  /* Free unrequired objects */
330  tntNetworkFree(&Ofull);
331  }
332 
333  tntNodeFree(&eye);
334 }
335 
336 
362 void tntMpsMpoMpsInit(tntNetwork mps,
363  tntNetwork mpo,
364  tntNodeArray *betas,
365  tntNodeArray *gammas)
366 {
367  tntNetwork Ofull; /* The full MPS-MPO-MPS network */
368  tntNode A, Af; /* The current node A of the MPS and the flipped (hermitian conjugate) of the current node Af */
369  tntNode O; /* The current MPO node */
370  tntNode beta, gamma; /* The node that is the results of all previously contracted nodes from the right and left */
371  tntNode eye; /* Identity node having one element to act as terminating node */
372  tntComplexArray eyevals;/* Values for the identity node to act as termninating node */
373  int L, j; /* the length of the MPS network and variable used for looping */
374 
375 
376  /* Create the required identity node: it will have the same form as a beta or gamma node, but all legs will have dimension 1, and the value of it will be 1. */
377  eyevals = tntComplexArrayAlloc(1);
378  eyevals.vals[0].re = 1.0;
379  eye = tntNodeCreate(&eyevals, "LMNRST");
380  /* Free the array values */
381  tntComplexArrayFree(&eyevals);
382 
383  /* Find the length of the network */
384  L = (int) tntMpsLength(mps);
385 
386  /* ------ First start contracting from the left to the right to form the nodes required for beta ---- */
387 
388  if (NULL != betas) {
389  *betas = tntNodeArrayAlloc(L);
390 
391  /* Create the full network */
392  Ofull = tntMpsMpoMpsConnect(mps,mpo);
393 
394  /* Find the MPS node, operator and flipped node corresponding to site 0 */
395  A = tntNodeFindFirst(Ofull);
396  O = tntNodeFindConn(A, "D");
397  Af = tntNodeFindConn(O, "D");
398 
399  /* Let beta be equal to the identity node */
400  beta = tntNodeCopy(eye);
401 
402  /* ----------------- SETTING QN INFO HERE ---------------- */
403  /* Put quantum number info (all zeros) on the legs of the node */
404  if (tntSymmTypeGet()) {
405  /* Set the quantum numbers for the identity node. */
406  tntNodeSetQN(beta,"L",NULL,TNT_QN_IN);
407  tntNodeSetQN(beta,"M",NULL,TNT_QN_IN);
408  tntNodeSetQN(beta,"N",NULL,TNT_QN_IN);
409  tntNodeSetQN(beta,"R",NULL,TNT_QN_IN);
410  tntNodeSetQN(beta,"S",NULL,TNT_QN_IN);
411  tntNodeSetQN(beta,"T",NULL,TNT_QN_IN);
412  }
413  /* ----------------- END OF SETTING QN INFO ----------------- */
414 
415  /* Insert a copy of the identity node at the start of the network and join to the other nodes */
416  tntNodeInsertAtStart(beta,"L","R",Ofull);
417  tntNodeJoin(beta,"S",O,"L");
418  tntNodeJoin(beta,"T",Af,"L");
419 
420  /* Let beta be the first element in the array */
421  betas->vals[0] = tntNodeCopy(beta);
422 
423  /* Now loop through the network from left to right performing contractions */
424  for (j = 1; j < L; j++) {
425 
426  /* Contract beta with the MPS node, operator, and flipped MPS node corresponding to the next site */
427  beta = tntNodeListContract("LMNRST", beta, A, O, Af);
428 
429  /* Copy the resulting node to the array */
430  betas->vals[j] = tntNodeCopy(beta);
431 
432  /* Find the three nodes that belong to the next site along */
433  A = tntNodeFindConn(beta, "R");
434  O = tntNodeFindConn(beta, "S");
435  Af = tntNodeFindConn(beta, "T");
436 
437  }
438 
439  /* Free the network */
440  tntNetworkFree(&Ofull);
441  }
442 
443 
444  /* ------ Now contract from right to left to form the nodes required for gamma ---- */
445 
446  if (NULL != gammas) {
447  *gammas = tntNodeArrayAlloc(L);
448 
449  /* Create the full network */
450  Ofull = tntMpsMpoMpsConnect(mps,mpo);
451 
452  /* Find the MPS node, operator and flipped MPS node corresponding to site L-1 */
453  A = tntNodeFindLast(Ofull);
454  O = tntNodeFindConn(A, "D");
455  Af = tntNodeFindConn(O, "D");
456 
457  /* Let gamma be equal to the identity node */
458  gamma = tntNodeCopy(eye);
459 
460  /* ----------------- SETTING QN INFO HERE ---------------- */
461  /* Put quantum number info (all zeros) on the legs of the node if they are present on the MPO and MPS */
462  if (tntSymmTypeGet()) {
463 
464  tntIntArray legqn; /* Contains the quantum number for the relevant leg */
465 
466  /* quantum numbers for the first two legs come from the last MPS */
467  legqn = tntNodeGetQN(A,"R");
468  if (legqn.sz > 0) {
469  tntNodeSetQN(gamma,"R",&legqn,tntNodeGetLegDir(A,"R"));
470  tntNodeSetQN(gamma,"L",&legqn,-1*tntNodeGetLegDir(A,"R"));
471  tntIntArrayFree(&legqn);
472  }
473 
474  /* quantum numbers for the first middle legs come from the last MPO */
475  legqn = tntNodeGetQN(O,"R");
476  if (legqn.sz > 0) {
477  tntNodeSetQN(gamma,"S",&legqn,tntNodeGetLegDir(O,"R"));
478  tntNodeSetQN(gamma,"M",&legqn,-1*tntNodeGetLegDir(O,"R"));
479  tntIntArrayFree(&legqn);
480  }
481 
482  /* quantum numbers for the last two legs come from the last flipped MPS */
483  legqn = tntNodeGetQN(Af,"R");
484  if (legqn.sz > 0) {
485  tntNodeSetQN(gamma,"T",&legqn,tntNodeGetLegDir(Af,"R"));
486  tntNodeSetQN(gamma,"N",&legqn,-1*tntNodeGetLegDir(Af,"R"));
487  tntIntArrayFree(&legqn);
488  }
489  }
490  /* ----------------- END OF SETTING QN INFO ----------------- */
491 
492  /* Insert a copy of the identity node at the end of the network */
493  tntNodeInsertAtEnd(gamma,"L","R",Ofull); /* insert between terminating node and first MPS node */
494  tntNodeJoin(gamma,"M",O,"R"); /* Join it to the MPO node */
495  tntNodeJoin(gamma,"N",Af,"R"); /* Join it to the flipped MPS node */
496 
497  /* Let gamma be the last element in the array */
498  gammas->vals[L-1] = tntNodeCopy(gamma);
499 
500  /* Now loop through the network from right to left performing contractions */
501  for (j = L-2; j >= 0; j--) {
502 
503  /* Contract beta with the MPS node, operator, and flipped MPS node corresponding to the next site left */
504  gamma = tntNodeListContract("RSTLMN", gamma, A, O, Af);
505 
506  /* Copy the resulting node to the array */
507  gammas->vals[j] = tntNodeCopy(gamma);
508 
509  /* Find the next three nodes belonging to the site to the left */
510  A = tntNodeFindConn(gamma, "L");
511  O = tntNodeFindConn(gamma, "M");
512  Af = tntNodeFindConn(gamma, "N");
513  }
514 
515  /* Free unrequired objects */
516  tntNetworkFree(&Ofull);
517  }
518 
519  tntNodeFree(&eye);
520 }
521 
522 
542  tntNetwork mpo)
543 {
544  tntNetwork sandwich; /* The full MPS-MPO-MPS network */
545 
546  /* Create the full network */
547  sandwich = tntMpsMpoMpsConnect(mps,mpo);
548 
549  /* Contract the full network */
550  return tntMpsMpoMpsContract(sandwich);
551 }
552 
553 
554 
575  tntNetwork mpo,
576  unsigned site_left,
577  unsigned site_right,
578  tntNode beta,
579  tntNode gamma)
580 {
581  tntNode A, O; /* The current mps, mpo, and flipped mps nodes */
582  tntNode Ac, Oc, Af; /* Copies and flipped copies of these nodes */
583  tntNode alpha; /* The node that is the result of the network contraction */
584  unsigned L, j, d; /* Length, the current site number, leg dimension */
585  tntComplex result; /* The result of the contraction */
586 
587  /* Determine the length of the MPS. */
588  L = tntMpsLength(mps);
589 
590  /* Check site_left is not more than site_right */
591  if (site_left > site_right) tntErrorPrint("site_left (%d) is greater than site_right (%d)",site_left, site_right); /* NO_COVERAGE */
592 
593  /* Check site_left is not too big */
594  if (site_left >= L) tntErrorPrint("site_left (%d) is more than or equal to the length of the MPS (%d)", site_right, L); /* NO_COVERAGE */
595 
596  /* Check site_right is not too big */
597  if (site_right >= L) tntErrorPrint("site_right (%d) is more than or equal to the length of the MPS (%d)", site_right, L); /* NO_COVERAGE */
598 
599  A = tntNodeFindFirst(mps);
600  O = tntNodeFindFirst(mpo);
601 
602  /* Move to the correct node i.e. node with index = site_left*/
603  for (j = 1; j <= site_left; j++) {
604  A = tntNodeFindConn(A,"R");
605  O = tntNodeFindConn(O,"R");
606  }
607 
608  /* Perform the first contraction */
609  Ac = tntNodeCopy(A);
610  Af = tntNodeCopy(A,1);
611  Oc = tntNodeCopy(O);
612  tntNodeJoin(Ac,"D",Oc,"U");
613  tntNodeJoin(Oc,"D",Af,"D");
614 
615  if (beta != NULL) {
616  alpha = tntNodeCopy(beta);
617  tntNodeJoin(alpha,"R",Ac,"L");
618  tntNodeJoin(alpha,"S",Oc,"L");
619  tntNodeJoin(alpha,"T",Af,"L");
620 
621  if (site_left == site_right) {
622 
623  if (NULL == gamma) {
624  d = tntNodeGetLegDim(O,"R");
625  if (d != 1) tntErrorPrint("Terminating with identity is only allowed if the MPO has internal dimension 1|Here leg 'R' of operator %d of the MPO has dimension %d",site_right,d); /* NO_COVERAGE */
626 
627  tntNodeJoin(Ac,"R",Af,"R");
628  alpha = tntNodeListContract("LMNS",alpha,Ac,Oc,Af);
629  } else {
630  gamma = tntNodeCopy(gamma);
631 
632  alpha = tntNodeListContract("LMNRST",alpha,Ac,Oc,Af);
633 
634  tntNodeJoin(alpha,"R",gamma,"L");
635  tntNodeJoin(alpha,"S",gamma,"M");
636  tntNodeJoin(alpha,"T",gamma,"N");
637 
638  alpha = tntNodeContract(gamma,beta);
639  }
640  } else {
641  alpha = tntNodeListContract("LMNRST",alpha,Ac,Oc,Af);
642  }
643  } else {
644  /* get internal leg dimension of MPO node */
645  d = tntNodeGetLegDim(O,"L");
646 
647  /* Check we can use identity to terminate */
648  if (d != 1) tntErrorPrint("Terminating with identity is only allowed if the MPO has internal dimension 1|Here leg 'L' of operator %d of the MPO has dimension %d",site_left,d); /* NO_COVERAGE */
649 
650  tntNodeJoin(Ac,"L",Af,"L");
651  alpha = tntNodeListContract("RMST",Ac,Oc,Af);
652 
653  /* Add extra singleton legs to make sure the nodes look the same in all cases */
654  tntNodeAddLeg(alpha,"LN");
655  }
656 
657  /* Now keep contracting nodes until the node before site-right is reached */
658  for (j = site_left+1; j <= site_right; j++) {
659  A = tntNodeFindConn(A,"R");
660  O = tntNodeFindConn(O,"R");
661 
662  Ac = tntNodeCopy(A);
663  Af = tntNodeCopy(A,1);
664  Oc = tntNodeCopy(O);
665 
666  tntNodeJoin(Ac,"D",Oc,"U");
667  tntNodeJoin(Oc,"D",Af,"D");
668 
669  tntNodeJoin(alpha,"R",Ac,"L");
670  tntNodeJoin(alpha,"S",Oc,"L");
671  tntNodeJoin(alpha,"T",Af,"L");
672 
673  if (j != site_right) {
674  alpha = tntNodeListContract("LMNRST",alpha,Ac,Oc,Af);
675  } else {
676  if (gamma != NULL) {
677  gamma = tntNodeCopy(gamma);
678 
679  alpha = tntNodeListContract("LMNRST",alpha,Ac,Oc,Af);
680 
681  tntNodeJoin(alpha,"R",gamma,"L");
682  tntNodeJoin(alpha,"S",gamma,"M");
683  tntNodeJoin(alpha,"T",gamma,"N");
684 
685  alpha = tntNodeContract(gamma,beta);
686  } else {
687  /* get internal leg dimension of MPO node */
688  d = tntNodeGetLegDim(O,"R");
689 
690  /* Check we can use identity to terminate */
691  if (d != 1) tntErrorPrint("Terminating with identity is only allowed if the MPO has internal dimension 1|Here leg 'R' of operator %d of the MPO has dimension %d",site_right,d); /* NO_COVERAGE */
692 
693  tntNodeJoin(Ac,"R",Af,"R");
694  alpha = tntNodeListContract("LMNS",alpha,Ac,Oc,Af);
695  }
696  }
697  }
698 
699  result = tntNodeGetFirstEl(alpha);
700 
701  tntNodeFree(&alpha);
702 
703  return result;
704 }
tntNode tntNodeCopy(tntNode A)
Definition: tntNodeUtil.c:304
void tntNodeSetQN(tntNode A, tntLegLabel legA, tntIntArray *qvals, int legdir)
Definition: tntNodeQN.c:37
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
void tntMpsMpoMpsInit(tntNetwork mps, tntNetwork mpo, tntNodeArray *betas, tntNodeArray *gammas)
Definition: tntMpsMpoMps.c:362
tntNodeArray tntNodeArrayAlloc(unsigned num_elems)
Definition: tntArray.c:428
void tntNodeInsertAtEnd(tntNode I, tntLegLabel legIlast, tntLegLabel legInwend, tntNetwork nw)
Definition: tntNodeConn.c:252
tntComplex tntMpsMpoMpsContract(tntNetwork sandwich)
Definition: tntMpsMpoMps.c:94
void tntMpsMpsConnect(tntNetwork mpsA, tntNetwork mpsB)
Definition: tntMpsMps.c:38
tntNetwork tntMpsMpoMpsConnect(tntNetwork mps, tntNetwork mpo)
Definition: tntMpsMpoMps.c:25
void tntNodeFree(tntNode *A)
Definition: tntNodeUtil.c:275
tntComplexArray tntComplexArrayAlloc(unsigned numrows, unsigned numcols)
Definition: tntArray.c:392
unsigned tntMpsLength(tntNetwork wf)
Definition: tntMpsUtil.c:17
void tntNodeInsert(tntNode I, tntLegLabel legIA, tntLegLabel legIB, tntNode A, tntLegLabel legA, tntNode B, tntLegLabel legB)
Definition: tntNodeConn.c:177
tntIntArray tntNodeGetQN(tntNode A, tntLegLabel legA)
Definition: tntNodeQN.c:155
Definition: tnt.h:65
void tntIntArrayFree(tntIntArray *arr)
Definition: tntArray.c:620
tntComplex tntMpsMpoMpsProduct(tntNetwork mps, tntNetwork mpo)
Definition: tntMpsMpoMps.c:541
void tntNodeAddLeg(tntNode A, tntLegLabel legA)
Definition: tntNodeConn.c:24
tntNode tntNodeFindConn(tntNode A, tntLegLabel legA)
Definition: tntNodeInfo.c:29
tntNode tntNodeContract(tntNode A, tntNode B, tntLegLabel legMapAC, tntLegLabel legMapBC)
tntNode tntNodeCreate(tntComplexArray *nodeVals, tntLegLabel leglabels, unsigned dimleg1, unsigned dim...)
Definition: tntNodeUtil.c:354
void tntComplexArrayFree(tntComplexArray *arr)
Definition: tntArray.c:650
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 tntMpsOrth(tntNetwork wf, unsigned orth_centre)
Definition: tntMpsOrth.c:36
void tntMpsMpoMpsInitOrth(tntNetwork mps, tntNetwork mpo, tntNodeArray *betas, tntNodeArray *gammas)
Definition: tntMpsMpoMps.c:171
int tntSymmTypeGet(void)
Definition: tntSys.c:498
unsigned tntNodeGetLegDim(tntNode A, tntLegLabel legA)
Definition: tntNodeInfo.c:246
int tntNodeGetLegDir(tntNode A, tntLegLabel legA)
Definition: tntNodeInfo.c:295
tntComplex tntNodeGetFirstEl(tntNode A)
Definition: tntNodeInfo.c:86
tntComplex tntMpsMpoMpsPartProduct(tntNetwork mps, tntNetwork mpo, unsigned site_left, unsigned site_right, tntNode beta, tntNode gamma)
Definition: tntMpsMpoMps.c:574