Tensor Network Theory Library  Beta release 1.2.0 A library of routines for performing TNT-based operations
tntArray.c
1 /*
2 Authors: Sarah Al-Assam, Stephen Clark and Dieter Jaksch
3 Date: $LastChangedDate: 2016-10-04 17:22:47 +0100 (Tue, 04 Oct 2016)$
4 (c) University of Oxford 2014
5 */
6
12 /*-------------------------------------------*/
13
16
17 TNT_int_err _tnt_get_array_elems(const char *array_string, char ***stringrowsp, unsigned *Mp, unsigned *Np, unsigned *szp);
18
28 #ifdef MAKINGPUBLICDOCS
29 tntIntArray tntIntArrayAlloc(unsigned numrows,
30  unsigned numcols)
31 #else
32  /* Called via pre-processor macro to make sure there are always two arguments, the second of which is 1 if it has not been provided. */
33 tntIntArray tntIntMatrixAlloc(unsigned numrows,
34  unsigned numcols)
35 #endif
36 {
37  tntIntArray arr; /* array to return */
38  TNT_ERR_RET_DEFS
39
40  arr.sz = numrows*numcols;
41  arr.numrows = numrows;
42  arr.numcols = numcols;
43
44  chk = arr.vals = calloc(arr.sz,sizeof(int));
45  TNT_PUB_MEM_CHK /* NO_COVERAGE */
46
47  return arr;
48 }
49
70 tntIntArray tntIntArrayCreate(const char *array_string)
71 {
72  tntIntArray arr;
73  char **stringelems;
74  unsigned k;
75  TNT_ERR_RET_DEFS
76
77  ret = _tnt_get_array_elems(array_string, &stringelems, &arr.numrows, &arr.numcols, &arr.sz);
78  if (ret != TNT_SUCCESS) {
79  sprintf(tnt_err.pubfuncname,"tntIntArrayCreate"); /* NO_COVERAGE */
80  _tnt_print_error(); /* NO_COVERAGE */
81  }
82
83  chk = arr.vals = malloc(arr.sz*sizeof(int));
84  TNT_PUB_MEM_CHK /* NO_COVERAGE */
85
86  /* Now go through each row and column and get the number */
87  for (k = 0;k < arr.sz; k++) {
88  arr.vals[k] = atoi(stringelems[k]);
89  }
90
91  free(stringelems[0]);
92  free(stringelems);
93
94  return arr;
95 }
96
118 tntDoubleArray tntDoubleArrayCreate(const char *array_string)
119 {
120  tntDoubleArray arr;
121  char **stringelems;
122  unsigned k;
123  TNT_ERR_RET_DEFS
124
125  ret = _tnt_get_array_elems(array_string, &stringelems, &arr.numrows, &arr.numcols, &arr.sz);
126  if (ret != TNT_SUCCESS) {
127  sprintf(tnt_err.pubfuncname,"tntDoubleArrayCreate"); /* NO_COVERAGE */
128  _tnt_print_error(); /* NO_COVERAGE */
129  }
130
131  chk = arr.vals = malloc(arr.sz*sizeof(double));
132  TNT_PUB_MEM_CHK /* NO_COVERAGE */
133
134  /* Now go through each row and column and get the number */
135  for (k = 0;k < arr.sz; k++) {
136  arr.vals[k] = atof(stringelems[k]);
137  }
138
139  free(stringelems[0]);
140  free(stringelems);
141
142  return arr;
143 }
144
165 tntComplexArray tntComplexArrayCreate(const char *array_string)
166 {
167  tntComplexArray arr;
168  char **stringelems;
169  unsigned k;
170  TNT_ERR_RET_DEFS
171
172  ret = _tnt_get_array_elems(array_string, &stringelems, &arr.numrows, &arr.numcols, &arr.sz);
173  if (ret != TNT_SUCCESS) {
174  sprintf(tnt_err.pubfuncname,"tntComplexArrayCreate"); /* NO_COVERAGE */
175  _tnt_print_error(); /* NO_COVERAGE */
176  }
177
178  chk = arr.vals = malloc(arr.sz*sizeof(tntComplex));
179  TNT_PUB_MEM_CHK /* NO_COVERAGE */
180
181  /* Now go through each row and column and get the number */
182  for (k = 0;k < arr.sz; k++) {
183  arr.vals[k] = tntAtoC(stringelems[k]);
184  }
185
186  free(stringelems[0]);
187  free(stringelems);
188
189  return arr;
190 }
191
208 tntIntArray tntIntArrayCreateDiag(const char *array_string, int offs)
209 {
210  tntIntArray arr;
211  char **stringelems;
212  unsigned k, M, N, sz, m, n;
213  TNT_ERR_RET_DEFS
214
215  ret = _tnt_get_array_elems(array_string, &stringelems, &M, &N, &sz);
216  if (ret != TNT_SUCCESS) {
217  sprintf(tnt_err.pubfuncname,"tntIntArrayCreateDiag"); /* NO_COVERAGE */
218  _tnt_print_error(); /* NO_COVERAGE */
219  }
220
221  arr.numrows = arr.numcols = sz + abs(offs);
222  arr.sz = arr.numrows*arr.numcols;
223  chk = arr.vals = calloc(arr.sz, sizeof(int));
224  TNT_PUB_MEM_CHK /* NO_COVERAGE */
225
226  /* Now go through each row and column and get the number */
227  for (k = 0; k < sz; k++) {
228  if (offs < 0) {
229  m = k - offs;
230  n = k;
231  } else if (offs > 0) {
232  m = k;
233  n = k + offs;
234  } else {
235  m = n = k;
236  }
237  arr.vals[m + n*arr.numrows] = atoi(stringelems[k]);
238  }
239
240  free(stringelems[0]);
241  free(stringelems);
242
243  return arr;
244 }
245
262 tntDoubleArray tntDoubleArrayCreateDiag(const char *array_string, int offs)
263 {
264  tntDoubleArray arr;
265  char **stringelems;
266  unsigned k, M, N, sz, m, n;
267  TNT_ERR_RET_DEFS
268
269  ret = _tnt_get_array_elems(array_string, &stringelems, &M, &N, &sz);
270  if (ret != TNT_SUCCESS) {
271  sprintf(tnt_err.pubfuncname,"tntDoubleArrayCreateDiag"); /* NO_COVERAGE */
272  _tnt_print_error(); /* NO_COVERAGE */
273  }
274
275  arr.numrows = arr.numcols = sz + abs(offs);
276  arr.sz = arr.numrows*arr.numcols;
277  chk = arr.vals = calloc(arr.sz, sizeof(double));
278  TNT_PUB_MEM_CHK /* NO_COVERAGE */
279
280  /* Now go through each row and column and get the number */
281  for (k = 0; k < sz; k++) {
282  if (offs < 0) {
283  m = k - offs;
284  n = k;
285  } else if (offs > 0) {
286  m = k;
287  n = k + offs;
288  } else {
289  m = n = k;
290  }
291  arr.vals[m + n*arr.numrows] = atof(stringelems[k]);
292  }
293
294  free(stringelems[0]);
295  free(stringelems);
296
297  return arr;
298 }
299
316 tntComplexArray tntComplexArrayCreateDiag(const char *array_string, int offs)
317 {
318  tntComplexArray arr;
319  char **stringelems;
320  unsigned k, M, N, sz, m, n;
321  TNT_ERR_RET_DEFS
322
323  ret = _tnt_get_array_elems(array_string, &stringelems, &M, &N, &sz);
324  if (ret != TNT_SUCCESS) {
325  sprintf(tnt_err.pubfuncname,"tntComplexArrayCreateDiag"); /* NO_COVERAGE */
326  _tnt_print_error(); /* NO_COVERAGE */
327  }
328
329  arr.numrows = arr.numcols = sz + abs(offs);
330  arr.sz = arr.numrows*arr.numcols;
331  chk = arr.vals = calloc(arr.sz, sizeof(tntComplex));
332  TNT_PUB_MEM_CHK /* NO_COVERAGE */
333
334  /* Now go through each row and column and get the number */
335  for (k = 0; k < sz; k++) {
336  if (offs < 0) {
337  m = k - offs;
338  n = k;
339  } else if (offs > 0) {
340  m = k;
341  n = k + offs;
342  } else {
343  m = n = k;
344  }
345  arr.vals[m + n*arr.numrows] = tntAtoC(stringelems[k]);
346  }
347
348  free(stringelems[0]);
349  free(stringelems);
350
351  return arr;
352 }
353
362 #ifdef MAKINGPUBLICDOCS
363 tntDoubleArray tntDoubleArrayAlloc(unsigned numrows,
364  unsigned numcols)
365 #else
366 /* Called via pre-processor macro to make sure there are always two arguments, the second of which is 1 if it has not been provided. */
367 tntDoubleArray tntDoubleMatrixAlloc(unsigned numrows,
368  unsigned numcols)
369 #endif
370 {
371  tntDoubleArray arr; /* array to return */
372  TNT_ERR_RET_DEFS
373
374  arr.sz = numrows*numcols;
375  arr.numrows = numrows;
376  arr.numcols = numcols;
377
378  chk = arr.vals = calloc(arr.sz,sizeof(double));
379  TNT_PUB_MEM_CHK /* NO_COVERAGE */
380
381  return arr;
382 }
383
391 #ifdef MAKINGPUBLICDOCS
392 tntComplexArray tntComplexArrayAlloc(unsigned numrows,
393  unsigned numcols)
394 #else
395 /* Called via pre-processor macro to make sure there are always two arguments, the second of which is 1 if it has not been provided. */
396 tntComplexArray tntComplexMatrixAlloc(unsigned numrows,
397  unsigned numcols)
398 #endif
399 {
400  tntComplexArray arr; /* array to return */
401  unsigned i; /* used for looping over array elements */
402  TNT_ERR_RET_DEFS
403
404  arr.sz = numrows*numcols;
405  arr.numrows = numrows;
406  arr.numcols = numcols;
407
408  chk = arr.vals = malloc(arr.sz*sizeof(tntComplex));
409  TNT_PUB_MEM_CHK /* NO_COVERAGE */
410
411  /* Initialise all entries to zero */
412  for (i = 0; i < arr.sz; i++) {
413  arr.vals[i].re = 0.0;
414  arr.vals[i].im = 0.0;
415  }
416
417  return arr;
418 }
419
428 tntNodeArray tntNodeArrayAlloc(unsigned num_elems)
429 {
430  tntNodeArray arr; /* array to return */
431  TNT_ERR_RET_DEFS
432
433  ret = _tnt_tnarr_alloc(&arr, num_elems);
434  TNT_PUB_ERR_CHK /* NO_COVERAGE */
435
436  return arr;
437 }
438
439
440 #ifdef MAKINGPUBLICDOCS
441
449 /* Function call leads to function below through C pre-processor macro */
450 tntNodeArray tntNodeArrayCreate(tntNode A,
451  tntNode B,
452  tntNode C...)
453 #else
454 tntNodeArray tntNodeArrayCreateStatic(tntNode A, tntNode B, tntNode C, tntNode D, tntNode E, tntNode F, tntNode G, tntNode H, tntNode I, tntNode J, tntNode K, tntNode L, tntNode M, tntNode N, tntNode O, tntNode P, tntNode Q, tntNode R, tntNode S, tntNode T, tntNode U, tntNode V, tntNode W, tntNode X)
455 #endif
456 {
457  tntNode tns[24] = {A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X}; /* Array of the nodes to add to the array */
458  tntNodeArray arr; /* The array to return */
459  unsigned numnodes=0, k; /* Number of nodes in the array, loop counter */
460
461  TNT_ERR_RET_DEFS
462
463
464  /* Count the number of non-NULL arguments */
465  for (k = 0; k < 24; k++) {
466  if (NULL != tns[k]) numnodes++;
467  }
468
469  /* allocate an array of that size */
470  ret = _tnt_tnarr_alloc(&arr, numnodes);
471  TNT_PUB_ERR_CHK /* NO_COVERAGE */
472
473  /* copy over nodes */
474  numnodes = 0;
475  for (k = 0; k < 24; k++) {
476  if (NULL != tns[k]) {
477  arr.vals[numnodes] = tntNodeCopy(tns[k]);
478  numnodes++;
479  }
480  }
481
482  return arr;
483 }
484
485
492 tntStringArray tntStringArrayAlloc(unsigned num_elems)
493 {
494  tntStringArray arr; /* array to return */
495  unsigned loop; /* used for looping over aray elements */
496  TNT_ERR_RET_DEFS
497
498
499  chk = arr.vals = malloc(num_elems*sizeof(char *));
500  TNT_PUB_MEM_CHK /* NO_COVERAGE */
501
502  arr.sz = num_elems;
503
504  /* Set all values to be a string (character array) of length TNT_STRLEN */
505  for (loop = 0; loop < num_elems; loop++) {
506  chk = arr.vals[loop] = malloc(TNT_STRLEN*sizeof(char));
507  TNT_PUB_MEM_CHK /* NO_COVERAGE */
508  }
509
510  return arr;
511 }
512
513 #ifdef MAKINGPUBLICDOCS
514
521 /* Function call leads to function below through C pre-processor macro */
522 tntStringArray tntStringArrayCreate(const char *A,
523  const char *B,
524  const char *C...)
525 #else
526 tntStringArray tntStringArrayCreateStatic(const char *A, const char *B, const char *C, const char *D, const char *E, const char *F, const char *G, const char *H, const char *I, const char *J, const char *K, const char *L, const char *M, const char *N, const char *O, const char *P, const char *Q, const char *R, const char *S, const char *T, const char *U, const char *V, const char *W, const char *X)
527 #endif
528 {
529  const char *strings[24] = {A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X}; /* Array of the strings to add to the array */
530  tntStringArray arr; /* The array to return */
531  unsigned numstrings=0, k; /* Number of strings in the array, loop counter */
532
533  TNT_ERR_RET_DEFS
534
535
536  /* Count the number of non-NULL arguments */
537  for (k = 0; k < 24; k++) {
538  if (NULL != strings[k]) numstrings++;
539  }
540
541  /* allocate an array of that size */
542  chk = arr.vals = malloc(numstrings*sizeof(char *));
543  TNT_PUB_MEM_CHK /* NO_COVERAGE */
544
545  arr.sz = numstrings;
546
547  /* Set all values to be a string (character array) of length TNT_STRLEN */
548  for (k = 0; k < numstrings; k++) {
549  chk = arr.vals[k] = malloc(TNT_STRLEN*sizeof(char));
550  TNT_PUB_MEM_CHK /* NO_COVERAGE */
551  }
552
553  /* copy over strings */
554  numstrings = 0;
555  for (k = 0; k < 24; k++) {
556  if (NULL != strings[k]) {
557  strcpy(arr.vals[k], strings[numstrings]);
558  numstrings++;
559  }
560  }
561
562  return arr;
563 }
564
570 int tntComplexArrayIsReal(tntComplexArray *arr)
571 {
572  unsigned loop;
573
574  for (loop = 0; loop < arr->sz; loop++) {
575  if (fabs(arr->vals[loop].im/arr->vals[loop].re) > TNT_COMP_TOL) {
576  return 0;
577  }
578  }
579
580  return 1;
581 }
582
591 tntDoubleArray tntComplexArrayToReal(tntComplexArray *arr)
592 {
593  unsigned loop;
594  tntDoubleArray darr;
595
596  darr = tntDoubleMatrixAlloc(arr->numrows,arr->numcols);
597
598  if (tntComplexArrayIsReal(arr)) { /* If the whole array is real, then return real parts of all elements */
599  for (loop = 0; loop < arr->sz; loop++) {
600  darr.vals[loop] = arr->vals[loop].re;
601  }
602  } else { /* Otherwise return the absolute part of all the elements */
603  for (loop = 0; loop < arr->sz; loop++) {
604  darr.vals[loop] = sqrt(arr->vals[loop].re*arr->vals[loop].re + arr->vals[loop].im*arr->vals[loop].im);
605  }
606  }
607
608
609  tntComplexArrayFree(arr);
610
611  return darr;
612 }
613
614
620 void tntIntArrayFree(tntIntArray *arr)
621 {
622  if (arr->sz != 0) {
623  free(arr->vals);
624  arr->sz = 0;
625  arr->numrows = 0;
626  arr->numcols = 0;
627  }
628 }
629
635 void tntDoubleArrayFree(tntDoubleArray *arr)
636 {
637  if (arr->sz != 0) {
638  free(arr->vals);
639  arr->sz = 0;
640  arr->numrows = 0;
641  arr->numcols = 0;
642  }
643 }
644
650 void tntComplexArrayFree(tntComplexArray *arr)
651 {
652  if (arr->sz != 0) {
653  free(arr->vals);
654  arr->sz = 0;
655  arr->numrows = 0;
656  arr->numcols = 0;
657  }
658 }
659
668 void tntNodeArrayFree(tntNodeArray *arr)
669 {
670  TNT_ERR_RET_DEFS
671
672  ret = _tnt_tnarr_free(arr);
673  TNT_PUB_ERR_CHK /* NO_COVERAGE */
674 }
675
684 void tntStringArrayFree(tntStringArray *arr)
685 {
686  unsigned loop; /* used for looping over array elements */
687
688  /* Free all charachter arrays (or the dynamically allocated memory for the string itself) */
689  for (loop = 0; loop < arr->sz; loop++) {
690  free(arr->vals[loop]);
691  }
692
693  /* Free the array of strings */
694  if (arr->sz != 0) {
695  free(arr->vals);
696  arr->sz = 0;
697  }
698 }
699
700 /* internal function to parse the array string */
701 TNT_int_err _tnt_get_array_elems(const char *array_string, char ***stringelemsp, unsigned *Mp, unsigned *Np, unsigned *szp) {
702
703  char *str_part, *str;
704  char **stringelems;
705  unsigned m, n, M, N, sz;
706  TNT_ERR_RET_DEFS
707
708  str = malloc(sizeof(char) * TNT_STRLEN);
709  /* copy the string to a new array (which is not of type const) */
710  strcpy(str, array_string);
711
712  /* Count the number of rows and number of total elements */
713  M = 1;
714
715  /* count the number of rows */
716  str_part = strpbrk(array_string, ";");
717  while (str_part != NULL) {
718  str_part = strpbrk(str_part+1,";");
719  M++;
720  }
721
722  /* Split the copy of the string into tokens */
723  str_part = strtok(str," ,;");
724  sz = 0;
725  while (str_part != NULL) {
726  sz++;
727  str_part = strtok(NULL, " ,;");
728  }
729
730  /* Check that the sz is divisible by the number of rows */
731  if (sz%M) {
732  sprintf(tnt_err.errinfostr,"Invalid array string %s |"
733  "Check that the number of columns is the same for each row",
734  array_string); /* NO_COVERAGE */
735  return TNT_ERR_GEN;
736  }
737
738  /* Number of columns */
739  N = sz/M;
740
741  /* Allocate a new string for each element of the matrix */
742  chk = stringelems = malloc(sz * sizeof(char *));
743  TNT_PUB_MEM_CHK /* NO_COVERAGE */
744
745  /* split the string into tokens again, copying each token into the correct part of the array */
746  strcpy(str, array_string); for (m = 0; m < M; m++) {
747  for (n = 0; n < N; n++) {
748  if (0 == m && 0 == n) {
749  stringelems[m + M*n] = strtok(str, " ,;");
750  } else {
751  stringelems[m + M*n] = strtok(NULL," ,;");
752  }
753  }
754  }
755
756  /* allocate memory for the array */
757  *szp = sz;
758  *Mp = M;
759  *Np = N;
760  *stringelemsp = stringelems;
761
762  return TNT_SUCCESS;
763 }
764
int tntComplexArrayIsReal(tntComplexArray *arr)
Definition: tntArray.c:570
void tntNodeArrayFree(tntNodeArray *arr)
Definition: tntArray.c:668
tntComplexArray tntComplexArrayCreateDiag(const char *array_string, int offs)
Definition: tntArray.c:316
tntIntArray tntIntArrayAlloc(unsigned numrows, unsigned numcols)
Definition: tntArray.c:29
tntDoubleArray tntComplexArrayToReal(tntComplexArray *arr)
Definition: tntArray.c:591
tntStringArray tntStringArrayCreate(const char *A, const char *B, const char *C...)
Definition: tntArray.c:522
tntComplexArray tntComplexArrayAlloc(unsigned numrows, unsigned numcols)
Definition: tntArray.c:392
tntComplexArray tntComplexArrayCreate(const char *array_string)
Definition: tntArray.c:165
void tntStringArrayFree(tntStringArray *arr)
Definition: tntArray.c:684
tntComplex tntAtoC(const char *str)
Definition: tntUtil.c:123
tntDoubleArray tntDoubleArrayCreateDiag(const char *array_string, int offs)
Definition: tntArray.c:262
void tntIntArrayFree(tntIntArray *arr)
Definition: tntArray.c:620
tntIntArray tntIntArrayCreate(const char *array_string)
Definition: tntArray.c:70
tntNodeArray tntNodeArrayCreate(tntNode A, tntNode B, tntNode C...)
Definition: tntArray.c:450
tntIntArray tntIntArrayCreateDiag(const char *array_string, int offs)
Definition: tntArray.c:208
tntNode tntNodeCopy(tntNode A)
Definition: tntNodeUtil.c:305
tntDoubleArray tntDoubleArrayAlloc(unsigned numrows, unsigned numcols)
Definition: tntArray.c:363
tntNodeArray tntNodeArrayAlloc(unsigned num_elems)
Definition: tntArray.c:428
tntDoubleArray tntDoubleArrayCreate(const char *array_string)
Definition: tntArray.c:118
void tntComplexArrayFree(tntComplexArray *arr)
Definition: tntArray.c:650
tntStringArray tntStringArrayAlloc(unsigned num_elems)
Definition: tntArray.c:492
void tntDoubleArrayFree(tntDoubleArray *arr)
Definition: tntArray.c:635
Definition: tnt.h:65