matrix.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*!
  2. * \author
  3. * Lubos Mitas (original program and various modifications)
  4. *
  5. * \author
  6. * H. Mitasova,
  7. * I. Kosinovsky, D. Gerdes,
  8. * D. McCauley
  9. * (GRASS4.1 version of the program and GRASS4.2 modifications)
  10. *
  11. * \author
  12. * L. Mitas,
  13. * H. Mitasova,
  14. * I. Kosinovsky,
  15. * D.Gerdes,
  16. * D. McCauley
  17. * (1993, 1995)
  18. *
  19. * \author modified by McCauley in August 1995
  20. * \author modified by Mitasova in August 1995, Nov. 1996
  21. *
  22. * \copyright
  23. * (C) 1993-1996 by Lubos Mitas and the GRASS Development Team
  24. *
  25. * \copyright
  26. * This program is free software under the GNU General Public License (>=v2).
  27. * Read the file COPYING that comes with GRASS for details.
  28. */
  29. #include <stdio.h>
  30. #include <math.h>
  31. #include <unistd.h>
  32. #include <grass/gis.h>
  33. #include <grass/interpf.h>
  34. #include <grass/gmath.h>
  35. int IL_matrix_create(struct interp_params *params,
  36. struct triple *points, /* points for interpolation */
  37. int n_points, /* number of points */
  38. double **matrix, /* matrix */
  39. int *indx)
  40. {
  41. static double *A = NULL;
  42. if (!A) {
  43. if (!
  44. (A =
  45. G_alloc_vector((params->KMAX2 + 2) * (params->KMAX2 + 2) + 1))) {
  46. fprintf(stderr, "Cannot allocate memory for A\n");
  47. return -1;
  48. }
  49. }
  50. return IL_matrix_create_alloc(params, points, n_points, matrix, indx, A);
  51. }
  52. /*!
  53. * \brief Creates system of linear equations from interpolated points
  54. *
  55. * Creates system of linear equations represented by matrix using given
  56. * points and interpolating function interp()
  57. *
  58. * \param params struct interp_params *
  59. * \param points points for interpolation as struct triple
  60. * \param n_points number of points
  61. * \param[out] matrix the matrix
  62. * \param indx
  63. *
  64. * \return -1 on failure, 1 on success
  65. */
  66. int IL_matrix_create_alloc(struct interp_params *params,
  67. struct triple *points, /* points for interpolation */
  68. int n_points, /* number of points */
  69. double **matrix, /* matrix */
  70. int *indx,
  71. double *A /* temporary matrix unique for all threads */)
  72. {
  73. double xx, yy;
  74. double rfsta2, r;
  75. double d;
  76. int n1, k1, k2, k, i1, l, m, i, j;
  77. double fstar2 = params->fi * params->fi / 4.;
  78. double RO, amaxa;
  79. double rsin = 0, rcos = 0, teta, scale = 0; /*anisotropy parameters - added by JH 2002 */
  80. double xxr, yyr;
  81. if (params->theta) {
  82. teta = params->theta * (M_PI / 180); /* deg to rad */
  83. rsin = sin(teta);
  84. rcos = cos(teta);
  85. }
  86. if (params->scalex)
  87. scale = params->scalex;
  88. n1 = n_points + 1;
  89. /*
  90. C GENERATION OF MATRIX
  91. C FIRST COLUMN
  92. */
  93. A[1] = 0.;
  94. for (k = 1; k <= n_points; k++) {
  95. i1 = k + 1;
  96. A[i1] = 1.;
  97. }
  98. /*
  99. C OTHER COLUMNS
  100. */
  101. RO = -params->rsm;
  102. /* fprintf (stderr, "sm[%d] = %f, ro=%f\n", 1, points[1].smooth, RO); */
  103. for (k = 1; k <= n_points; k++) {
  104. k1 = k * n1 + 1;
  105. k2 = k + 1;
  106. i1 = k1 + k;
  107. if (params->rsm < 0.) { /*indicates variable smoothing */
  108. A[i1] = -points[k - 1].sm; /* added by Mitasova nov. 96 */
  109. /* G_debug(5, "sm[%d]=%f, a=%f", k, points[k-1].sm, A[i1]); */
  110. }
  111. else {
  112. A[i1] = RO; /* constant smoothing */
  113. }
  114. /* if (i1 == 100) fprintf (stderr,i "A[%d] = %f\n", i1, A[i1]); */
  115. /* A[i1] = RO; */
  116. for (l = k2; l <= n_points; l++) {
  117. xx = points[k - 1].x - points[l - 1].x;
  118. yy = points[k - 1].y - points[l - 1].y;
  119. if ((params->theta) && (params->scalex)) {
  120. /* re run anisotropy */
  121. xxr = xx * rcos + yy * rsin;
  122. yyr = yy * rcos - xx * rsin;
  123. xx = xxr;
  124. yy = yyr;
  125. r = scale * xx * xx + yy * yy;
  126. rfsta2 = fstar2 * (scale * xx * xx + yy * yy);
  127. }
  128. else {
  129. r = xx * xx + yy * yy;
  130. rfsta2 = fstar2 * (xx * xx + yy * yy);
  131. }
  132. if (rfsta2 == 0.) {
  133. fprintf(stderr, "ident. points in segm.\n");
  134. fprintf(stderr, "x[%d]=%f, x[%d]=%f, y[%d]=%f, y[%d]=%f\n",
  135. k - 1, points[k - 1].x, l - 1, points[l - 1].x, k - 1,
  136. points[k - 1].y, l - 1, points[l - 1].y);
  137. return -1;
  138. }
  139. i1 = k1 + l;
  140. A[i1] = params->interp(r, params->fi);
  141. }
  142. }
  143. /* C SYMMETRISATION */
  144. amaxa = 1.;
  145. for (k = 1; k <= n1; k++) {
  146. k1 = (k - 1) * n1;
  147. k2 = k + 1;
  148. for (l = k2; l <= n1; l++) {
  149. m = (l - 1) * n1 + k;
  150. A[m] = A[k1 + l];
  151. amaxa = amax1(A[m], amaxa);
  152. }
  153. }
  154. m = 0;
  155. for (i = 0; i <= n_points; i++) {
  156. for (j = 0; j <= n_points; j++) {
  157. m++;
  158. matrix[i][j] = A[m];
  159. }
  160. }
  161. G_debug(3, "calling G_ludcmp() n=%d indx=%d", n_points, *indx);
  162. if (G_ludcmp(matrix, n_points + 1, indx, &d) <= 0) {
  163. /* find the inverse of the matrix */
  164. fprintf(stderr, "G_ludcmp() failed! n=%d d=%.2f\n", n_points, d);
  165. return -1;
  166. }
  167. /* G_free_vector(A); */
  168. return 1;
  169. }