GRASS Programmer's Manual  6.5.svn(2012)-r51648
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
qrbdv.c
Go to the documentation of this file.
00001 /*  qrbdv.c    CCMATH mathematics library source code.
00002  *
00003  *  Copyright (C)  2000   Daniel A. Atkinson    All rights reserved.
00004  *  This code may be redistributed under the terms of the GNU library
00005  *  public license (LGPL). ( See the lgpl.license file for details.)
00006  * ------------------------------------------------------------------------
00007  */
00008 #include "ccmath.h"
00009 int qrbdv(double *dm, double *em, double *um, int mm, double *vm, int m)
00010 {
00011     int i, j, k, n, jj, nm;
00012 
00013     double u, x, y, a, b, c, s, t, w, *p, *q;
00014 
00015     for (j = 1, t = fabs(dm[0]); j < m; ++j)
00016         if ((s = fabs(dm[j]) + fabs(em[j - 1])) > t)
00017             t = s;
00018     t *= 1.e-15;
00019     n = 100 * m;
00020     nm = m;
00021     for (j = 0; m > 1 && j < n; ++j) {
00022         for (k = m - 1; k > 0; --k) {
00023             if (fabs(em[k - 1]) < t)
00024                 break;
00025             if (fabs(dm[k - 1]) < t) {
00026                 for (i = k, s = 1., c = 0.; i < m; ++i) {
00027                     a = s * em[i - 1];
00028                     b = dm[i];
00029                     em[i - 1] *= c;
00030                     dm[i] = u = sqrt(a * a + b * b);
00031                     s = -a / u;
00032                     c = b / u;
00033                     for (jj = 0, p = um + k - 1; jj < mm; ++jj, p += mm) {
00034                         q = p + i - k + 1;
00035                         w = c * *p + s * *q;
00036                         *q = c * *q - s * *p;
00037                         *p = w;
00038                     }
00039                 }
00040                 break;
00041             }
00042         }
00043         y = dm[k];
00044         x = dm[m - 1];
00045         u = em[m - 2];
00046         a = (y + x) * (y - x) - u * u;
00047         s = y * em[k];
00048         b = s + s;
00049         u = sqrt(a * a + b * b);
00050         if (u != 0.) {
00051             c = sqrt((u + a) / (u + u));
00052             if (c != 0.)
00053                 s /= (c * u);
00054             else
00055                 s = 1.;
00056             for (i = k; i < m - 1; ++i) {
00057                 b = em[i];
00058                 if (i > k) {
00059                     a = s * em[i];
00060                     b *= c;
00061                     em[i - 1] = u = sqrt(x * x + a * a);
00062                     c = x / u;
00063                     s = a / u;
00064                 }
00065                 a = c * y + s * b;
00066                 b = c * b - s * y;
00067                 for (jj = 0, p = vm + i; jj < nm; ++jj, p += nm) {
00068                     w = c * *p + s * *(p + 1);
00069                     *(p + 1) = c * *(p + 1) - s * *p;
00070                     *p = w;
00071                 }
00072                 s *= dm[i + 1];
00073                 dm[i] = u = sqrt(a * a + s * s);
00074                 y = c * dm[i + 1];
00075                 c = a / u;
00076                 s /= u;
00077                 x = c * b + s * y;
00078                 y = c * y - s * b;
00079                 for (jj = 0, p = um + i; jj < mm; ++jj, p += mm) {
00080                     w = c * *p + s * *(p + 1);
00081                     *(p + 1) = c * *(p + 1) - s * *p;
00082                     *p = w;
00083                 }
00084             }
00085         }
00086         em[m - 2] = x;
00087         dm[m - 1] = y;
00088         if (fabs(x) < t)
00089             --m;
00090         if (m == k + 1)
00091             --m;
00092     }
00093     return j;
00094 }