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
tntMpoST2sc.c
1 /*
2 Authors: Sarah Al-Assam, Stephen Clark and Dieter Jaksch
3 $LastChangedDate: 2015-06-29 20:44:17 +0100 (Mon, 29 Jun 2015) $
4 (c) University of Oxford 2014
5 */
6 
12 /* Include the internal header for the TNT library */
13 #include "tntMpsInternal.h"
14 
27 void tntMpoPropST2scConnect(tntNetwork mpo,
28  tntNetwork PropB,
29  tntNetwork PropT)
30 {
31 
32  tntNode P, Pc, M; /* The current propagator, conjugate propogator and MPO nodes */
33  unsigned j, L; /* Site counter and length of MPO */
34 
35  /* make a copies of the propogators and find the first nodes */
36  L = tntMpoLength(mpo);
37 
38  if (PropB != NULL) {
39  PropB = tntNetworkCopy(PropB);
40  P = tntNodeFindFirst(PropB);
41  }
42 
43  /* Note for the conjugate propagator, a conjugate network copy is made which flips the directions of the legs but does not rename them */
44  /* Perform a leg mapping on all nodes to 'turn it upside down' */
45  if (PropT != NULL) {
46  PropT = tntNetworkConjCopy(PropT);
47  Pc = tntNodeFindFirst(PropT);
48  /* Map legs in pairs of propogators for each sweep direction */
49  for (j = 0; j < L-1; j++) {
50  tntNodeMapLegs(tntNodeFindConn(Pc,"D"),"UVDE=DEUV");
51  tntNodeMapLegs(Pc,"UVDE=DEUV");
52  Pc = tntNodeFindConn(Pc, "V");
53  }
54  Pc = tntNodeFindFirst(PropT);
55  }
56 
57  /* Find the first MPO node */
58  M = tntNodeFindFirst(mpo);
59 
60  /* Attach the top left leg of the first propagator to the first MP0 node */
61  if (PropB != NULL) tntNodeJoin(P, "U", M, "D");
62 
63  /* Attach the bottom left leg of the first conjugate propagator to the first MP0 node */
64  if (PropT != NULL) tntNodeJoin(Pc, "D", M, "U");
65 
66  /* Loop through the networks, joining top right leg of propagator to the downard leg of the next MPO node */
67  /* and joining bottom right leg of conjugate propagator to the upward leg of the next MPO node */
68  for (j = 0; j < L-1; j++) {
69 
70  /* Find the next MPS node */
71  M = tntNodeFindConn(M, "R");
72 
73  /* Connect it to the top right leg of the current propagator */
74  if (PropB != NULL) tntNodeJoin(P, "V", M, "D");
75 
76  /* Connect it to the bottom right leg of the current conjugate propagator */
77  if (PropT != NULL) tntNodeJoin(Pc, "E", M, "U");
78 
79  /* Go to the next propagators in the staircase */
80  if (PropB != NULL) P = tntNodeFindConn(P, "E");
81  if (PropT != NULL) Pc = tntNodeFindConn(Pc, "V");
82  }
83 
84  /* Get rid of connections to the start and end of the network */
85  if (PropB != NULL) tntNetworkToNodeGroup(&PropB,1);
86  if (PropT != NULL) tntNetworkToNodeGroup(&PropT,1);
87 
88  return;
89 
90 }
91 
92 
113 double tntMpoPropSTscContract(tntNetwork mpoProp,
114  int chi)
115 {
116 
117  tntNode Ml, Mr, S; /* The current pair of MPO nodes and the singular values from the SVD */
118  unsigned L, j; /* Number of nodes in the MPS and site counter */
119  int direction = 1; /* The direction of the sweep: 1 for right to left sweep, -1 for left to right sweep */
120  double err = 0; /* Total truncation error, truncation error for each SVD. */
121 
122  /* Get the number of nodes in the MPO */
123  L = tntMpoLength(mpoProp);
124 
125  /* Determine the direction of the staircase, and whether there are staircases in both directions */
126  Ml = tntNodeFindFirst(mpoProp);
127  Mr = tntNodeFindConn(Ml, "R");
128 
129  if (NULL != tntNodeFindConn(Ml, "U")) {
130  if (tntNodeFindConn(Ml, "U") != tntNodeFindConn(Mr, "U")) direction = -1;
131  } else if (NULL != tntNodeFindConn(Ml, "D")) {
132  if (tntNodeFindConn(Ml, "D") != tntNodeFindConn(Mr, "D")) direction = -1;
133  } else {
134  tntWarningPrint("tntMpoPropST2scContract is having no effect since no propogators have been passed"); /* NO_COVERAGE */
135  return 0.0; /* NO_COVERAGE */
136  } /* NO_COVERAGE */
137 
138  /* Check the direction of moving through the network, and set variables appropriately. */
139  if (1 == direction) {
140  /* Start at the first tensor in the network if moving right */
141  Ml = tntNodeFindFirst(mpoProp);
142  Mr = tntNodeFindConn(Ml,"R");
143 
144  /* Move through all the tensors in the chain perform the SVD and contraction steps */
145  for (j = 0; j < L-1; j++) {
146  /* Perform local operations to change apply the propagator, then factorise into two unitary nodes and a singular value matrix */
147  S = tntMpoPropTwoSite(&Ml, &Mr, chi, &err);
148 
149  /* Contract S with Mr and make the result the new left node */
150  Ml = tntNodeContract(S, Mr);
151 
152  /* Find the next node along */
153  Mr = tntNodeFindConn(Ml,"R");
154 
155  }
156 
157  } else {
158 
159  /* Start at the last tensor if moving left */
160  Mr = tntNodeFindLast(mpoProp);
161  Ml = tntNodeFindConn(Mr,"L");
162 
163  /* Move through all the tensors in the chain perform the SVD and contraction steps */
164  for (j = L-1; j > 0; j--) {
165 
166  /* Perform local operations to change apply the propagator, then factorise into two unitary nodes and a singular value matrix */
167  S = tntMpoPropTwoSite(&Ml, &Mr, chi, &err);
168 
169  /* Contract S with Ml and make the result the new right node */
170  Mr = tntNodeContract(S, Ml);
171 
172  /* Find the next left node */
173  Ml = tntNodeFindConn(Mr,"L");
174 
175  }
176  }
177  /* Return the error */
178  return err;
179 }
180 
185 tntNode tntMpoPropTwoSite(tntNode *Mlp,
186  tntNode *Mrp,
187  int chi,
188  double *err)
189 {
190  tntNode Ml=*Mlp, Mr=*Mrp; /* The current pair of MPO nodes */
191  tntNode S; /* The singular value matrix from the SVD */
192  tntNode theta; /* The node made by contracting the the two MPO nodes with the two site gate(s) */
193  tntNode P, Pc; /* The propagators to contract below and and above the MPO */
194  double errc; /* Truncation error from each SVD */
195 
196  /* Change the labels the right node */
197  tntNodeMapLegs(Mr,"UD=VE");
198 
199  /* Find the propagators */
200  P = tntNodeFindConn(Ml, "D");
201  Pc = tntNodeFindConn(Ml, "U");
202 
203  /* Contract the operators present with the time step */
204  if (NULL == P) theta = tntNodeListContract(NULL, Ml, Mr, Pc);
205  else if (NULL == Pc) theta = tntNodeListContract(NULL, Ml, Mr, P);
206  else theta = tntNodeListContract(NULL, Ml, Mr, P, Pc);
207 
208  /* SVD theta tensor and assign U to the left node */
209  Ml = tntNodeSVD(theta,"LUD","R","L","R","L",chi,&errc,"EV=DU");
210  *err += errc;
211 
212  /* Find S and the right node (VT from SVD) */
213  S = tntNodeFindConn(Ml,"R");
214  *Mrp = tntNodeFindConn(S,"R");
215  *Mlp = Ml;
216 
217  return S;
218 }
219 
236 double tntMpoPropST2scProduct(tntNetwork mpo,
237  tntNetwork PropB,
238  tntNetwork PropT,
239  int chi)
241 {
242 
243  /* Total truncation error */
244  double err;
245 
246  if (NULL == PropB && NULL == PropT) {
247  tntWarningPrint("tntMpoPropST2scProduct is having no effect since no propogators have been passed"); /* NO_COVERAGE */
248  return 0.0; /* NO_COVERAGE */
249  } /* NO_COVERAGE */
250 
251  /* Connect a copy of Prop to the mps */
252  tntMpoPropST2scConnect(mpo,PropB,PropT);
253 
254  /* Apply two contractions of a single staircase */
255  err = tntMpoPropSTscContract(mpo,chi);
256  err += tntMpoPropSTscContract(mpo,chi);
257 
258  /* Return the error */
259  return err;
260 
261 }
void tntNodeJoin(tntNode A, tntLegLabel legA, tntNode B, tntLegLabel legB)
Definition: tntNodeConn.c:52
tntNode tntNodeFindLast(tntNetwork nw)
Definition: tntNodeInfo.c:68
tntNetwork tntNetworkConjCopy(tntNetwork nw)
Definition: tntNetwork.c:19
void tntNodeMapLegs(tntNode A, tntLegLabel legmap)
Definition: tntNodeConn.c:125
tntNode tntNodeSVD(tntNode A, tntLegLabel Ulegs, tntLegLabel legUS, tntLegLabel legSU, tntLegLabel legSV, tntLegLabel legVS, int chi, double *err, tntLegLabel legmap)
tntNode tntMpoPropTwoSite(tntNode *Mlp, tntNode *Mrp, int chi, double *err)
Definition: tntMpoST2sc.c:185
double tntMpoPropST2scProduct(tntNetwork mpo, tntNetwork PropB, tntNetwork PropT, int chi)
Definition: tntMpoST2sc.c:236
void tntMpoPropST2scConnect(tntNetwork mpo, tntNetwork PropB, tntNetwork PropT)
Definition: tntMpoST2sc.c:27
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
tntNetwork tntNetworkCopy(tntNetwork nw)
Definition: tntNetwork.c:56
double tntMpoPropSTscContract(tntNetwork mpoProp, int chi)
Definition: tntMpoST2sc.c:113
void tntNetworkToNodeGroup(tntNetwork *nwp, int strip_connections)
Definition: tntNetwork.c:268