inverse.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /* @(#)inverse.c 2.1 6/26/87 */
  2. #include <math.h>
  3. #include <grass/libtrans.h>
  4. #define EPSILON 1.0e-16
  5. /* DIM_matrix is defined in "libtrans.h" */
  6. #define N DIM_matrix
  7. /*
  8. * inverse: invert a square matrix (puts pivot elements on main diagonal).
  9. * returns arg2 as the inverse of arg1.
  10. *
  11. * This routine is based on a routine found in Andrei Rogers, "Matrix
  12. * Methods in Urban and Regional Analysis", (1971), pp. 143-153.
  13. */
  14. int inverse(double m[N][N])
  15. {
  16. int i, j, k, l, ir = 0, ic = 0;
  17. int ipivot[N], itemp[N][2];
  18. double pivot[N], t;
  19. double fabs();
  20. if (isnull(m))
  21. return (-1);
  22. /* initialization */
  23. for (i = 0; i < N; i++)
  24. ipivot[i] = 0;
  25. for (i = 0; i < N; i++) {
  26. t = 0.0; /* search for pivot element */
  27. for (j = 0; j < N; j++) {
  28. if (ipivot[j] == 1) /* found pivot */
  29. continue;
  30. for (k = 0; k < N; k++)
  31. switch (ipivot[k] - 1) {
  32. case 0:
  33. break;
  34. case -1:
  35. if (fabs(t) < fabs(m[j][k])) {
  36. ir = j;
  37. ic = k;
  38. t = m[j][k];
  39. }
  40. break;
  41. case 1:
  42. return (-1);
  43. break;
  44. default: /* shouldn't get here */
  45. return (-1);
  46. break;
  47. }
  48. }
  49. ipivot[ic] += 1;
  50. if (ipivot[ic] > 1) { /* check for dependency */
  51. return (-1);
  52. }
  53. /* interchange rows to put pivot element on diagonal */
  54. if (ir != ic)
  55. for (l = 0; l < N; l++) {
  56. t = m[ir][l];
  57. m[ir][l] = m[ic][l];
  58. m[ic][l] = t;
  59. }
  60. itemp[i][0] = ir;
  61. itemp[i][1] = ic;
  62. pivot[i] = m[ic][ic];
  63. /* check for zero pivot */
  64. if (fabs(pivot[i]) < EPSILON) {
  65. return (-1);
  66. }
  67. /* divide pivot row by pivot element */
  68. m[ic][ic] = 1.0;
  69. for (j = 0; j < N; j++)
  70. m[ic][j] /= pivot[i];
  71. /* reduce nonpivot rows */
  72. for (k = 0; k < N; k++)
  73. if (k != ic) {
  74. t = m[k][ic];
  75. m[k][ic] = 0.0;
  76. for (l = 0; l < N; l++)
  77. m[k][l] -= (m[ic][l] * t);
  78. }
  79. }
  80. /* interchange columns */
  81. for (i = 0; i < N; i++) {
  82. l = N - i - 1;
  83. if (itemp[l][0] == itemp[l][1])
  84. continue;
  85. ir = itemp[l][0];
  86. ic = itemp[l][1];
  87. for (k = 0; k < N; k++) {
  88. t = m[k][ir];
  89. m[k][ir] = m[k][ic];
  90. m[k][ic] = t;
  91. }
  92. }
  93. return 1;
  94. }
  95. #define ZERO 1.0e-8
  96. /*
  97. * isnull: returns 1 if matrix is null, else 0.
  98. */
  99. int isnull(double a[N][N])
  100. {
  101. register int i, j;
  102. double fabs();
  103. for (i = 0; i < N; i++)
  104. for (j = 0; j < N; j++)
  105. if ((fabs(a[i][j]) - ZERO) > ZERO)
  106. return 0;
  107. return 1;
  108. }