|
GRASS Programmer's Manual
6.5.svn(2012)-r51648
|
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 }