sparse_matrix.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /*****************************************************************************
  2. *
  3. * MODULE: Grass Gmath Library
  4. * AUTHOR(S): Soeren Gebbert, Berlin (GER) Dec 2006
  5. * soerengebbert <at> gmx <dot> de
  6. *
  7. * PURPOSE: functions to manage linear equation systems
  8. * part of the gmath library
  9. *
  10. * COPYRIGHT: (C) 2000 by the GRASS Development Team
  11. *
  12. * This program is free software under the GNU General Public
  13. * License (>=v2). Read the file COPYING that comes with GRASS
  14. * for details.
  15. *
  16. *****************************************************************************/
  17. #include <stdlib.h>
  18. #include <math.h>
  19. #include <grass/gmath.h>
  20. #include <grass/gis.h>
  21. /*!
  22. * \brief Adds a sparse vector to a sparse matrix at position row
  23. *
  24. * Return 1 for success and -1 for failure
  25. *
  26. * \param Asp G_math_spvector **
  27. * \param spvector G_math_spvector *
  28. * \param row int
  29. * \return int 1 success, -1 failure
  30. *
  31. * */
  32. int G_math_add_spvector(G_math_spvector ** Asp, G_math_spvector * spvector,
  33. int row)
  34. {
  35. if (Asp != NULL) {
  36. G_debug(5,
  37. "Add sparse vector %p to the sparse linear equation system at row %i\n",
  38. spvector, row);
  39. Asp[row] = spvector;
  40. }
  41. else {
  42. return -1;
  43. }
  44. return 1;
  45. }
  46. /*!
  47. * \brief Allocate memory for a sparse matrix
  48. *
  49. * \param rows int
  50. * \return G_math_spvector **
  51. *
  52. * */
  53. G_math_spvector **G_math_alloc_spmatrix(int rows)
  54. {
  55. G_math_spvector **spmatrix;
  56. G_debug(4, "Allocate memory for a sparse matrix with %i rows\n", rows);
  57. spmatrix = (G_math_spvector **) G_calloc(rows, sizeof(G_math_spvector *));
  58. return spmatrix;
  59. }
  60. /*!
  61. * \brief Allocate memory for a sparse vector
  62. *
  63. * \param cols int
  64. * \return G_math_spvector *
  65. *
  66. * */
  67. G_math_spvector *G_math_alloc_spvector(int cols)
  68. {
  69. G_math_spvector *spvector;
  70. G_debug(4, "Allocate memory for a sparse vector with %i cols\n", cols);
  71. spvector = (G_math_spvector *) G_calloc(1, sizeof(G_math_spvector));
  72. spvector->cols = cols;
  73. spvector->index = (unsigned int *)G_calloc(cols, sizeof(unsigned int));
  74. spvector->values = (double *)G_calloc(cols, sizeof(double));
  75. return spvector;
  76. }
  77. /*!
  78. * \brief Release the memory of the sparse vector
  79. *
  80. * \param spvector G_math_spvector *
  81. * \return void
  82. *
  83. * */
  84. void G_math_free_spvector(G_math_spvector * spvector)
  85. {
  86. if (spvector) {
  87. if (spvector->values)
  88. G_free(spvector->values);
  89. if (spvector->index)
  90. G_free(spvector->index);
  91. G_free(spvector);
  92. spvector = NULL;
  93. }
  94. return;
  95. }
  96. /*!
  97. * \brief Release the memory of the sparse matrix
  98. *
  99. * \param Asp G_math_spvector **
  100. * \param rows int
  101. * \return void
  102. *
  103. * */
  104. void G_math_free_spmatrix(G_math_spvector ** Asp, int rows)
  105. {
  106. int i;
  107. if (Asp) {
  108. for (i = 0; i < rows; i++)
  109. G_math_free_spvector(Asp[i]);
  110. G_free(Asp);
  111. Asp = NULL;
  112. }
  113. return;
  114. }
  115. /*!
  116. *
  117. * \brief print the sparse matrix Asp to stdout
  118. *
  119. *
  120. * \param Asp (G_math_spvector **)
  121. * \param rows (int)
  122. * \return void
  123. *
  124. * */
  125. void G_math_print_spmatrix(G_math_spvector ** Asp, int rows)
  126. {
  127. int i, j, k, out;
  128. for (i = 0; i < rows; i++) {
  129. for (j = 0; j < rows; j++) {
  130. out = 0;
  131. for (k = 0; k < Asp[i]->cols; k++) {
  132. if (Asp[i]->index[k] == j) {
  133. fprintf(stdout, "%4.5f ", Asp[i]->values[k]);
  134. out = 1;
  135. }
  136. }
  137. if (!out)
  138. fprintf(stdout, "%4.5f ", 0.0);
  139. }
  140. fprintf(stdout, "\n");
  141. }
  142. return;
  143. }
  144. /*!
  145. * \brief Convert a sparse matrix into a quadratic matrix
  146. *
  147. * This function is multi-threaded with OpenMP. It creates its own parallel OpenMP region.
  148. *
  149. * \param Asp (G_math_spvector **)
  150. * \param rows (int)
  151. * \return (double **)
  152. *
  153. * */
  154. double **G_math_Asp_to_A(G_math_spvector ** Asp, int rows)
  155. {
  156. int i, j;
  157. double **A = NULL;
  158. A = G_alloc_matrix(rows, rows);
  159. #pragma omp parallel for schedule (static) private(i, j)
  160. for (i = 0; i < rows; i++) {
  161. for (j = 0; j < Asp[i]->cols; j++) {
  162. A[i][Asp[i]->index[j]] = Asp[i]->values[j];
  163. }
  164. }
  165. return A;
  166. }
  167. /*!
  168. * \brief Convert a quadratic matrix into a sparse matrix
  169. *
  170. * This function is multi-threaded with OpenMP. It creates its own parallel OpenMP region.
  171. *
  172. * \param A (double **)
  173. * \param rows (int)
  174. * \param epsilon (double) -- non-zero values are greater then epsilon
  175. * \return (G_math_spvector **)
  176. *
  177. * */
  178. G_math_spvector **G_math_A_to_Asp(double **A, int rows, double epsilon)
  179. {
  180. int i, j;
  181. int nonull, count = 0;
  182. G_math_spvector **Asp = NULL;
  183. Asp = G_math_alloc_spmatrix(rows);
  184. #pragma omp parallel for schedule (static) private(i, j, nonull, count)
  185. for (i = 0; i < rows; i++) {
  186. nonull = 0;
  187. /*Count the number of non zero entries */
  188. for (j = 0; j < rows; j++) {
  189. if (A[i][j] > epsilon)
  190. nonull++;
  191. }
  192. /*Allocate the sparse vector and insert values */
  193. G_math_spvector *v = G_math_alloc_spvector(nonull);
  194. count = 0;
  195. for (j = 0; j < rows; j++) {
  196. if (A[i][j] > epsilon) {
  197. v->index[count] = j;
  198. v->values[count] = A[i][j];
  199. count++;
  200. }
  201. }
  202. /*Add vector to sparse matrix */
  203. G_math_add_spvector(Asp, v, i);
  204. }
  205. return Asp;
  206. }