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