lfematrix.hh

Go to the documentation of this file.
00001 #ifndef DUNE_ALGLIB_MATRIX_HH
00002 #define DUNE_ALGLIB_MATRIX_HH
00003 
00004 #include <cassert>
00005 #include <vector>
00006 
00007 #include <dune/localfunctions/utility/field.hh>
00008 // #include <dune/localfunctions/utility/vector.hh>
00009 
00010 #if HAVE_ALGLIB
00011 #include <alglib/amp.h>
00012 #include <alglib/inv.h>
00013 #endif
00014 
00015 namespace Dune
00016 {
00017 
00018   template< class F, bool aligned = false >
00019   class LFEMatrix;
00020 
00021 
00022   template< class F, bool aligned >
00023   class LFEMatrix
00024   {
00025     typedef LFEMatrix< F, aligned > This;
00026     // typedef LFEVector< F > Row;
00027     typedef std::vector< F > Row;
00028     typedef std::vector<Row> RealMatrix;
00029 
00030   public:
00031     typedef F Field;
00032 
00033     operator const RealMatrix & () const
00034     {
00035       return matrix_;
00036     }
00037 
00038     operator RealMatrix & ()
00039     {
00040       return matrix_;
00041     }
00042 
00043     template <class Vector>
00044     void row( const unsigned int row, Vector &vec ) const
00045     {
00046       assert(row<rows());
00047       for (int i=0;i<cols();++i)
00048         field_cast(matrix_[row][i], vec[i]);
00049     }
00050 
00051     const Field &operator() ( const unsigned int row, const unsigned int col ) const
00052     {
00053       assert(row<rows());
00054       assert(col<cols());
00055       return matrix_[ row ][ col ];
00056     }
00057 
00058     Field &operator() ( const unsigned int row, const unsigned int col )
00059     {
00060       assert(row<rows());
00061       assert(col<cols());
00062       return matrix_[ row ][ col ];
00063     }
00064 
00065     unsigned int rows () const
00066     {
00067       return rows_;
00068     }
00069 
00070     unsigned int cols () const
00071     {
00072       return cols_;
00073     }
00074 
00075     const Field *rowPtr ( const unsigned int row ) const
00076     {
00077       assert(row<rows());
00078       return &(matrix_[row][0]);
00079     }
00080 
00081     Field *rowPtr ( const unsigned int row )
00082     {
00083       assert(row<rows());
00084       return &(matrix_[row][0]);
00085     }
00086 
00087     void resize ( const unsigned int rows, const unsigned int cols )
00088     {
00089       matrix_.resize(rows);
00090       for (unsigned int i=0;i<rows;++i)
00091         matrix_[i].resize(cols);
00092       rows_ = rows;
00093       cols_ = cols;
00094     }
00095 
00096     bool invert ()
00097     {
00098       assert( rows() == cols() );
00099       std::vector<unsigned int> p(rows());
00100       for (unsigned int j=0;j<rows();++j)
00101         p[j] = j;
00102       for (unsigned int j=0;j<rows();++j)
00103       {
00104         // pivot search
00105         unsigned int r = j;
00106         Field max = std::abs( (*this)(j,j) ); 
00107         for (unsigned int i=j+1;i<rows();++i)
00108         {
00109           if ( std::abs( (*this)(i,j) ) > max )
00110           {
00111             max = std::abs( (*this)(i,j) ); 
00112             r = i;
00113           }
00114         }
00115         if (max == Zero<Field>())
00116           return false;
00117         // row swap
00118         if (r > j) 
00119         {
00120           for (unsigned int k=0;k<cols();++k)
00121             std::swap( (*this)(j,k), (*this)(r,k) );
00122           std::swap( p[j], p[r] );
00123         }
00124         // transformation
00125         Field hr = Unity<Field>()/(*this)(j,j);
00126         for (unsigned int i=0;i<rows();++i) 
00127           (*this)(i,j) *= hr;
00128         (*this)(j,j) = hr;
00129         for (unsigned int k=0;k<cols();++k) 
00130         {
00131           if (k==j) continue;
00132           for (unsigned int i=0;i<rows();++i)
00133           {
00134             if (i==j) continue;
00135             (*this)(i,k) -= (*this)(i,j)*(*this)(j,k);
00136           }
00137           (*this)(j,k) *= -hr;
00138         }
00139       }
00140       // column exchange
00141       Row hv(rows());
00142       for (unsigned int i=0;i<rows();++i)
00143       {
00144         for (unsigned int k=0;k<rows();++k)
00145           hv[ p[k] ] = (*this)(i,k);
00146         for (unsigned int k=0;k<rows();++k)
00147           (*this)(i,k) = hv[k];
00148       }
00149       return true;
00150     }
00151 
00152   private:
00153     RealMatrix matrix_;
00154     unsigned int cols_,rows_;
00155   };
00156 
00157 #if HAVE_ALGLIB
00158   template< unsigned int precision, bool aligned >
00159   class LFEMatrix< amp::ampf< precision >, aligned >
00160   {
00161   public:
00162     typedef amp::ampf< precision > Field;
00163   private:
00164     typedef LFEMatrix< amp::ampf< precision >, aligned > This;
00165     typedef ap::template_2d_array< Field, aligned > RealMatrix;
00166 
00167   public:
00168     operator const RealMatrix & () const
00169     {
00170       return matrix_;
00171     }
00172 
00173     operator RealMatrix & ()
00174     {
00175       return matrix_;
00176     }
00177 
00178     template <class Vector>
00179     void row( const unsigned int row, Vector &vec ) const
00180     {
00181       assert(row<rows());
00182       for (unsigned int i=0;i<cols();++i)
00183         field_cast(matrix_(row,i), vec[i]);
00184     }
00185 
00186     const Field &operator() ( const unsigned int row, const unsigned int col ) const
00187     {
00188       assert(row<rows());
00189       assert(col<cols());
00190       return matrix_( row, col );
00191     }
00192 
00193     Field &operator() ( const unsigned int row, const unsigned int col )
00194     {
00195       assert(row<rows());
00196       assert(col<cols());
00197       return matrix_( row, col );
00198     }
00199 
00200     unsigned int rows () const
00201     {
00202       return matrix_.gethighbound( 1 )+1;
00203     }
00204 
00205     unsigned int cols () const
00206     {
00207       return matrix_.gethighbound( 2 )+1;
00208     }
00209 
00210     const Field *rowPtr ( const unsigned int row ) const
00211     {
00212       assert(row<rows());
00213       const int lastCol = matrix_.gethighbound( 2 );
00214       ap::const_raw_vector< Field > rowVector = matrix_.getrow( row, 0, lastCol );
00215       assert( (rowVector.GetStep() == 1) && (rowVector.GetLength() == lastCol+1) );
00216       return rowVector.GetData();
00217     }
00218 
00219     Field *rowPtr ( const unsigned int row )
00220     {
00221       assert(row<rows());
00222       const int lastCol = matrix_.gethighbound( 2 );
00223       ap::raw_vector< Field > rowVector = matrix_.getrow( row, 0, lastCol );
00224       assert( (rowVector.GetStep() == 1) && (rowVector.GetLength() == lastCol+1) );
00225       return rowVector.GetData();
00226     }
00227 
00228     void resize ( const unsigned int rows, const unsigned int cols )
00229     {
00230       matrix_.setbounds( 0, rows-1, 0, cols-1 );
00231     }
00232 
00233     bool invert ()
00234     {
00235       assert( rows() == cols() );
00236       return inv::rmatrixinverse< precision >( matrix_, rows() );
00237     }
00238 
00239   private:
00240     RealMatrix matrix_;
00241   };
00242 #endif
00243 
00244   template< class Field, bool aligned >
00245   inline std::ostream &operator<<(std::ostream &out, const LFEMatrix<Field,aligned> &mat) 
00246   {
00247     for (unsigned int r=0;r<mat.rows();++r)
00248     {
00249       out << field_cast<double>(mat(r,0));
00250       for (unsigned int c=1;c<mat.cols();++c) 
00251       {
00252         out << " , " << field_cast<double>(mat(r,c));
00253       }
00254       out << std::endl;
00255     }
00256     return out;
00257   }
00258 }
00259 
00260 #endif // #ifndef DUNE_ALGLIB_MATRIX_HH
Generated on Sat Apr 24 11:15:34 2010 for dune-localfunctions by  doxygen 1.6.3