qrbdu1.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /* qrbdu1.c CCMATH mathematics library source code.
  2. *
  3. * Copyright (C) 2000 Daniel A. Atkinson All rights reserved.
  4. * This code may be redistributed under the terms of the GNU library
  5. * public license (LGPL). ( See the lgpl.license file for details.)
  6. * ------------------------------------------------------------------------
  7. */
  8. #include "ccmath.h"
  9. int qrbdu1(double *dm, double *em, double *um, int mm, double *vm, int m)
  10. {
  11. int i, j, k, n, jj, nm;
  12. double u, x, y, a, b, c, s, t, w, *p, *q;
  13. for (j = 1, t = fabs(dm[0]); j < m; ++j)
  14. if ((s = fabs(dm[j]) + fabs(em[j - 1])) > t)
  15. t = s;
  16. t *= 1.e-15;
  17. n = 100 * m;
  18. nm = m;
  19. for (j = 0; m > 1 && j < n; ++j) {
  20. for (k = m - 1; k > 0; --k) {
  21. if (fabs(em[k - 1]) < t)
  22. break;
  23. if (fabs(dm[k - 1]) < t) {
  24. for (i = k, s = 1., c = 0.; i < m; ++i) {
  25. a = s * em[i - 1];
  26. b = dm[i];
  27. em[i - 1] *= c;
  28. dm[i] = u = sqrt(a * a + b * b);
  29. s = -a / u;
  30. c = b / u;
  31. for (jj = 0, p = um + k - 1; jj < mm; ++jj, p += nm) {
  32. q = p + i - k + 1;
  33. w = c * *p + s * *q;
  34. *q = c * *q - s * *p;
  35. *p = w;
  36. }
  37. }
  38. break;
  39. }
  40. }
  41. y = dm[k];
  42. x = dm[m - 1];
  43. u = em[m - 2];
  44. a = (y + x) * (y - x) - u * u;
  45. s = y * em[k];
  46. b = s + s;
  47. u = sqrt(a * a + b * b);
  48. if (u > 0.) {
  49. c = sqrt((u + a) / (u + u));
  50. if (c != 0.)
  51. s /= (c * u);
  52. else
  53. s = 1.;
  54. for (i = k; i < m - 1; ++i) {
  55. b = em[i];
  56. if (i > k) {
  57. a = s * em[i];
  58. b *= c;
  59. em[i - 1] = u = sqrt(x * x + a * a);
  60. c = x / u;
  61. s = a / u;
  62. }
  63. a = c * y + s * b;
  64. b = c * b - s * y;
  65. for (jj = 0, p = vm + i; jj < nm; ++jj, p += nm) {
  66. w = c * *p + s * *(p + 1);
  67. *(p + 1) = c * *(p + 1) - s * *p;
  68. *p = w;
  69. }
  70. s *= dm[i + 1];
  71. dm[i] = u = sqrt(a * a + s * s);
  72. y = c * dm[i + 1];
  73. c = a / u;
  74. s /= u;
  75. x = c * b + s * y;
  76. y = c * y - s * b;
  77. for (jj = 0, p = um + i; jj < mm; ++jj, p += nm) {
  78. w = c * *p + s * *(p + 1);
  79. *(p + 1) = c * *(p + 1) - s * *p;
  80. *p = w;
  81. }
  82. }
  83. }
  84. em[m - 2] = x;
  85. dm[m - 1] = y;
  86. if (fabs(x) < t)
  87. --m;
  88. if (m == k + 1)
  89. --m;
  90. }
  91. return j;
  92. }