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
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 
14 #include "../headers/tnt_int.h"
15 #include "../headers/dec_public.h"
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 
tntNode tntNodeCopy(tntNode A)
Definition: tntNodeUtil.c:304
void tntNodeArrayFree(tntNodeArray *arr)
Definition: tntArray.c:668
tntComplexArray tntComplexArrayCreateDiag(const char *array_string, int offs)
Definition: tntArray.c:316
tntIntArray tntIntArrayCreateDiag(const char *array_string, int offs)
Definition: tntArray.c:208
int tntComplexArrayIsReal(tntComplexArray *arr)
Definition: tntArray.c:570
void tntStringArrayFree(tntStringArray *arr)
Definition: tntArray.c:684
tntDoubleArray tntDoubleArrayAlloc(unsigned numrows, unsigned numcols)
Definition: tntArray.c:363
tntNodeArray tntNodeArrayAlloc(unsigned num_elems)
Definition: tntArray.c:428
tntDoubleArray tntComplexArrayToReal(tntComplexArray *arr)
Definition: tntArray.c:591
tntDoubleArray tntDoubleArrayCreate(const char *array_string)
Definition: tntArray.c:118
tntDoubleArray tntDoubleArrayCreateDiag(const char *array_string, int offs)
Definition: tntArray.c:262
tntComplexArray tntComplexArrayAlloc(unsigned numrows, unsigned numcols)
Definition: tntArray.c:392
Definition: tnt.h:65
void tntIntArrayFree(tntIntArray *arr)
Definition: tntArray.c:620
void tntDoubleArrayFree(tntDoubleArray *arr)
Definition: tntArray.c:635
tntComplexArray tntComplexArrayCreate(const char *array_string)
Definition: tntArray.c:165
tntNodeArray tntNodeArrayCreate(tntNode A, tntNode B, tntNode C...)
Definition: tntArray.c:450
tntIntArray tntIntArrayAlloc(unsigned numrows, unsigned numcols)
Definition: tntArray.c:29
tntStringArray tntStringArrayCreate(const char *A, const char *B, const char *C...)
Definition: tntArray.c:522
tntComplex tntAtoC(const char *str)
Definition: tntUtil.c:123
void tntComplexArrayFree(tntComplexArray *arr)
Definition: tntArray.c:650
tntStringArray tntStringArrayAlloc(unsigned num_elems)
Definition: tntArray.c:492
tntIntArray tntIntArrayCreate(const char *array_string)
Definition: tntArray.c:70