blas_level_3.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*****************************************************************************
  2. *
  3. * MODULE: Grass numerical math interface
  4. * AUTHOR(S): Soeren Gebbert, Berlin (GER) Dec 2006
  5. * soerengebbert <at> googlemail <dot> com
  6. *
  7. * PURPOSE: grass blas implementation
  8. * part of the gmath library
  9. *
  10. * COPYRIGHT: (C) 2010 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 <math.h>
  18. #include <unistd.h>
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <stdlib.h>
  22. #include <grass/gis.h>
  23. #include <grass/gmath.h>
  24. /*!
  25. * \brief Add two matrices and scale matrix A with the scalar a
  26. *
  27. * \f[ {\bf C} = a {\bf A} + {\bf B} \f]
  28. *
  29. * In case B == NULL, matrix A will be scaled by scalar a. \n
  30. * In case a == 1.0, a simple matrix addition is performed. \n
  31. * In case a == -1.0 matrix A is subtracted from matrix B. \n
  32. * The result is written into matrix C.
  33. *
  34. *
  35. * This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
  36. *
  37. * \param A (double **)
  38. * \param B (double **) if NULL, matrix A is scaled by scalar a only
  39. * \param a (double)
  40. * \param C (double **)
  41. * \param rows (int)
  42. * \param cols (int)
  43. * \return (void)
  44. *
  45. * */
  46. void G_math_d_aA_B(double **A, double **B, double a, double **C, int rows,
  47. int cols)
  48. {
  49. int i, j;
  50. /*If B is null, scale the matrix A with th scalar a */
  51. if (B == NULL) {
  52. #pragma omp for schedule (static) private(i, j)
  53. for (i = rows - 1; i >= 0; i--)
  54. for (j = cols - 1; j >= 0; j--)
  55. C[i][j] = a * A[i][j];
  56. return;
  57. }
  58. /*select special cases */
  59. if (a == 1.0) {
  60. #pragma omp for schedule (static) private(i, j)
  61. for (i = rows - 1; i >= 0; i--)
  62. for (j = cols - 1; j >= 0; j--)
  63. C[i][j] = A[i][j] + B[i][j];
  64. }
  65. else if (a == -1.0) {
  66. #pragma omp for schedule (static) private(i, j)
  67. for (i = rows - 1; i >= 0; i--)
  68. for (j = cols - 1; j >= 0; j--)
  69. C[i][j] = B[i][j] - A[i][j];
  70. }
  71. else {
  72. #pragma omp for schedule (static) private(i, j)
  73. for (i = rows - 1; i >= 0; i--)
  74. for (j = cols - 1; j >= 0; j--)
  75. C[i][j] = a * A[i][j] + B[i][j];
  76. }
  77. return;
  78. }
  79. /*!
  80. * \brief Add two matrices and scale matrix A with the scalar a
  81. *
  82. * \f[ {\bf C} = a {\bf A} + {\bf B} \f]
  83. *
  84. * In case B == NULL, matrix A will be scaled by scalar a. \n
  85. * In case a == 1.0, a simple matrix addition is performed. \n
  86. * In case a == -1.0 matrix A is subtracted from matrix B. \n
  87. * The result is written into matrix C.
  88. *
  89. *
  90. *
  91. * This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
  92. *
  93. * \param A (float **)
  94. * \param B (float **) if NULL, matrix A is scaled by scalar a only
  95. * \param a (float)
  96. * \param C (float **)
  97. * \param rows (int)
  98. * \param cols (int)
  99. * \return (void)
  100. *
  101. * */
  102. void G_math_f_aA_B(float **A, float **B, float a, float **C, int rows,
  103. int cols)
  104. {
  105. int i, j;
  106. /*If B is null, scale the matrix A with th scalar a */
  107. if (B == NULL) {
  108. #pragma omp for schedule (static) private(i, j)
  109. for (i = rows - 1; i >= 0; i--)
  110. for (j = cols - 1; j >= 0; j--)
  111. C[i][j] = a * A[i][j];
  112. return;
  113. }
  114. /*select special cases */
  115. if (a == 1.0) {
  116. #pragma omp for schedule (static) private(i, j)
  117. for (i = rows - 1; i >= 0; i--)
  118. for (j = cols - 1; j >= 0; j--)
  119. C[i][j] = A[i][j] + B[i][j];
  120. }
  121. else if (a == -1.0) {
  122. #pragma omp for schedule (static) private(i, j)
  123. for (i = rows - 1; i >= 0; i--)
  124. for (j = cols - 1; j >= 0; j--)
  125. C[i][j] = B[i][j] - A[i][j];
  126. }
  127. else {
  128. #pragma omp for schedule (static) private(i, j)
  129. for (i = rows - 1; i >= 0; i--)
  130. for (j = cols - 1; j >= 0; j--)
  131. C[i][j] = a * A[i][j] + B[i][j];
  132. }
  133. return;
  134. }
  135. /*!
  136. * \brief Matrix multiplication
  137. *
  138. * \f[ {\bf C} = {\bf A}{\bf B} \f]
  139. *
  140. * The result is written into matrix C.
  141. *
  142. * A must be of size rows_A * cols_A
  143. * B must be of size rows_B * cols_B with rows_B == cols_A
  144. * C must be of size rows_A * cols_B
  145. *
  146. *
  147. * This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
  148. *
  149. * \param A (double **)
  150. * \param B (double **)
  151. * \param C (double **)
  152. * \param rows_A (int)
  153. * \param cols_A (int)
  154. * \param cols_B (int)
  155. * \return (void)
  156. *
  157. * */
  158. void G_math_d_AB(double **A, double **B, double **C, int rows_A,
  159. int cols_A, int cols_B)
  160. {
  161. int i, j, k;
  162. #pragma omp for schedule (static) private(i, j, k)
  163. for (i = 0; i < rows_A; i++) {
  164. for (j = 0; j < cols_B; j++) {
  165. C[i][j] = 0.0;
  166. for (k = cols_A - 1; k >= 0; k--) {
  167. C[i][j] += A[i][k] * B[k][j];
  168. }
  169. }
  170. }
  171. return;
  172. }
  173. /*!
  174. * \brief Matrix multiplication
  175. *
  176. * \f[ {\bf C} = {\bf A}{\bf B} \f]
  177. *
  178. * The result is written into matrix C.
  179. *
  180. * A must be of size rows_A * cols_A
  181. * B must be of size rows_B * cols_B with rows_B == cols_A
  182. * C must be of size rows_A * cols_B
  183. *
  184. *
  185. * This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
  186. *
  187. * \param A (float **)
  188. * \param B (float **)
  189. * \param C (float **)
  190. * \param rows_A (int)
  191. * \param cols_A (int)
  192. * \param cols_B (int)
  193. * \return (void)
  194. *
  195. * */
  196. void G_math_f_AB(float **A, float **B, float **C, int rows_A,
  197. int cols_A, int cols_B)
  198. {
  199. int i, j, k;
  200. #pragma omp for schedule (static) private(i, j, k)
  201. for (i = 0; i < rows_A; i++) {
  202. for (j = 0; j < cols_B; j++) {
  203. C[i][j] = 0.0;
  204. for (k = cols_A - 1; k >= 0; k--) {
  205. C[i][j] += A[i][k] * B[k][j];
  206. }
  207. }
  208. }
  209. return;
  210. }