eigen_tools.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #include <grass/gis.h>
  2. #include <math.h>
  3. #define MAX_ITERS 30
  4. #define SIGN(a,b) ((b)<0 ? -fabs(a) : fabs(a))
  5. int G_tqli(double d[], double e[], int n, double **z)
  6. {
  7. int m, l, iter, i, k;
  8. double s, r, p, g, f, dd, c, b;
  9. for (i = 1; i < n; i++)
  10. e[i - 1] = e[i];
  11. e[n - 1] = 0.0;
  12. for (l = 0; l < n; l++) {
  13. iter = 0;
  14. do {
  15. for (m = l; m < n - 1; m++) {
  16. dd = fabs(d[m]) + fabs(d[m + 1]);
  17. if (fabs(e[m]) + dd == dd)
  18. break;
  19. }
  20. if (m != l) {
  21. if (iter++ == MAX_ITERS)
  22. return 0; /* Too many iterations in TQLI */
  23. g = (d[l + 1] - d[l]) / (2.0 * e[l]);
  24. r = sqrt((g * g) + 1.0);
  25. g = d[m] - d[l] + e[l] / (g + SIGN(r, g));
  26. s = c = 1.0;
  27. p = 0.0;
  28. for (i = m - 1; i >= l; i--) {
  29. f = s * e[i];
  30. b = c * e[i];
  31. if (fabs(f) >= fabs(g)) {
  32. c = g / f;
  33. r = sqrt((c * c) + 1.0);
  34. e[i + 1] = f * r;
  35. c *= (s = 1.0 / r);
  36. }
  37. else {
  38. s = f / g;
  39. r = sqrt((s * s) + 1.0);
  40. e[i + 1] = g * r;
  41. s *= (c = 1.0 / r);
  42. }
  43. g = d[i + 1] - p;
  44. r = (d[i] - g) * s + 2.0 * c * b;
  45. p = s * r;
  46. d[i + 1] = g + p;
  47. g = c * r - b;
  48. /* Next loop can be omitted if eigenvectors not wanted */
  49. for (k = 0; k < n; k++) {
  50. f = z[k][i + 1];
  51. z[k][i + 1] = s * z[k][i] + c * f;
  52. z[k][i] = c * z[k][i] - s * f;
  53. }
  54. }
  55. d[l] = d[l] - p;
  56. e[l] = g;
  57. e[m] = 0.0;
  58. }
  59. } while (m != l);
  60. }
  61. return 1;
  62. }
  63. void G_tred2(double **a, int n, double d[], double e[])
  64. {
  65. int l, k, j, i;
  66. double scale, hh, h, g, f;
  67. for (i = n - 1; i >= 1; i--) {
  68. l = i - 1;
  69. h = scale = 0.0;
  70. if (l > 0) {
  71. for (k = 0; k <= l; k++)
  72. scale += fabs(a[i][k]);
  73. if (scale == 0.0)
  74. e[i] = a[i][l];
  75. else {
  76. for (k = 0; k <= l; k++) {
  77. a[i][k] /= scale;
  78. h += a[i][k] * a[i][k];
  79. }
  80. f = a[i][l];
  81. g = f > 0 ? -sqrt(h) : sqrt(h);
  82. e[i] = scale * g;
  83. h -= f * g;
  84. a[i][l] = f - g;
  85. f = 0.0;
  86. for (j = 0; j <= l; j++) {
  87. /* Next statement can be omitted if eigenvectors not wanted */
  88. a[j][i] = a[i][j] / h;
  89. g = 0.0;
  90. for (k = 0; k <= j; k++)
  91. g += a[j][k] * a[i][k];
  92. for (k = j + 1; k <= l; k++)
  93. g += a[k][j] * a[i][k];
  94. e[j] = g / h;
  95. f += e[j] * a[i][j];
  96. }
  97. hh = f / (h + h);
  98. for (j = 0; j <= l; j++) {
  99. f = a[i][j];
  100. e[j] = g = e[j] - hh * f;
  101. for (k = 0; k <= j; k++)
  102. a[j][k] -= (f * e[k] + g * a[i][k]);
  103. }
  104. }
  105. }
  106. else
  107. e[i] = a[i][l];
  108. d[i] = h;
  109. }
  110. /* Next statement can be omitted if eigenvectors not wanted */
  111. d[0] = 0.0;
  112. e[0] = 0.0;
  113. /* Contents of this loop can be omitted if eigenvectors not
  114. wanted except for statement d[i]=a[i][i]; */
  115. for (i = 0; i < n; i++) {
  116. l = i - 1;
  117. if (d[i]) {
  118. for (j = 0; j <= l; j++) {
  119. g = 0.0;
  120. for (k = 0; k <= l; k++)
  121. g += a[i][k] * a[k][j];
  122. for (k = 0; k <= l; k++)
  123. a[k][j] -= g * a[k][i];
  124. }
  125. }
  126. d[i] = a[i][i];
  127. a[i][i] = 1.0;
  128. for (j = 0; j <= l; j++)
  129. a[j][i] = a[i][j] = 0.0;
  130. }
  131. }