00001
00002
00003
00004
00005
00006 #ifndef realroot_SOLVE_SBDSLV_LINEAR_GRAMSCHMIDT_HPP
00007 #define realroot_SOLVE_SBDSLV_LINEAR_GRAMSCHMIDT_HPP
00008
00009 #include <assert.h>
00010
00011 namespace mmx {
00012
00013 namespace linear
00014 {
00015
00016 template<typename real_t>
00017 bool gramschmidt( real_t * M, unsigned m, unsigned n )
00018 {
00019 unsigned i,j,k;
00020 assert(m<=n);
00021 for ( i = 0; i < m; i ++ )
00022 {
00023 real_t s = 0.0;
00024 for ( k = 0; k < n; k ++ )
00025 s += M[i*n+k]*M[i*n+k];
00026 if ( s < numerics::epsilon<real_t>::result ) return false;
00027 for ( j = i+1; j < m; j ++ )
00028 {
00029 real_t d = 0.0;
00030 for ( k = 0; k < n; k ++ )
00031 d += M[i*n+k]*M[j*n+k];
00032 d /= s;
00033 for ( k = 0; k < n; k ++ )
00034 M[j*n+k] -= d*M[i*n+k];
00035 };
00036 };
00037 return true;
00038 };
00039
00040
00041
00042
00043
00044 template<typename real_t>
00045 void library( real_t * M, unsigned n, real_t * v )
00046 {
00047 int goods[n];
00048 int c = 0;
00049 int i,j,k,p;
00050 real_t sc[ n ];
00051
00052 c = 0;
00053 for ( i = 0; i < n; i ++ )
00054 {
00055 real_t s = 0.0;
00056 for ( k = 0; k < n; s += M[i*n+k]*M[i*n+k], k ++ ) ;
00057 if ( s < numerics::epsilon<real_t>::result ) continue;
00058 goods[c++] = i;
00059 for ( j = i+1; j < n; j ++ )
00060 {
00061 real_t d = 0.0;
00062 for ( k = 0; k < n; k ++ )
00063 d += M[i*n+k]*M[j*n+k];
00064 d /= s;
00065 for ( k = 0; k < n; k ++ )
00066 M[j*n+k] -= d*M[i*n+k];
00067 };
00068 sc[i] = s;
00069 };
00070 if ( c == n ) return;
00071 k = 0;
00072 while( k < c && goods[k] == k ) k ++;
00073 while ( k < c )
00074 {
00075 std::copy( M + goods[k]*n, M + (goods[k]+1)*n,
00076 M + k );
00077 sc[k] = sc[goods[k]];
00078 k++;
00079 };
00080
00081
00082
00083
00084
00085
00086
00087
00088 for ( i = c; i < n; i ++ )
00089 for ( k = 0; k < n; k ++ )
00090 M[i*n+k] = ((real_t)rand())/((real_t)RAND_MAX);
00091
00092
00093 for ( i = c; i < n; i ++ )
00094 {
00095 for ( p = i-1; p >= 0; p-- )
00096 {
00097
00098 real_t d = 0.0;
00099 for ( k = 0; k < n; k ++ )
00100 d += M[p*n+k]*M[i*n+k];
00101 d /= sc[p];
00102 for ( k = 0; k < n; k ++ )
00103 {
00104
00105 M[i*n+k] -= d*M[p*n+k];
00106
00107 };
00108 };
00109 real_t s = 0.0;
00110 for ( k = 0; k < n; k ++ )
00111 s += M[i*n+k]*M[i*n+k];
00112 sc[i] = s;
00113 };
00114 };
00115
00116
00117 };
00118
00119 }
00120
00121 #endif //