symmetric_band_matrix.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include <grass/gis.h>
  5. #include <grass/gmath.h>
  6. #include <grass/glocale.h>
  7. /**
  8. * \brief Convert a symmetrix matrix into a symmetric band matrix
  9. *
  10. * \verbatim
  11. Symmetric matrix with bandwidth of 3
  12. 5 2 1 0
  13. 2 5 2 1
  14. 1 2 5 2
  15. 0 1 2 5
  16. will be converted into the symmetric band matrix
  17. 5 2 1
  18. 5 2 1
  19. 5 2 0
  20. 5 0 0
  21. \endverbatim
  22. * \param A (double**) the symmetric matrix
  23. * \param rows (int)
  24. * \param bandwidth (int)
  25. * \return B (double**) new created symmetric band matrix
  26. * */
  27. double **G_math_matrix_to_sband_matrix(double **A, int rows, int bandwidth)
  28. {
  29. int i, j;
  30. double **B = G_alloc_matrix(rows, bandwidth);
  31. double tmp;
  32. for(i = 0; i < rows; i++) {
  33. for(j = 0; j < bandwidth; j++) {
  34. if(i + j < rows) {
  35. tmp = A[i][i + j];
  36. B[i][j] = tmp;
  37. } else {
  38. B[i][j] = 0.0;
  39. }
  40. }
  41. }
  42. return B;
  43. }
  44. /**
  45. * \brief Convert a symmetric band matrix into a symmetric matrix
  46. *
  47. * \verbatim
  48. Such a symmetric band matrix with banwidth 3
  49. 5 2 1
  50. 5 2 1
  51. 5 2 0
  52. 5 0 0
  53. Will be converted into this symmetric matrix
  54. 5 2 1 0
  55. 2 5 2 1
  56. 1 2 5 2
  57. 0 1 2 5
  58. \endverbatim
  59. * \param A (double**) the symmetric band matrix
  60. * \param rows (int)
  61. * \param bandwidth (int)
  62. * \return B (double**) new created symmetric matrix
  63. * */
  64. double **G_math_sband_matrix_to_matrix(double **A, int rows, int bandwidth)
  65. {
  66. int i, j;
  67. double **B = G_alloc_matrix(rows, rows);
  68. double tmp;
  69. for(i = 0; i < rows; i++) {
  70. for(j = 0; j < bandwidth; j++) {
  71. tmp = A[i][j];
  72. if(i + j < rows) {
  73. B[i][i + j] = tmp;
  74. }
  75. }
  76. }
  77. /*Symmetry*/
  78. for(i = 0; i < rows; i++) {
  79. for(j = i; j < rows; j++) {
  80. B[j][i] = B[i][j];
  81. }
  82. }
  83. return B;
  84. }
  85. /*!
  86. * \brief Compute the matrix - vector product
  87. * of symmetric band matrix A and vector x.
  88. *
  89. * This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
  90. *
  91. * y = A * x
  92. *
  93. *
  94. * \param A (double **)
  95. * \param x (double) *)
  96. * \param y (double * )
  97. * \param rows (int)
  98. * \param bandwidth (int)
  99. * \return (void)
  100. *
  101. * */
  102. void G_math_Ax_sband(double ** A, double *x, double *y, int rows, int bandwidth)
  103. {
  104. int i, j;
  105. double tmp;
  106. #pragma omp for schedule (static) private(i, j, tmp)
  107. for (i = 0; i < rows; i++) {
  108. tmp = 0;
  109. for (j = 0; j < bandwidth; j++) {
  110. if((i + j) < rows)
  111. tmp += A[i][j]*x[i + j];
  112. }
  113. y[i] = tmp;
  114. }
  115. #pragma omp single
  116. {
  117. for (i = 0; i < rows; i++) {
  118. tmp = 0;
  119. for (j = 1; j < bandwidth; j++) {
  120. if(i + j < rows)
  121. y[i + j] += A[i][j]*x[i];
  122. }
  123. }
  124. }
  125. return;
  126. }