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
tntNetwork.c
1 /*
2 Authors: Sarah Al-Assam, Stephen Clark and Dieter Jaksch
3 $LastChangedDate: 2016-05-16 10:01:57 +0100 (Mon, 16 May 2016) $
4 (c) University of Oxford 2013
5  */
6 
7 #include "../headers/tnt_int.h"
8 #include "../headers/dec_public.h"
9 #include "../headers/dec_tnode.h"
10 #include "../headers/dec_network.h"
11 
19 tntNetwork tntNetworkConjCopy(tntNetwork nw)
20 {
21  struct tnetwork *tnw_copy; /* Pointer to network structure for the copy of the network */
22 
23  TNT_ERR_RET_DEFS /* return value from internal function */
24 
25  /* Allocate memory for the new network */
26  chk = tnw_copy = malloc(sizeof(struct tnetwork));
27  TNT_PUB_MEM_CHK /* NO_COVERAGE */
28 
29  /* Call the function for taking a copy of the network */
30  ret = _tnt_network_copy(nw->nw_start,nw->nw_end,&tnw_copy->nw_start,&tnw_copy->nw_end, 1);
31  TNT_PUB_ERR_CHK /* NO_COVERAGE */
32 
33  /* Copy over any Schmidt data (note values will all be real) */
34  if (NULL != nw->schmidt_vec) {
35  ret = _tnt_tnarr_copy(tnw_copy->schmidt_vec, nw->schmidt_vec);
36  TNT_PUB_ERR_CHK /* NO_COVERAGE */
37  } else {
38  tnw_copy->schmidt_vec = NULL;
39  }
40 
41  /* Set the flags of the terminating nodes */
42  nw->nw_start->flag = TNT_STARTNODE_FLAG;
43  nw->nw_end->flag = TNT_ENDNODE_FLAG;
44 
45  /* Return the pointer to the network structure */
46  return tnw_copy;
47 }
48 
49 
56 tntNetwork tntNetworkCopy(tntNetwork nw)
57 {
58  struct tnetwork *tnw_copy; /* Pointer to network structure for the copy of the network */
59 
60  TNT_ERR_RET_DEFS /* return value from internal function */
61 
62  /* Allocate memory for the new network */
63  chk = tnw_copy = malloc(sizeof(struct tnetwork));
64  TNT_PUB_MEM_CHK /* NO_COVERAGE */
65 
66  /* Call the function for taking a copy of the mps */
67  ret = _tnt_network_copy(nw->nw_start,nw->nw_end,&tnw_copy->nw_start,&tnw_copy->nw_end, 0);
68  TNT_PUB_ERR_CHK /* NO_COVERAGE */
69 
70  /* Set the flags of the terminating nodes */
71  nw->nw_start->flag = TNT_STARTNODE_FLAG;
72  nw->nw_end->flag = TNT_ENDNODE_FLAG;
73 
74  /* Copy over any Schmidt data */
75  if (NULL != nw->schmidt_vec) {
76  ret = _tnt_tnarr_copy(tnw_copy->schmidt_vec, nw->schmidt_vec);
77  TNT_PUB_ERR_CHK /* NO_COVERAGE */
78  } else {
79  tnw_copy->schmidt_vec = NULL;
80  }
81 
82  /* Return the pointer to the network structure */
83  return tnw_copy;
84 }
85 
92 tntNetwork tntNetworkCreate(void)
93 {
94  struct tnetwork *tnw; /* Pointer to network structure for the new of the network */
95  TNT_ERR_RET_DEFS
96 
97  /* Create the new network */
98  ret = _tnt_network_create(&tnw);
99  TNT_PUB_ERR_CHK /* NO_COVERAGE */
100 
101  /* Set the flags of the terminating nodes */
102  tnw->nw_start->flag = TNT_STARTNODE_FLAG;
103  tnw->nw_end->flag = TNT_ENDNODE_FLAG;
104 
105  /* Initialise pointer to vector for Schmidt data */
106  tnw->schmidt_vec = NULL;
107 
108  /* Return the pointer to the network structure */
109  return tnw;
110 }
111 
118 void tntNetworkFree(tntNetwork *nwp)
119 {
120  struct tnetwork *tnw = *nwp; /* dereferenced network pointer */
121  TNT_ERR_RET_DEFS /* return value from internal function */
122 
123  if (NULL == tnw) return;
124 
125  /* First call network_free, which frees every node in the network */
126  ret = _tnt_network_free(&(tnw->nw_start));
127  TNT_PUB_ERR_CHK /* NO_COVERAGE */
128 
129  /* Free any Schmidt data */
130  if (NULL != tnw->schmidt_vec) {
131  ret = _tnt_tnarr_free(tnw->schmidt_vec);
132  TNT_PUB_ERR_CHK /* NO_COVERAGE */
133 
134  free(tnw->schmidt_vec);
135  }
136 
137  /* Finally free the tnetwork structure itself */
138  free(tnw);
139 
140  /* Set the value to NULL */
141  *nwp = NULL;
142 
143 }
144 
153 tntNode tntNetworkMinSite(tntNode V,
154  tntNetwork *nwMV,
155  unsigned NM,
156  tntNode (*eig_contract)(tntNode, tntNetwork),
159  void (*eig_prep)(tntNode, tntNetwork),
161  tntComplex *eigval)
162 {
163 
164  struct tnode *eigNode;
165  TNT_ERR_RET_DEFS /* return value from internal function */
166 
167  ret = _tnt_network_eig(&eigNode, V, nwMV, NM, eig_contract, eig_prep, eigval);
168  TNT_PUB_ERR_CHK /* NO_COVERAGE */
169 
170  return eigNode;
171 }
172 
203 tntNetwork tntNetworkSplit(tntNetwork nw,
205  tntNode tnFirst_1,
206  tntLegLabel leg_start_1,
207  tntNode tnLast_1,
208  tntLegLabel leg_end_1,
210  tntNode tnFirst_2,
211  tntLegLabel leg_start_2,
212  tntNode tnLast_2,
213  tntLegLabel leg_end_2,
215  unsigned numSplit_1,
216  tntNode *tnSplit_1,
217  unsigned numSplit_2,
218  tntNode *tnSplit_2)
219 {
220  unsigned legid_start_1, legid_start_2, legid_end_1, legid_end_2;
221  struct tnetwork *tnw_2; /* Pointer to network structure for the second network */
222  TNT_ERR_RET_DEFS /* return value from internal function */
223 
224  /* Turn the leg labels into ids */
225  ret = _tnt_node_id_chartonum(&legid_start_1,leg_start_1[0]);
226  TNT_PUB_ERR_CHK /* NO_COVERAGE */
227  ret = _tnt_node_id_chartonum(&legid_start_2,leg_start_2[0]);
228  TNT_PUB_ERR_CHK /* NO_COVERAGE */
229  ret = _tnt_node_id_chartonum(&legid_end_1,leg_end_1[0]);
230  TNT_PUB_ERR_CHK /* NO_COVERAGE */
231  ret = _tnt_node_id_chartonum(&legid_end_2,leg_end_2[0]);
232  TNT_PUB_ERR_CHK /* NO_COVERAGE */
233 
234  /* Free the schmidt data on the network if it exists */
235  if (NULL != nw->schmidt_vec) {
236  ret = _tnt_tnarr_free(nw->schmidt_vec);
237  TNT_PUB_ERR_CHK /* NO_COVERAGE */
238 
239  free(nw->schmidt_vec);
240  nw->schmidt_vec = NULL;
241  }
242 
243  /* Call the network function */
244  ret = _tnt_network_split(nw, &tnw_2, tnFirst_1, legid_start_1, tnLast_1, legid_end_1, tnFirst_2, legid_start_2, tnLast_2, legid_end_2, numSplit_1, tnSplit_1, numSplit_2, tnSplit_2);
245  TNT_PUB_ERR_CHK /* NO_COVERAGE */
246 
247  /* Set the flags of the terminating nodes */
248  nw->nw_start->flag = TNT_STARTNODE_FLAG;
249  nw->nw_end->flag = TNT_ENDNODE_FLAG;
250 
251  /* Set the flags of the terminating nodes */
252  tnw_2->nw_start->flag = TNT_STARTNODE_FLAG;
253  tnw_2->nw_end->flag = TNT_ENDNODE_FLAG;
254 
255  tnw_2->schmidt_vec = NULL;
256 
257  return tnw_2;
258 
259 }
260 
268 void tntNetworkToNodeGroup(tntNetwork *nwp,
269  int strip_connections)
270 {
271  TNT_ERR_RET_DEFS /* return value from internal function */
272 
273  /* Free the schmidt data on the network if it exists */
274  if (NULL != (*nwp)->schmidt_vec) {
275  ret = _tnt_tnarr_free((*nwp)->schmidt_vec);
276  TNT_PUB_ERR_CHK /* NO_COVERAGE */
277 
278  free((*nwp)->schmidt_vec);
279  (*nwp)->schmidt_vec = NULL;
280  }
281 
282  /* Call the network function */
283  ret = _tnt_network_to_nodegroup(nwp, strip_connections);
284  TNT_PUB_ERR_CHK /* NO_COVERAGE */
285 
286  return;
287 
288 }
289 
290 
294 /*void tntNetworkSchmidtVecInit(tntNetwork nw,
295 // unsigned N,
296 // tntNode A)
297 // {
298 // TNT_ERR_RET_DEFS /* return value from internal function */
299 // unsigned loop;
300 //
301 // /* Check if schmidt data already exists */
302 // if (NULL != nw->schmidt_vec) {
303 // sprintf(tnt_err.errinfostr,"The Schmidt vectors have already been initialised"); /* NO_COVERAGE */
304 // sprintf(tnt_err.pubfuncname,__FUNCTION__); /* NO_COVERAGE */
305 // _tnt_print_error(); /* NO_COVERAGE */
306 // } /* NO_COVERAGE */
307 //
308 // chk = nw->schmidt_vec = malloc(sizeof(struct tn_arr));
309 // TNT_PUB_MEM_CHK /* NO_COVERAGE */
310 //
311 // ret = _tnt_tnarr_alloc(nw->schmidt_vec, N);
312 // TNT_PUB_ERR_CHK /* NO_COVERAGE */
313 //
314 // for (loop = 0; loop < N; loop++) {
315 // ret = _tnt_tnode_copy(nw->schmidt_vec->vals + loop, A, 0);
316 // TNT_PUB_ERR_CHK /* NO_COVERAGE */
317 // }
318 //
319 // return;
320 //
321 // }
322 
323 
329 // tntNode tntNetworkSchmidtVecGet(tntNetwork nw, /*!< The network */
330 // unsigned j) /*!< Site number to get schmidt vector for */
331 // {
332 // TNT_ERR_RET_DEFS /* return value from internal function */
333 // tntNode tnreturn; /* The node to return */
334 //
335 // /* Check whether schmidt data already exists */
336 // if (NULL == nw->schmidt_vec) {
337 // sprintf(tnt_err.errinfostr,"The Schmidt vectors have not yet been initialised!| Call tntNetworkSchmidtVecInit() to initialise."); /* NO_COVERAGE */
338 // sprintf(tnt_err.pubfuncname,__FUNCTION__); /* NO_COVERAGE */
339 // _tnt_print_error(); /* NO_COVERAGE */
340 // } /* NO_COVERAGE */
341 //
342 // /* Check the site number is valid */
343 // if (j >= nw->schmidt_vec->sz) {
344 // sprintf(tnt_err.errinfostr,"The site number (%d) exceeds the number of sites for which Schmidt vectors are stored (%d)",j,nw->schmidt_vec->sz); /* NO_COVERAGE */
345 // sprintf(tnt_err.pubfuncname,__FUNCTION__); /* NO_COVERAGE */
346 // _tnt_print_error(); /* NO_COVERAGE */
347 // } /* NO_COVERAGE */
348 //
349 // ret = _tnt_tnode_copy(&tnreturn, nw->schmidt_vec->vals[j], 0);
350 // TNT_PUB_ERR_CHK /* NO_COVERAGE */
351 //
352 // return tnreturn;
353 //
354 // }
355 
361 // void tntNetworkSchmidtVecSet(tntNetwork nw, /*!< The network */
362 // unsigned j, /*!< Site number to set schmidt vector for */
363 // tntNode lambda) /*!< The node containing the schmidt vector */
364 // {
365 // TNT_ERR_RET_DEFS /* return value from internal function */
366 // tntNode tnreturn; /* The node to return */
367 //
368 // /* Check whether schmidt data already exists */
369 // if (NULL == nw->schmidt_vec) {
370 // sprintf(tnt_err.errinfostr,"The Schmidt vectors have not yet been initialised!| Call tntNetworkSchmidtVecInit() to initialise."); /* NO_COVERAGE */
371 // sprintf(tnt_err.pubfuncname,__FUNCTION__); /* NO_COVERAGE */
372 // _tnt_print_error(); /* NO_COVERAGE */
373 // } /* NO_COVERAGE */
374 //
375 // /* Check that the site number is valid */
376 // if (j >= nw->schmidt_vec->sz) {
377 // sprintf(tnt_err.errinfostr,"The site number (%d) exceeds the number of sites for which Schmidt vectors are stored (%d)",j,nw->schmidt_vec->sz); /* NO_COVERAGE */
378 // sprintf(tnt_err.pubfuncname,__FUNCTION__); /* NO_COVERAGE */
379 // _tnt_print_error(); /* NO_COVERAGE */
380 // } /* NO_COVERAGE */
381 //
382 // /* Free the current node for that site */
383 // ret = _tnt_tnode_free(nw->schmidt_vec->vals + j);
384 // TNT_PUB_ERR_CHK /* NO_COVERAGE */
385 //
386 // /* Copy over the new node */
387 // ret = _tnt_tnode_copy(nw->schmidt_vec->vals + j, lambda, 0);
388 // TNT_PUB_ERR_CHK /* NO_COVERAGE */
389 //
390 // return;
391 //
392 // }
void tntNetworkFree(tntNetwork *nwp)
Definition: tntNetwork.c:118
tntNetwork tntNetworkCreate(void)
Definition: tntNetwork.c:92
tntNetwork tntNetworkConjCopy(tntNetwork nw)
Definition: tntNetwork.c:19
tntNetwork tntNetworkSplit(tntNetwork nw, tntNode tnFirst_1, tntLegLabel leg_start_1, tntNode tnLast_1, tntLegLabel leg_end_1, tntNode tnFirst_2, tntLegLabel leg_start_2, tntNode tnLast_2, tntLegLabel leg_end_2, unsigned numSplit_1, tntNode *tnSplit_1, unsigned numSplit_2, tntNode *tnSplit_2)
Definition: tntNetwork.c:203
Definition: tnt.h:65
tntNode tntNetworkMinSite(tntNode V, tntNetwork *nwMV, unsigned NM, tntNode(*eig_contract)(tntNode, tntNetwork), void(*eig_prep)(tntNode, tntNetwork), tntComplex *eigval)
Definition: tntNetwork.c:153
tntNetwork tntNetworkCopy(tntNetwork nw)
Definition: tntNetwork.c:56
void tntNetworkToNodeGroup(tntNetwork *nwp, int strip_connections)
Definition: tntNetwork.c:268