Tensor Network Theory Library  Beta release 1.2.1 A library of routines for performing TNT-based operations
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
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