eigen_tools.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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(
  6. double d[],double e[],
  7. int n,
  8. double **z)
  9. {
  10. int m,l,iter,i,k;
  11. double s,r,p,g,f,dd,c,b;
  12. for (i=1;i<n;i++) e[i-1]=e[i];
  13. e[n-1]=0.0;
  14. for (l=0;l<n;l++) {
  15. iter=0;
  16. do {
  17. for (m=l;m<n-1;m++) {
  18. dd=fabs(d[m])+fabs(d[m+1]);
  19. if (fabs(e[m])+dd == dd) break;
  20. }
  21. if (m != l) {
  22. if (iter++ == MAX_ITERS) 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. } else {
  37. s=f/g;
  38. r=sqrt((s*s)+1.0);
  39. e[i+1]=g*r;
  40. s *= (c=1.0/r);
  41. }
  42. g=d[i+1]-p;
  43. r=(d[i]-g)*s+2.0*c*b;
  44. p=s*r;
  45. d[i+1]=g+p;
  46. g=c*r-b;
  47. /* Next loop can be omitted if eigenvectors not wanted */
  48. for (k=0;k<n;k++) {
  49. f=z[k][i+1];
  50. z[k][i+1]=s*z[k][i]+c*f;
  51. z[k][i]=c*z[k][i]-s*f;
  52. }
  53. }
  54. d[l]=d[l]-p;
  55. e[l]=g;
  56. e[m]=0.0;
  57. }
  58. } while (m != l);
  59. }
  60. return 1;
  61. }
  62. void
  63. 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. } else
  106. e[i]=a[i][l];
  107. d[i]=h;
  108. }
  109. /* Next statement can be omitted if eigenvectors not wanted */
  110. d[0]=0.0;
  111. e[0]=0.0;
  112. /* Contents of this loop can be omitted if eigenvectors not
  113. wanted except for statement d[i]=a[i][i]; */
  114. for (i=0;i<n;i++) {
  115. l=i-1;
  116. if (d[i]) {
  117. for (j=0;j<=l;j++) {
  118. g=0.0;
  119. for (k=0;k<=l;k++)
  120. g += a[i][k]*a[k][j];
  121. for (k=0;k<=l;k++)
  122. a[k][j] -= g*a[k][i];
  123. }
  124. }
  125. d[i]=a[i][i];
  126. a[i][i]=1.0;
  127. for (j=0;j<=l;j++) a[j][i]=a[i][j]=0.0;
  128. }
  129. }