matrix.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*!
  2. Temelia - Matrix implementation source file.
  3. Copyright (C) 2008 Ceata (http://ceata.org/proiecte/temelia).
  4. @author Dascalu Laurentiu
  5. This program is free software; you can redistribute it and
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 3
  8. of the License, or (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. */
  17. #include "include/matrix.h"
  18. #include <stdlib.h>
  19. struct _matrix_t
  20. {
  21. /*! Number of columns */
  22. int columns;
  23. /*! Number of rows */
  24. int rows;
  25. /*! Elements of the matrix */
  26. void **data;
  27. };
  28. matrix_t matrix_new(int rows, int columns)
  29. {
  30. matrix_t mat;
  31. int i;
  32. LOGGER("[matrix new] rows %d, columns %d\n", rows, columns);
  33. _ASSERT(rows , <=, 0, INVALID_INPUT, NULL);
  34. _ASSERT(columns , <=, 0, INVALID_INPUT, NULL);
  35. mat = (struct _matrix_t *) _new(sizeof(struct _matrix_t));
  36. mat->rows = rows;
  37. mat->columns = columns;
  38. mat->data = (void **) _new(rows * columns * sizeof(void *));
  39. if (mat->data == NULL)
  40. {
  41. LOGGER("[matrix new] memory allocation failed\n");
  42. _delete(mat);
  43. return NULL;
  44. }
  45. for (i = 0; i < rows * columns; i++)
  46. mat->data[i] = NULL;
  47. LOGGER("[matrix new] succeed and returned %p, data %p\n", mat, mat->data);
  48. return mat;
  49. }
  50. matrix_t matrix_clone(matrix_t matrix)
  51. {
  52. matrix_t clone;
  53. int i, j;
  54. _ASSERT(matrix, ==, NULL, NULL_POINTER, NULL);
  55. clone = matrix_new(matrix->rows, matrix->columns);
  56. _ASSERT(clone, ==, NULL, NULL_POINTER, NULL);
  57. for (i = 0; i < matrix->rows; i++)
  58. for (j = 0; j < matrix->columns; j++)
  59. clone->data[i * matrix->columns + j] = matrix->data[i
  60. * matrix->columns + j];
  61. return clone;
  62. }
  63. matrix_t matrix_zeros(int rows, int columns)
  64. {
  65. matrix_t mat;
  66. int i, j;
  67. mat = matrix_new(rows, columns);
  68. _ASSERT(mat, ==, NULL, NULL_POINTER, NULL);
  69. for (i = 0; i < rows; i++)
  70. for (j = 0; j < columns; j++)
  71. mat->data[i * columns + j] = NULL;
  72. return mat;
  73. }
  74. void matrix_delete(matrix_t matrix)
  75. {
  76. _ASSERT(matrix , ==, NULL, NULL_POINTER,);
  77. _delete(matrix->data);
  78. matrix->columns = matrix->rows = 0;
  79. _delete(matrix);
  80. }
  81. void matrix_resize(matrix_t matrix, int rows, int columns)
  82. {
  83. void **data, *aux;
  84. int i, j;
  85. LOGGER("[matrix resize] matrix = %p, new_rows = %d, new_columns = %d\n",
  86. matrix, rows, columns);
  87. _ASSERT(matrix, ==, NULL, NULL_POINTER,);
  88. // I don't resize a matrix to a little dimension
  89. if (matrix->rows > rows || matrix->columns > columns)
  90. return;
  91. data = (void **) _new(rows * columns * sizeof(void *));
  92. _ASSERT(data, ==, NULL, NULL_POINTER,);
  93. LOGGER("[matrix resize] clearing new allocated matrix\n");
  94. for (i = 0; i < rows * columns; i++)
  95. data[i] = NULL;
  96. LOGGER("[matrix resize] copying to old matrix into new matrix\n");
  97. for (i = 0; i < matrix->rows; i++)
  98. for (j = 0; j < matrix->columns; j++)
  99. data[i * columns + j] = matrix->data[i * matrix->columns + j];
  100. LOGGER("[matrix resize] clearing the old resized matrix\n");
  101. aux = matrix->data;
  102. matrix->data = data;
  103. _delete(aux);
  104. matrix->columns = columns;
  105. matrix->rows = rows;
  106. }
  107. void matrix_set_key_at(matrix_t matrix, int row, int column, void *key)
  108. {
  109. LOGGER("[matrix set key at] matrix %p, row %d, column %d, key %p\n",
  110. matrix, row, column, key);
  111. _ASSERT(matrix, ==, NULL, NULL_POINTER,);
  112. _ASSERT(row, <, 0, INVALID_INPUT,);
  113. _ASSERT(row, >=, matrix->rows, INVALID_INPUT,);
  114. _ASSERT(column, <, 0, INVALID_INPUT,);
  115. _ASSERT(column, >=, matrix->columns, INVALID_INPUT,);
  116. matrix->data[row * matrix->columns + column] = key;
  117. }
  118. void *matrix_get_key_at(matrix_t matrix, int row, int column)
  119. {
  120. LOGGER("[matrix get key at] matrix %p, row %d, column %d\n", matrix, row,
  121. column);
  122. _ASSERT(matrix, ==, NULL, NULL_POINTER, NULL);
  123. _ASSERT(row, <, 0, INVALID_INPUT, NULL);
  124. _ASSERT(row, >=, matrix->rows, INVALID_INPUT, NULL);
  125. _ASSERT(column, <, 0, INVALID_INPUT, NULL);
  126. _ASSERT(column, >=, matrix->columns, INVALID_INPUT, NULL);
  127. return matrix->data[row * matrix->columns + column];
  128. }
  129. int matrix_get_rows_number(matrix_t matrix)
  130. {
  131. _ASSERT(matrix, ==, NULL, NULL_POINTER, -1);
  132. return matrix->rows;
  133. }
  134. int matrix_get_columns_number(matrix_t matrix)
  135. {
  136. _ASSERT(matrix, ==, NULL, NULL_POINTER, -1);
  137. return matrix->columns;
  138. }
  139. void *matrix_get_implementation(matrix_t matrix)
  140. {
  141. _ASSERT(matrix, ==, NULL, NULL_POINTER, NULL);
  142. return matrix->data;
  143. }
  144. void **matrix_get_row(matrix_t matrix, int row)
  145. {
  146. void **data;
  147. int i;
  148. _ASSERT(matrix, ==, NULL, NULL_POINTER, NULL);
  149. _ASSERT(row, <, 0, INVALID_INPUT, NULL);
  150. _ASSERT(row, >=, matrix->rows, INVALID_INPUT, NULL);
  151. data = (void **) _new(matrix->columns * sizeof(void *));
  152. _ASSERT(data, ==, NULL, NULL_POINTER, NULL);
  153. for (i = 0; i < matrix->columns; i++)
  154. data[i] = matrix->data[row * matrix->columns + i];
  155. return data;
  156. }
  157. void **matrix_get_column(matrix_t matrix, int column)
  158. {
  159. void **data;
  160. int i;
  161. _ASSERT(matrix, ==, NULL, NULL_POINTER, NULL);
  162. _ASSERT(column, <, 0, INVALID_INPUT, NULL);
  163. _ASSERT(column, >=, matrix->columns, INVALID_INPUT, NULL);
  164. data = (void **) _new(matrix->rows * sizeof(void *));
  165. _ASSERT(data, ==, NULL, NULL_POINTER, NULL);
  166. for (i = 0; i < matrix->rows; i++)
  167. data[i] = matrix->data[i * matrix->columns + column];
  168. return data;
  169. }
  170. void matrix_swap_rows(matrix_t matrix, int first_row, int second_row)
  171. {
  172. void *aux;
  173. int i;
  174. _ASSERT(matrix, ==, NULL, NULL_POINTER,);
  175. _ASSERT(first_row, <, 0, INVALID_INPUT,);
  176. _ASSERT(first_row, >=, matrix->rows, INVALID_INPUT,);
  177. _ASSERT(second_row, <, 0, INVALID_INPUT,);
  178. _ASSERT(second_row, >=, matrix->rows, INVALID_INPUT,);
  179. for (i = 0; i < matrix->columns; i++)
  180. {
  181. aux = matrix->data[first_row * matrix->columns + i];
  182. matrix->data[first_row * matrix->columns + i] = matrix->data[second_row
  183. * matrix->columns + i];
  184. matrix->data[second_row * matrix->columns + i] = aux;
  185. }
  186. }
  187. void matrix_swap_columns(matrix_t matrix, int first_column, int second_column)
  188. {
  189. void *aux;
  190. int i;
  191. _ASSERT(matrix, ==, NULL, NULL_POINTER,);
  192. _ASSERT(first_column, <, 0, INVALID_INPUT,);
  193. _ASSERT(first_column, >=, matrix->columns, INVALID_INPUT,);
  194. _ASSERT(second_column, <, 0, INVALID_INPUT,);
  195. _ASSERT(second_column, >=, matrix->columns, INVALID_INPUT,);
  196. for (i = 0; i < matrix->rows; i++)
  197. {
  198. aux = matrix->data[i * matrix->columns + first_column];
  199. matrix->data[i * matrix->columns + first_column] = matrix->data[i
  200. * matrix->columns + second_column];
  201. matrix->data[i * matrix->columns + second_column] = aux;
  202. }
  203. }
  204. matrix_t matrix_transpose(matrix_t matrix)
  205. {
  206. matrix_t transposed;
  207. int i, j;
  208. _ASSERT(matrix, ==, NULL, NULL_POINTER, NULL);
  209. transposed = matrix_new(matrix->columns, matrix->rows);
  210. for (i = 0; i < matrix->rows; i++)
  211. for (j = 0; j < matrix->columns; j++)
  212. transposed->data[j * matrix->columns + i] = matrix->data[i * matrix->columns
  213. + j];
  214. return transposed;
  215. }
  216. void matrix_iterate(matrix_t matrix,
  217. void key_handler(void *key, void *context), void *context)
  218. {
  219. int i, j;
  220. _ASSERT(matrix, ==, NULL, NULL_POINTER,);
  221. _ASSERT(key_handler, ==, NULL, NULL_POINTER,);
  222. for (i = 0; i < matrix->rows; i++)
  223. for (j = 0; j < matrix->columns; j++)
  224. key_handler(matrix->data[i * matrix->columns + j], context);
  225. }