1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- /* qrbdv.c CCMATH mathematics library source code.
- *
- * Copyright (C) 2000 Daniel A. Atkinson All rights reserved.
- * This code may be redistributed under the terms of the GNU library
- * public license (LGPL). ( See the lgpl.license file for details.)
- * ------------------------------------------------------------------------
- */
- #include "ccmath.h"
- int qrbdv(double *dm, double *em, double *um, int mm, double *vm, int m)
- {
- int i, j, k, n, jj, nm;
- double u, x, y, a, b, c, s, t, w, *p, *q;
- for (j = 1, t = fabs(dm[0]); j < m; ++j)
- if ((s = fabs(dm[j]) + fabs(em[j - 1])) > t)
- t = s;
- t *= 1.e-15;
- n = 100 * m;
- nm = m;
- for (j = 0; m > 1 && j < n; ++j) {
- for (k = m - 1; k > 0; --k) {
- if (fabs(em[k - 1]) < t)
- break;
- if (fabs(dm[k - 1]) < t) {
- for (i = k, s = 1., c = 0.; i < m; ++i) {
- a = s * em[i - 1];
- b = dm[i];
- em[i - 1] *= c;
- dm[i] = u = sqrt(a * a + b * b);
- s = -a / u;
- c = b / u;
- for (jj = 0, p = um + k - 1; jj < mm; ++jj, p += mm) {
- q = p + i - k + 1;
- w = c * *p + s * *q;
- *q = c * *q - s * *p;
- *p = w;
- }
- }
- break;
- }
- }
- y = dm[k];
- x = dm[m - 1];
- u = em[m - 2];
- a = (y + x) * (y - x) - u * u;
- s = y * em[k];
- b = s + s;
- u = sqrt(a * a + b * b);
- if (u != 0.) {
- c = sqrt((u + a) / (u + u));
- if (c != 0.)
- s /= (c * u);
- else
- s = 1.;
- for (i = k; i < m - 1; ++i) {
- b = em[i];
- if (i > k) {
- a = s * em[i];
- b *= c;
- em[i - 1] = u = sqrt(x * x + a * a);
- c = x / u;
- s = a / u;
- }
- a = c * y + s * b;
- b = c * b - s * y;
- for (jj = 0, p = vm + i; jj < nm; ++jj, p += nm) {
- w = c * *p + s * *(p + 1);
- *(p + 1) = c * *(p + 1) - s * *p;
- *p = w;
- }
- s *= dm[i + 1];
- dm[i] = u = sqrt(a * a + s * s);
- y = c * dm[i + 1];
- c = a / u;
- s /= u;
- x = c * b + s * y;
- y = c * y - s * b;
- for (jj = 0, p = um + i; jj < mm; ++jj, p += mm) {
- w = c * *p + s * *(p + 1);
- *(p + 1) = c * *(p + 1) - s * *p;
- *p = w;
- }
- }
- }
- em[m - 2] = x;
- dm[m - 1] = y;
- if (fabs(x) < t)
- --m;
- if (m == k + 1)
- --m;
- }
- return j;
- }
|