realroot_doc 0.1.1
|
00001 /******************************************************************** 00002 * This file is part of the source code of the realroot library. 00003 * Author(s): J.P. Pavone, GALAAD, INRIA 00004 * $Id: gramschmidt.hpp,v 1.1 2005/07/11 10:03:55 jppavone Exp $ 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 /* on suppose que M admet un noyau de dimension 1 00041 * ( et puis c tout !) 00042 */ 00043 00044 template<typename real_t> 00045 void library( real_t * M, unsigned n, real_t * v ) 00046 { 00047 00048 int m = n; 00049 int goods[n]; 00050 int c = 0; 00051 int i,j,k,p; 00052 int already =0; 00053 real_t sc[ n ]; 00054 00055 c = 0; 00056 for ( i = 0; i < n; i ++ ) 00057 { 00058 real_t s = 0.0; 00059 for ( k = 0; k < n; s += M[i*n+k]*M[i*n+k], k ++ ) ; 00060 if ( s < numerics::epsilon<real_t>::result ) continue; 00061 goods[c++] = i; 00062 for ( j = i+1; j < n; j ++ ) 00063 { 00064 real_t d = 0.0; 00065 for ( k = 0; k < n; k ++ ) 00066 d += M[i*n+k]*M[j*n+k]; 00067 d /= s; 00068 for ( k = 0; k < n; k ++ ) 00069 M[j*n+k] -= d*M[i*n+k]; 00070 }; 00071 sc[i] = s; 00072 }; 00073 if ( c == n ) return; 00074 k = 0; 00075 while( k < c && goods[k] == k ) k ++; 00076 while ( k < c ) 00077 { 00078 std::copy( M + goods[k]*n, M + (goods[k]+1)*n, 00079 M + k ); 00080 sc[k] = sc[goods[k]]; 00081 k++; 00082 }; 00083 // vctops::print(goods,c); 00084 // std::cout << std::endl; 00085 // vctops::print(M,n); 00086 // std::cout << std::endl; 00087 // vctops::print(M+n,n); 00088 // std::cout << std::endl; 00089 // std::cout << "c = " << c << std::endl; 00090 // std::cout << "n = " << n << std::endl; 00091 for ( i = c; i < n; i ++ ) 00092 for ( k = 0; k < n; k ++ ) 00093 M[i*n+k] = ((real_t)rand())/((real_t)RAND_MAX); 00094 // vctops::print(M+c*n,n); 00095 // std::cout << std::endl; 00096 for ( i = c; i < n; i ++ ) 00097 { 00098 for ( p = i-1; p >= 0; p-- ) 00099 { 00100 // std::cout << sc[p] << std::endl; 00101 real_t d = 0.0; 00102 for ( k = 0; k < n; k ++ ) 00103 d += M[p*n+k]*M[i*n+k]; 00104 d /= sc[p]; 00105 for ( k = 0; k < n; k ++ ) 00106 { 00107 // std::cout << M[i*n+k] << std::endl; 00108 M[i*n+k] -= d*M[p*n+k]; 00109 // std::cout << M[i*n+k] << std::endl; 00110 }; 00111 }; 00112 real_t s = 0.0; 00113 for ( k = 0; k < n; k ++ ) 00114 s += M[i*n+k]*M[i*n+k]; 00115 sc[i] = s; 00116 }; 00117 }; 00118 00119 00120 }; 00121 //-------------------------------------------------------------------- 00122 } //namespace mmx 00123 /********************************************************************/ 00124 #endif //