GRASS Programmer's Manual  6.5.svn(2012)-r51648
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
qrbdi.c
Go to the documentation of this file.
00001 /*  qrbdi.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 qrbdi(double *dm, double *em, int m)
00010 {
00011     int i, j, k, n;
00012 
00013     double u, x, y, a, b, c, s, t;
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     for (j = 0; m > 1 && j < n; ++j) {
00021         for (k = m - 1; k > 0; --k) {
00022             if (fabs(em[k - 1]) < t)
00023                 break;
00024             if (fabs(dm[k - 1]) < t) {
00025                 for (i = k, s = 1., c = 0.; i < m; ++i) {
00026                     a = s * em[i - 1];
00027                     b = dm[i];
00028                     em[i - 1] *= c;
00029                     dm[i] = u = sqrt(a * a + b * b);
00030                     s = -a / u;
00031                     c = b / u;
00032                 }
00033                 break;
00034             }
00035         }
00036         y = dm[k];
00037         x = dm[m - 1];
00038         u = em[m - 2];
00039         a = (y + x) * (y - x) - u * u;
00040         s = y * em[k];
00041         b = s + s;
00042         u = sqrt(a * a + b * b);
00043         if (u > 0.) {
00044             c = sqrt((u + a) / (u + u));
00045             if (c != 0.)
00046                 s /= (c * u);
00047             else
00048                 s = 1.;
00049             for (i = k; i < m - 1; ++i) {
00050                 b = em[i];
00051                 if (i > k) {
00052                     a = s * em[i];
00053                     b *= c;
00054                     em[i - 1] = u = sqrt(x * x + a * a);
00055                     c = x / u;
00056                     s = a / u;
00057                 }
00058                 a = c * y + s * b;
00059                 b = c * b - s * y;
00060                 s *= dm[i + 1];
00061                 dm[i] = u = sqrt(a * a + s * s);
00062                 y = c * dm[i + 1];
00063                 c = a / u;
00064                 s /= u;
00065                 x = c * b + s * y;
00066                 y = c * y - s * b;
00067             }
00068         }
00069         em[m - 2] = x;
00070         dm[m - 1] = y;
00071         if (fabs(x) < t)
00072             --m;
00073         if (m == k + 1)
00074             --m;
00075     }
00076     return j;
00077 }