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
tntNodeInfo.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 /*-------------------------------------------*/
7 
8 #include "../headers/tnt_int.h"
9 #include "../headers/dec_public.h"
10 #include "../headers/dec_tnode.h"
11 #include "../headers/dec_network.h"
12 
13 
29 tntNode tntNodeFindConn(tntNode A,
30  tntLegLabel legA)
31 {
32  struct tnode *tnconn; /* the connecting tnode */
33  unsigned lA;
34  TNT_ERR_RET_DEFS /* return value from internal function */
35 
36  /* Convert characters to integers */
37  ret = _tnt_node_id_chartonum(&lA,legA[0]);
38  TNT_PUB_ERR_CHK /* NO_COVERAGE */
39 
40  ret = _tnt_tnode_findtnconn(&tnconn, A, lA);
41  TNT_PUB_ERR_CHK /* NO_COVERAGE */
42 
43  return tnconn;
44 }
45 
50 tntNode tntNodeFindFirst(tntNetwork nw)
51 {
52  struct tnode *A; /* the starting tnode */
53  TNT_ERR_RET_DEFS /* return value from internal function */
54 
55  ret = _tnt_tnode_findfirst(nw->nw_start, &A);
56  TNT_PUB_ERR_CHK /* NO_COVERAGE */
57 
58  if (A == nw->nw_end) A = NULL;
59 
60  return A;
61 }
62 
63 
68 tntNode tntNodeFindLast(tntNetwork nw)
69 {
70  struct tnode *A; /* the last tnode */
71  TNT_ERR_RET_DEFS /* return value from internal function */
72 
73  ret = _tnt_tnode_findlast(nw->nw_end, &A);
74  TNT_PUB_ERR_CHK /* NO_COVERAGE */
75 
76  if (A == nw->nw_start) A = NULL;
77 
78  return A;
79 }
80 
87 {
88  TNT_ERR_RET_DEFS /* return value from internal function */
89  tntComplex felem; /* the first element */
90 
91  ret = _tnt_tnode_checkqn(A);
92  TNT_PUB_ERR_CHK /* NO_COVERAGE */
93 
94  ret = _tnt_tnode_getfirstelement(&felem, A);
95  TNT_PUB_ERR_CHK /* NO_COVERAGE */
96 
97  return felem;
98 }
99 
100 
111  tntLegLabel rowlegs,
112  tntLegLabel collegs)
113 {
114 
115  TNT_ERR_RET_DEFS /* return value from internal function */
116  unsigned rownum, *rowlegids, colnum, *collegids;
117  tntComplex trace; /* the trace */
118 
119  ret = _tnt_tnode_checkqn(A);
120  TNT_PUB_ERR_CHK /* NO_COVERAGE */
121 
122  ret = _tnt_node_id_strtonum(&rownum, &rowlegids, rowlegs);
123  TNT_PUB_ERR_CHK /* NO_COVERAGE */
124 
125  ret = _tnt_node_id_strtonum(&colnum, &collegids, collegs);
126  TNT_PUB_ERR_CHK /* NO_COVERAGE */
127 
128  ret = _tnt_tnode_gettrace(&trace, A, rownum, (int *) rowlegids, colnum, (int *) collegids);
129  TNT_PUB_ERR_CHK /* NO_COVERAGE */
130 
131  free(rowlegids);
132  free(collegids);
133 
134  return trace;
135 }
136 
145 tntComplexArray tntNodeGetDiag(tntNode A,
146  tntLegLabel rowlegs,
147  tntLegLabel collegs)
148 {
149  TNT_ERR_RET_DEFS /* return value from internal function */
150  unsigned rownum, *rowlegids, colnum, *collegids;
151  tntComplexArray diag; /* the diagonal values */
152 
153  ret = _tnt_tnode_checkqn(A);
154  TNT_PUB_ERR_CHK /* NO_COVERAGE */
155 
156  ret = _tnt_node_id_strtonum(&rownum, &rowlegids, rowlegs);
157  TNT_PUB_ERR_CHK /* NO_COVERAGE */
158 
159  ret = _tnt_node_id_strtonum(&colnum, &collegids, collegs);
160  TNT_PUB_ERR_CHK /* NO_COVERAGE */
161 
162  ret = _tnt_tnode_getdiag(&diag, A, rownum, (int *) rowlegids, colnum, (int *) collegids);
163  TNT_PUB_ERR_CHK /* NO_COVERAGE */
164 
165  free(rowlegids);
166  free(collegids);
167 
168  return diag;
169 }
170 
178 tntComplexArray tntNodeGetMatrix(tntNode A,
179  tntLegLabel rowlegs,
180  tntLegLabel collegs)
181 {
182  TNT_ERR_RET_DEFS /* return value from internal function */
183  unsigned rownum, *rowlegids, colnum, *collegids;
184  tntComplexArray matrix; /* the diagonal values */
185 
186  ret = _tnt_tnode_checkqn(A);
187  TNT_PUB_ERR_CHK /* NO_COVERAGE */
188 
189  ret = _tnt_node_id_strtonum(&rownum, &rowlegids, rowlegs);
190  TNT_PUB_ERR_CHK /* NO_COVERAGE */
191 
192  ret = _tnt_node_id_strtonum(&colnum, &collegids, collegs);
193  TNT_PUB_ERR_CHK /* NO_COVERAGE */
194 
195  ret = _tnt_tnode_getmatrix(&matrix, A, rownum, (int *) rowlegids, colnum, (int *) collegids);
196  TNT_PUB_ERR_CHK /* NO_COVERAGE */
197 
198  free(rowlegids);
199  free(collegids);
200 
201  return matrix;
202 }
203 
208 #ifdef MAKINGPUBLICDOCS
209 void tntNodePrintAsMatrix(tntNode A,
210  tntLegLabel rowlegs,
211  tntLegLabel collegs)
212 #else
213 void tntNodePrintNamedAsMatrix(const char *varname,
214  tntNode A,
215  tntLegLabel rowlegs,
216  tntLegLabel collegs)
217 #endif
218 {
219 
220  TNT_ERR_RET_DEFS /* return value from internal function */
221  unsigned rownum, *rowlegids, colnum, *collegids;
222 
223  ret = _tnt_tnode_checkqn(A);
224  TNT_PUB_ERR_CHK /* NO_COVERAGE */
225 
226  ret = _tnt_node_id_strtonum(&rownum, &rowlegids, rowlegs);
227  TNT_PUB_ERR_CHK /* NO_COVERAGE */
228 
229  ret = _tnt_node_id_strtonum(&colnum, &collegids, collegs);
230  TNT_PUB_ERR_CHK /* NO_COVERAGE */
231 
232  ret = _tnt_tnode_to_matrix(A, rownum, (int *) rowlegids, colnum, (int *) collegids);
233  TNT_PUB_ERR_CHK /* NO_COVERAGE */
234 
235  tntNodePrintNamedInfo(varname, A, 1);
236 
237  free(rowlegids);
238  free(collegids);
239 }
240 
246 unsigned tntNodeGetLegDim(tntNode A,
247  tntLegLabel legA)
248 {
249  tntIntArray leg_ids, leg_dims;
250  unsigned j, legid; /* loop counter, integer leg id */
251  int leg_dim_rt = -1; /* initialise value of leg dimension with -1 */
252  TNT_ERR_RET_DEFS /* return value from internal function */
253  char err_msg[TNT_STRLEN]; /* buffer for error messages */
254 
255  /* Convert legid to integer */
256  ret = _tnt_node_id_chartonum(&legid, legA[0]);
257  TNT_PUB_ERR_CHK /* NO_COVERAGE */
258 
259  /* Get leg ids to link leg ids to leg numbers */
260  ret = _tnt_tnode_idget(&leg_ids, A);
261  TNT_PUB_ERR_CHK /* NO_COVERAGE */
262 
263  /* Get leg dimensions, which will be in the order of the leg numbers */
264  ret = _tnt_tnode_dimget(&leg_dims, A);
265  TNT_PUB_ERR_CHK /* NO_COVERAGE */
266 
267  /* Look for the leg with id given */
268  for (j = 0; j < leg_dims.sz; j++) {
269  if ((unsigned) leg_ids.vals[j] == legid) {
270  leg_dim_rt = leg_dims.vals[j];
271  break;
272  }
273  }
274 
275  /* Free the arrays that are no longer required */
276  tntIntArrayFree(&leg_ids);
277  tntIntArrayFree(&leg_dims);
278 
279  /* If leg id hasn't been found, set an error */
280  if (-1 == leg_dim_rt) {
281  sprintf(err_msg,"Cannot get the dimension of leg %c - leg not found",*legA); /* NO_COVERAGE */
282  sprintf(tnt_err.errinfostr,"%s",err_msg); /* NO_COVERAGE */
283  sprintf(tnt_err.pubfuncname,__FUNCTION__); /* NO_COVERAGE */
284  _tnt_print_error(); /* NO_COVERAGE */
285  } /* NO_COVERAGE */
286 
287  return (unsigned) leg_dim_rt;
288 }
289 
295 int tntNodeGetLegDir(tntNode A,
296  tntLegLabel legA)
297 {
298  tntIntArray leg_dirs, leg_ids; /* Array to return containing directions and id's */
299  unsigned j, legid; /* loop counter, integer leg id */
300  int dirchk = -1, leg_dir_rt; /* check that a leg has been found, and leg direction to return */
301  TNT_ERR_RET_DEFS /* return value from internal function */
302  char err_msg[TNT_STRLEN]; /* buffer for error messages */
303 
304  ret = _tnt_tnode_checkqn(A);
305  TNT_PUB_ERR_CHK /* NO_COVERAGE */
306 
307  /* Convert legid to integer */
308  ret = _tnt_node_id_chartonum(&legid, legA[0]);
309  TNT_PUB_ERR_CHK /* NO_COVERAGE */
310 
311  /* Get leg ids to link leg ids to leg numbers */
312  ret = _tnt_tnode_idget(&leg_ids, A);
313  TNT_PUB_ERR_CHK /* NO_COVERAGE */
314 
315  /* Get leg directions */
316  ret = _tnt_tnode_dirget(&leg_dirs, A);
317  TNT_PUB_ERR_CHK /* NO_COVERAGE */
318 
319  /* Look for the leg with id given */
320  for (j = 0; j < leg_dirs.sz; j++) {
321  if ((unsigned) leg_ids.vals[j] == legid) {
322  leg_dir_rt = leg_dirs.vals[j];
323  dirchk = 0;
324  break;
325  }
326  }
327 
328  /* Free the arrays that are no longer required */
329  tntIntArrayFree(&leg_ids);
330  tntIntArrayFree(&leg_dirs);
331 
332  /* If leg id hasn't been found, set an error */
333  if (-1 == dirchk) {
334  sprintf(err_msg,"Cannot get the direction of leg %c - leg not found",*legA); /* NO_COVERAGE */
335  sprintf(tnt_err.errinfostr,"%s",err_msg); /* NO_COVERAGE */
336  sprintf(tnt_err.pubfuncname,__FUNCTION__); /* NO_COVERAGE */
337  _tnt_print_error(); /* NO_COVERAGE */
338  } /* NO_COVERAGE */
339 
340  return leg_dir_rt;
341 }
342 
343 #ifdef MAKINGPUBLICDOCS
344 
347 void tntNodePrintInfo(tntNode A)
348 {
349  tntNodePrintNamedInfo("A", A, 0);
350 }
354 void tntNodePrintAll(tntNode A)
355 #else
356 void tntNodePrintNamedInfo(const char *varname, tntNode A, int printvals)
357 #endif
358 {
359  tntIntArray leg_ids, leg_dims, leg_dirs, qn_nums;
360  tntDoubleArray doubleparams;
361  tntComplexArray compparams;
362  int valtypes;
363  unsigned j, n; int k, numqn; /* loop counters */
364  char dir_str[3][TNT_STRLEN] = {"outgoing"," un-set ","incoming"}; /* strings for leg directions */
365  extern tntSystem systype; /* Internal declaration of global variable for system type */
366  char idc; /* Label for the leg */
367  TNT_ERR_RET_DEFS /* return value from internal function */
368 
369  ret = _tnt_tnode_checkqn(A);
370  TNT_PUB_ERR_CHK /* NO_COVERAGE */
371 
372  /* Print info */
373  _tnt_printf("-----------------------------------\n");
374  _tnt_printf("Information for node %s\n", varname);
375  _tnt_printf("-----------------------------------\n");
376 
377  if (NULL == A) {
378  _tnt_printf("There is no node - variable has NULL value\n");
379  return;
380  }
381 
382  /* Get leg ids */
383  ret = _tnt_tnode_idget(&leg_ids, A);
384  TNT_PUB_ERR_CHK /* NO_COVERAGE */
385 
386  /* Get leg dimensions */
387  ret = _tnt_tnode_dimget(&leg_dims, A);
388  TNT_PUB_ERR_CHK /* NO_COVERAGE */
389 
390  /* Get leg directions */
391  ret = _tnt_tnode_dirget(&leg_dirs, A);
392  TNT_PUB_ERR_CHK /* NO_COVERAGE */
393 
394  _tnt_printf("%s has %d legs:\n",varname,leg_ids.sz);
395  /* Print table header */
396  _tnt_printf("Leg id Dimension Leg direction QN numbers\n");
397  for (j = 0; j < leg_ids.sz; j++) {
398  /* Print leg id, dimensions and direction */
399  /* get character id */
400  ret = _tnt_node_id_numtochar(&idc,leg_ids.vals[j]);
401  TNT_PUB_ERR_CHK /* NO_COVERAGE */
402 
403  _tnt_printf(" %c %d %s ", idc, leg_dims.vals[j], dir_str[leg_dirs.vals[j]+1]);
404 
405  /* get quantum numbers */
406  ret = _tnt_tnode_getqn(&qn_nums, A, leg_ids.vals[j]);
407  TNT_PUB_ERR_CHK /* NO_COVERAGE */
408 
409  /* print quantum numbers if they exist */
410  if (0 == qn_nums.sz) {
411  /* if no qn numbers set, print this */
412  _tnt_printf("None set\n");
413  } else {
414  _tnt_printf("{");
415  numqn = qn_nums.sz/systype.symm_num_qn;
416  /* if dimension is less than or equal to MAX_QN_PRINT, print numbers */
417  if (MAX_QN_PRINT >= numqn) {
418  for (k = 0; k < numqn-1; k++) {
419  if (1 == systype.symm_num_qn)
420  _tnt_printf("%d, ",qn_nums.vals[k]);
421  else {
422  _tnt_printf("{");
423  for (n = 0; n < systype.symm_num_qn - 1; n++) {
424  _tnt_printf("%d,",qn_nums.vals[k*systype.symm_num_qn + n]);
425  }
426  _tnt_printf("%d},", qn_nums.vals[k*systype.symm_num_qn + n]);
427  }
428  }
429  if (1 == systype.symm_num_qn)
430  _tnt_printf("%d",qn_nums.vals[k]);
431  else {
432  _tnt_printf("{");
433  for (n = 0; n < systype.symm_num_qn - 1; n++) {
434  _tnt_printf("%d,",qn_nums.vals[k*systype.symm_num_qn + n]);
435  }
436  _tnt_printf("%d}", qn_nums.vals[k*systype.symm_num_qn + n]);
437  }
438  } else {
439  /* Otherwise only print first 10 and last value, with ... to indicate that there are more that are not being listed */
440  for (k = 0; k < 10; k++) {
441  if (1 == systype.symm_num_qn)
442  _tnt_printf("%d,",qn_nums.vals[k]);
443  else {
444  _tnt_printf("{");
445  for (n = 0; n < systype.symm_num_qn - 1; n++) {
446  _tnt_printf("%d,",qn_nums.vals[k*systype.symm_num_qn + n]);
447  }
448  _tnt_printf("%d},", qn_nums.vals[k*systype.symm_num_qn + n]);
449  }
450  }
451  if (1 == systype.symm_num_qn)
452  _tnt_printf(",...,%d",qn_nums.vals[numqn-1]);
453  else {
454  _tnt_printf("{");
455  for (n = 0; n < systype.symm_num_qn - 1; n++) {
456  _tnt_printf("%d,",qn_nums.vals[(numqn-1)*systype.symm_num_qn + n]);
457  }
458  _tnt_printf("%d}", qn_nums.vals[(numqn-1)*systype.symm_num_qn + n]);
459  }
460  }
461  _tnt_printf("}\n");
462 
463  /* free the array*/
464  tntIntArrayFree(&qn_nums);
465  }
466  }
467 
468  /* Print other node info */
469  ret = _tnt_tnode_print(varname,A,printvals,TNT_PLAIN_STYLE);
470  TNT_PUB_ERR_CHK /* NO_COVERAGE */
471 
472  /* Print parameters if they exist */
473  ret = _tnt_tnode_paramsget(&valtypes, &doubleparams, &compparams, A);
474  TNT_PUB_ERR_CHK /* NO_COVERAGE */
475 
476  if (printvals) {
477  tntIntArray rows, cols;
478  char ol[] = "leg", ml[] = "legs";
479 
480  ret = _tnt_tnode_rowcolsget(&rows, &cols, A);
481  TNT_PUB_ERR_CHK /* NO_COVERAGE */
482 
483  if (rows.sz > 0 && cols.sz > 0) {
484  _tnt_printf("The node printed above has rows formed of %s ",(1 == rows.sz)?ol:ml);
485  for (j = 0; j < rows.sz; j++) _tnt_printf("%c, ",_tnt_node_iderr_numtochar(leg_ids.vals[rows.vals[j]]));
486  _tnt_printf("and columns formed of %s ",(1 == cols.sz)?ol:ml);
487  for (j = 0; j < cols.sz; j++) _tnt_printf("%c, ",_tnt_node_iderr_numtochar(leg_ids.vals[cols.vals[j]]));
488  _tnt_printf("to form the matrix given.\n");
489  } else if (0 == rows.sz) {
490  _tnt_printf("The columns are formed by %s ",(1 == cols.sz)?ol:ml);
491  for (j = 0; j < cols.sz; j++) _tnt_printf("%c, ",_tnt_node_iderr_numtochar(leg_ids.vals[cols.vals[j]]));
492  _tnt_printf("with no legs assigned to the single column.\n");
493  } else {
494  _tnt_printf("The rows are formed by %s ",(1 == rows.sz)?ol:ml);
495  for (j = 0; j < rows.sz; j++) _tnt_printf("%c, ",_tnt_node_iderr_numtochar(leg_ids.vals[rows.vals[j]]));
496  _tnt_printf("with no legs assigned to the single column.\n");
497  }
498 
499  tntIntArrayFree(&rows);
500  tntIntArrayFree(&cols);
501  }
502 
503  if (0 == valtypes) {
504  tntNamedDoubleArrayPrint("Parameters a_i = ", &doubleparams);
505  tntDoubleArrayFree(&doubleparams);
506  } else if (1 == valtypes) {
507  tntNamedComplexArrayPrint("Parameters a_i = ", &compparams);
508  tntComplexArrayFree(&compparams);
509  }
510 
511  /* Free arrays no longer required */
512  tntIntArrayFree(&leg_ids);
513  tntIntArrayFree(&leg_dims);
514  tntIntArrayFree(&leg_dirs);
515 }
516 
521 unsigned tntNodeIsFunctional(tntNode A)
522 {
523  if (NULL == A->pvals) {
524  return 0;
525  } else {
526  return A->pvals->sz;
527  }
528 }
529 
535 unsigned tntNodeIsCovariant(tntNode A)
536 {
537  TNT_ERR_RET_DEFS
538 
539  ret = _tnt_tnode_checkqn(A);
540  TNT_PUB_ERR_CHK /* NO_COVERAGE */
541 
542  if (BLKS == A->tnsr->elems_type) {
543  return 1;
544  } else {
545  return 0;
546  }
547 }
548 
554 double tntNodeGetNorm(tntNode A)
555 {
556  double norm;
557  TNT_ERR_RET_DEFS
558 
559  ret = _tnt_tnode_checkqn(A);
560  TNT_PUB_ERR_CHK /* NO_COVERAGE */
561 
562  /* find finishing norm */
563  ret = _tnt_tnode_norm(&norm,A);
564  TNT_PUB_ERR_CHK /* NO_COVERAGE */
565 
566  return norm;
567 }
tntSystem systype
Definition: tntSys.c:12
tntNode tntNodeFindLast(tntNetwork nw)
Definition: tntNodeInfo.c:68
void tntNodePrintInfo(tntNode A)
Definition: tntNodeInfo.c:347
double tntNodeGetNorm(tntNode A)
Definition: tntNodeInfo.c:554
tntComplex tntNodeGetTrace(tntNode A, tntLegLabel rowlegs, tntLegLabel collegs)
Definition: tntNodeInfo.c:110
void tntNodePrintAll(tntNode A)
Definition: tntNodeInfo.c:354
unsigned tntNodeIsCovariant(tntNode A)
Definition: tntNodeInfo.c:535
Definition: tnt.h:65
void tntIntArrayFree(tntIntArray *arr)
Definition: tntArray.c:620
void tntNodePrintAsMatrix(tntNode A, tntLegLabel rowlegs, tntLegLabel collegs)
Definition: tntNodeInfo.c:209
void tntDoubleArrayFree(tntDoubleArray *arr)
Definition: tntArray.c:635
tntNode tntNodeFindConn(tntNode A, tntLegLabel legA)
Definition: tntNodeInfo.c:29
void tntComplexArrayFree(tntComplexArray *arr)
Definition: tntArray.c:650
tntNode tntNodeFindFirst(tntNetwork nw)
Definition: tntNodeInfo.c:50
unsigned tntNodeIsFunctional(tntNode A)
Definition: tntNodeInfo.c:521
tntComplexArray tntNodeGetMatrix(tntNode A, tntLegLabel rowlegs, tntLegLabel collegs)
Definition: tntNodeInfo.c:178
unsigned tntNodeGetLegDim(tntNode A, tntLegLabel legA)
Definition: tntNodeInfo.c:246
tntComplexArray tntNodeGetDiag(tntNode A, tntLegLabel rowlegs, tntLegLabel collegs)
Definition: tntNodeInfo.c:145
int tntNodeGetLegDir(tntNode A, tntLegLabel legA)
Definition: tntNodeInfo.c:295
tntComplex tntNodeGetFirstEl(tntNode A)
Definition: tntNodeInfo.c:86