realroot_doc 0.1.1
/Users/mourrain/Devel/mmx/realroot/include/realroot/linear_gramschmidt.hpp
Go to the documentation of this file.
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 //