tutadv.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /* routines from the section 8 of tutorial.txt */
  2. #include "matrix.h"
  3. #define M3D_LIST 3 /* list number */
  4. #define TYPE_MAT3D 0 /* the number of a type */
  5. /* type for 3 dimensional matrices */
  6. typedef struct {
  7. int l,m,n; /* actual dimensions */
  8. int max_l, max_m, max_n; /* maximal dimensions */
  9. Real ***me; /* pointer to matrix elements */
  10. /* we do not consider segmented memory */
  11. Real *base, **me2d; /* me and me2d are additional pointers
  12. to base */
  13. } MAT3D;
  14. /* function for creating a variable of MAT3D type */
  15. MAT3D *m3d_get(l,m,n)
  16. int l,m,n;
  17. {
  18. MAT3D *mat;
  19. int i,j,k;
  20. /* check if arguments are positive */
  21. if (l <= 0 || m <= 0 || n <= 0)
  22. error(E_NEG,"m3d_get");
  23. /* new structure */
  24. if ((mat = NEW(MAT3D)) == (MAT3D *)NULL)
  25. error(E_MEM,"m3d_get");
  26. else if (mem_info_is_on()) {
  27. /* record how many bytes is allocated */
  28. mem_bytes_list(TYPE_MAT3D,0,sizeof(MAT3D),M3D_LIST);
  29. /* record a new allocated variable */
  30. mem_numvar_list(TYPE_MAT3D,1,M3D_LIST);
  31. }
  32. mat->l = mat->max_l = l;
  33. mat->m = mat->max_m = m;
  34. mat->n = mat->max_n = n;
  35. /* allocate memory for 3D array */
  36. if ((mat->base = NEW_A(l*m*n,Real)) == (Real *)NULL)
  37. error(E_MEM,"m3d_get");
  38. else if (mem_info_is_on())
  39. mem_bytes_list(TYPE_MAT3D,0,l*m*n*sizeof(Real),M3D_LIST);
  40. /* allocate memory for 2D pointers */
  41. if ((mat->me2d = NEW_A(l*m,Real *)) == (Real **)NULL)
  42. error(E_MEM,"m3d_get");
  43. else if (mem_info_is_on())
  44. mem_bytes_list(TYPE_MAT3D,0,l*m*sizeof(Real *),M3D_LIST);
  45. /* allocate memory for 1D pointers */
  46. if ((mat->me = NEW_A(l,Real **)) == (Real ***)NULL)
  47. error(E_MEM,"m3d_get");
  48. else if (mem_info_is_on())
  49. mem_bytes_list(TYPE_MAT3D,0,l*sizeof(Real **),M3D_LIST);
  50. /* pointers to 2D matrices */
  51. for (i=0,k=0; i < l; i++)
  52. for (j=0; j < m; j++)
  53. mat->me2d[k++] = &mat->base[(i*m+j)*n];
  54. /* pointers to rows */
  55. for (i=0; i < l; i++)
  56. mat->me[i] = &mat->me2d[i*m];
  57. return mat;
  58. }
  59. /* deallocate a variable of type MAT3D */
  60. int m3d_free(mat)
  61. MAT3D *mat;
  62. {
  63. /* do not try to deallocate the NULL pointer */
  64. if (mat == (MAT3D *)NULL)
  65. return -1;
  66. /* first deallocate base */
  67. if (mat->base != (Real *)NULL) {
  68. if (mem_info_is_on())
  69. /* record how many bytes is deallocated */
  70. mem_bytes_list(TYPE_MAT3D,mat->max_l*mat->max_m*mat->max_n*sizeof(Real),
  71. 0,M3D_LIST);
  72. free((char *)mat->base);
  73. }
  74. /* deallocate array of 2D pointers */
  75. if (mat->me2d != (Real **)NULL) {
  76. if (mem_info_is_on())
  77. /* record how many bytes is deallocated */
  78. mem_bytes_list(TYPE_MAT3D,mat->max_l*mat->max_m*sizeof(Real *),
  79. 0,M3D_LIST);
  80. free((char *)mat->me2d);
  81. }
  82. /* deallocate array of 1D pointers */
  83. if (mat->me != (Real ***)NULL) {
  84. if (mem_info_is_on())
  85. /* record how many bytes is deallocated */
  86. mem_bytes_list(TYPE_MAT3D,mat->max_l*sizeof(Real **),0,M3D_LIST);
  87. free((char *)mat->me);
  88. }
  89. /* deallocate MAT3D structure */
  90. if (mem_info_is_on()) {
  91. mem_bytes_list(TYPE_MAT3D,sizeof(MAT3D),0,M3D_LIST);
  92. mem_numvar_list(TYPE_MAT3D,-1,M3D_LIST);
  93. }
  94. free((char *)mat);
  95. return 0;
  96. }
  97. /*=============================================*/
  98. char *m3d_names[] = {
  99. "MAT3D"
  100. };
  101. #define M3D_NUM (sizeof(m3d_names)/sizeof(*m3d_names))
  102. int (*m3d_free_funcs[M3D_NUM])() = {
  103. m3d_free
  104. };
  105. static MEM_ARRAY m3d_sum[M3D_NUM];
  106. /* test routing for allocating/deallocating static variables */
  107. void test_stat(k)
  108. int k;
  109. {
  110. static MAT3D *work;
  111. if (!work) {
  112. work = m3d_get(10,10,10);
  113. mem_stat_reg_list((void **)&work,TYPE_MAT3D,M3D_LIST);
  114. work->me[9][9][9] = -3.14;
  115. }
  116. if (k == 9)
  117. printf(" work[9][9][9] = %g\n",work->me[9][9][9]);
  118. }
  119. void main()
  120. {
  121. MAT3D *M;
  122. int i,j,k;
  123. mem_info_on(TRUE);
  124. /* can be the first command */
  125. mem_attach_list(M3D_LIST,M3D_NUM,m3d_names,m3d_free_funcs,m3d_sum);
  126. M = m3d_get(3,4,5);
  127. mem_info_file(stdout,M3D_LIST);
  128. /* make use of M->me[i][j][k], where i,j,k are non-negative and
  129. i < 3, j < 4, k < 5 */
  130. mem_stat_mark(1);
  131. for (i=0; i < 3; i++)
  132. for (j=0; j < 4; j++)
  133. for (k=0; k < 5; k++) {
  134. test_stat(i+j+k);
  135. M->me[i][j][k] = i+j+k;
  136. }
  137. mem_stat_free_list(1,M3D_LIST);
  138. mem_info_file(stdout,M3D_LIST);
  139. printf(" M[%d][%d][%d] = %g\n",2,3,4,M->me[2][3][4]);
  140. mem_stat_mark(2);
  141. test_stat(9);
  142. mem_stat_free_list(2,M3D_LIST);
  143. m3d_free(M); /* if M is not necessary */
  144. mem_info_file(stdout,M3D_LIST);
  145. }