You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

jacobi.cc 2.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #include "ABACUS.h"
  2. using namespace std;
  3. using namespace ABACUS;
  4. namespace {
  5. inline void rot (SQMat<DP>& a, const DP s, const DP tau, const int i, const int j,
  6. const int k, const int l)
  7. {
  8. DP g, h;
  9. g = a[i][j];
  10. h = a[k][l];
  11. a[i][j] = g - s * (h + g * tau);
  12. a[k][l] = h + s * (g - h * tau);
  13. }
  14. }
  15. void ABACUS::jacobi (SQMat<DP>& a, Vect_DP& d, SQMat<DP>& v, int& nrot)
  16. {
  17. int i, j, ip, iq;
  18. DP tresh, theta, tau, t, sm, s, h, g, c;
  19. int n = a.size(); //
  20. Vect_DP b(n), z(n);
  21. for (ip = 0; ip < n; ++ip) { // initialize to identity
  22. for (iq = 0; iq < n; ++iq) v[ip][iq] = 0.0;
  23. v[ip][ip] = 1.0;
  24. }
  25. for (ip = 0; ip < n; ++ip) {
  26. b[ip] = d[ip] = a[ip][ip];
  27. z[ip] = 0.0;
  28. }
  29. nrot = 0;
  30. for (i = 1; i <= 50; i++) {
  31. cout << "Sweep number " << i << " under way..." << endl;
  32. sm = 0.0;
  33. for (ip = 0; ip < n-1; ip++) { // sum off-diagonal elements
  34. for (iq = ip + 1; iq < n; iq++)
  35. sm += fabs(a[ip][iq]);
  36. }
  37. if (sm == 0.0) return;
  38. if (i < 4) tresh = 0.2 * sm/(n*n);
  39. else tresh = 0.0;
  40. for (ip = 0; ip < n-1; ip++) {
  41. for (iq = ip + 1; iq < n; iq++) {
  42. g = 100.0 * fabs(a[ip][iq]);
  43. if ((i > 4) && (fabs(d[ip]) + g) == fabs(d[ip]) && (fabs(d[iq]) + g) == fabs(d[iq]))
  44. a[ip][iq] = 0.0;
  45. else if (fabs(a[ip][iq]) > tresh) {
  46. h = d[iq] - d[ip];
  47. if (( fabs(h) + g) == fabs(h))
  48. t = (a[ip][iq])/h;
  49. else {
  50. theta = 0.5*h/(a[ip][iq]);
  51. t = 1.0/(fabs(theta) + sqrt(1.0 + theta*theta));
  52. if (theta < 0.0) t = -t;
  53. }
  54. c = 1.0/sqrt(1.0 + t*t);
  55. s = t*c;
  56. tau = s/(1.0 + c);
  57. h = t*a[ip][iq];
  58. z[ip] -= h;
  59. z[iq] += h;
  60. d[ip] -= h;
  61. d[iq] += h;
  62. a[ip][iq] = 0.0;
  63. for (j = 0; j < ip; j++) rot(a, s, tau, j, ip, j, iq);
  64. for (j = ip+1; j < iq; j++) rot(a, s, tau, ip, j, j, iq);
  65. for (j = iq+1; j < n; j++) rot(a, s, tau, ip, j, iq, j);
  66. for (j = 0; j < n; j++) rot(v, s, tau, j, ip, j, iq);
  67. ++nrot;
  68. }
  69. }
  70. }
  71. for (ip = 0; ip < n; ip++) {
  72. b[ip] += z[ip];
  73. d[ip] = b[ip];
  74. z[ip] = 0.0;
  75. }
  76. }
  77. cout << "Too many iterations in routine jacobi." << endl;
  78. }