matrix.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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. /*!
  36. * \brief Creates system of linear equations from interpolated points
  37. *
  38. * Creates system of linear equations represented by matrix using given
  39. * points and interpolating function interp()
  40. *
  41. * \param params struct interp_params *
  42. * \param points points for interpolation as struct triple
  43. * \param n_points number of points
  44. * \param[out] matrix the matrix
  45. * \param indx
  46. *
  47. * \return -1 on failure, 1 on success
  48. */
  49. int IL_matrix_create(struct interp_params *params,
  50. struct triple *points, /* points for interpolation */
  51. int n_points, /* number of points */
  52. double **matrix, /* matrix */
  53. int *indx)
  54. {
  55. double xx, yy;
  56. double rfsta2, r;
  57. double d;
  58. int n1, k1, k2, k, i1, l, m, i, j;
  59. double fstar2 = params->fi * params->fi / 4.;
  60. static double *A = NULL;
  61. double RO, amaxa;
  62. double rsin = 0, rcos = 0, teta, scale = 0; /*anisotropy parameters - added by JH 2002 */
  63. double xxr, yyr;
  64. if (params->theta) {
  65. teta = params->theta * (M_PI / 180); /* deg to rad */
  66. rsin = sin(teta);
  67. rcos = cos(teta);
  68. }
  69. if (params->scalex)
  70. scale = params->scalex;
  71. n1 = n_points + 1;
  72. if (!A) {
  73. if (!
  74. (A =
  75. G_alloc_vector((params->KMAX2 + 2) * (params->KMAX2 + 2) + 1))) {
  76. fprintf(stderr, "Cannot allocate memory for A\n");
  77. return -1;
  78. }
  79. }
  80. /*
  81. C GENERATION OF MATRIX
  82. C FIRST COLUMN
  83. */
  84. A[1] = 0.;
  85. for (k = 1; k <= n_points; k++) {
  86. i1 = k + 1;
  87. A[i1] = 1.;
  88. }
  89. /*
  90. C OTHER COLUMNS
  91. */
  92. RO = -params->rsm;
  93. /* fprintf (stderr, "sm[%d] = %f, ro=%f\n", 1, points[1].smooth, RO); */
  94. for (k = 1; k <= n_points; k++) {
  95. k1 = k * n1 + 1;
  96. k2 = k + 1;
  97. i1 = k1 + k;
  98. if (params->rsm < 0.) { /*indicates variable smoothing */
  99. A[i1] = -points[k - 1].sm; /* added by Mitasova nov. 96 */
  100. /* G_debug(5, "sm[%d]=%f, a=%f", k, points[k-1].sm, A[i1]); */
  101. }
  102. else {
  103. A[i1] = RO; /* constant smoothing */
  104. }
  105. /* if (i1 == 100) fprintf (stderr,i "A[%d] = %f\n", i1, A[i1]); */
  106. /* A[i1] = RO; */
  107. for (l = k2; l <= n_points; l++) {
  108. xx = points[k - 1].x - points[l - 1].x;
  109. yy = points[k - 1].y - points[l - 1].y;
  110. if ((params->theta) && (params->scalex)) {
  111. /* re run anisotropy */
  112. xxr = xx * rcos + yy * rsin;
  113. yyr = yy * rcos - xx * rsin;
  114. xx = xxr;
  115. yy = yyr;
  116. r = scale * xx * xx + yy * yy;
  117. rfsta2 = fstar2 * (scale * xx * xx + yy * yy);
  118. }
  119. else {
  120. r = xx * xx + yy * yy;
  121. rfsta2 = fstar2 * (xx * xx + yy * yy);
  122. }
  123. if (rfsta2 == 0.) {
  124. fprintf(stderr, "ident. points in segm.\n");
  125. fprintf(stderr, "x[%d]=%f, x[%d]=%f, y[%d]=%f, y[%d]=%f\n",
  126. k - 1, points[k - 1].x, l - 1, points[l - 1].x, k - 1,
  127. points[k - 1].y, l - 1, points[l - 1].y);
  128. return -1;
  129. }
  130. i1 = k1 + l;
  131. A[i1] = params->interp(r, params->fi);
  132. }
  133. }
  134. /* C SYMMETRISATION */
  135. amaxa = 1.;
  136. for (k = 1; k <= n1; k++) {
  137. k1 = (k - 1) * n1;
  138. k2 = k + 1;
  139. for (l = k2; l <= n1; l++) {
  140. m = (l - 1) * n1 + k;
  141. A[m] = A[k1 + l];
  142. amaxa = amax1(A[m], amaxa);
  143. }
  144. }
  145. m = 0;
  146. for (i = 0; i <= n_points; i++) {
  147. for (j = 0; j <= n_points; j++) {
  148. m++;
  149. matrix[i][j] = A[m];
  150. }
  151. }
  152. G_debug(3, "calling G_ludcmp() n=%d indx=%d", n_points, *indx);
  153. if (G_ludcmp(matrix, n_points + 1, indx, &d) <= 0) {
  154. /* find the inverse of the matrix */
  155. fprintf(stderr, "G_ludcmp() failed! n=%d d=%.2f\n", n_points, d);
  156. return -1;
  157. }
  158. /* G_free_vector(A); */
  159. return 1;
  160. }