dune-localfunctions  2.3beta2
lfematrix.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_LOCALFUNCTIONS_UTILITY_LFEMATRIX_HH
4 #define DUNE_LOCALFUNCTIONS_UTILITY_LFEMATRIX_HH
5 
6 #include <cassert>
7 #include <vector>
8 
9 #include "field.hh"
10 
11 namespace Dune
12 {
13 
14  template< class F, bool aligned = false >
15  class LFEMatrix;
16 
17  template< class F, bool aligned >
18  class LFEMatrix
19  {
21  typedef std::vector< F > Row;
22  typedef std::vector<Row> RealMatrix;
23 
24  public:
25  typedef F Field;
26 
27  operator const RealMatrix & () const
28  {
29  return matrix_;
30  }
31 
32  operator RealMatrix & ()
33  {
34  return matrix_;
35  }
36 
37  template <class Vector>
38  void row( const unsigned int row, Vector &vec ) const
39  {
40  assert(row<rows());
41  for (int i=0; i<cols(); ++i)
42  field_cast(matrix_[row][i], vec[i]);
43  }
44 
45  const Field &operator() ( const unsigned int row, const unsigned int col ) const
46  {
47  assert(row<rows());
48  assert(col<cols());
49  return matrix_[ row ][ col ];
50  }
51 
52  Field &operator() ( const unsigned int row, const unsigned int col )
53  {
54  assert(row<rows());
55  assert(col<cols());
56  return matrix_[ row ][ col ];
57  }
58 
59  unsigned int rows () const
60  {
61  return rows_;
62  }
63 
64  unsigned int cols () const
65  {
66  return cols_;
67  }
68 
69  const Field *rowPtr ( const unsigned int row ) const
70  {
71  assert(row<rows());
72  return &(matrix_[row][0]);
73  }
74 
75  Field *rowPtr ( const unsigned int row )
76  {
77  assert(row<rows());
78  return &(matrix_[row][0]);
79  }
80 
81  void resize ( const unsigned int rows, const unsigned int cols )
82  {
83  matrix_.resize(rows);
84  for (unsigned int i=0; i<rows; ++i)
85  matrix_[i].resize(cols);
86  rows_ = rows;
87  cols_ = cols;
88  }
89 
90  bool invert ()
91  {
92  assert( rows() == cols() );
93  std::vector<unsigned int> p(rows());
94  for (unsigned int j=0; j<rows(); ++j)
95  p[j] = j;
96  for (unsigned int j=0; j<rows(); ++j)
97  {
98  // pivot search
99  unsigned int r = j;
100  Field max = std::abs( (*this)(j,j) );
101  for (unsigned int i=j+1; i<rows(); ++i)
102  {
103  if ( std::abs( (*this)(i,j) ) > max )
104  {
105  max = std::abs( (*this)(i,j) );
106  r = i;
107  }
108  }
109  if (max == Zero<Field>())
110  return false;
111  // row swap
112  if (r > j)
113  {
114  for (unsigned int k=0; k<cols(); ++k)
115  std::swap( (*this)(j,k), (*this)(r,k) );
116  std::swap( p[j], p[r] );
117  }
118  // transformation
119  Field hr = Unity<Field>()/(*this)(j,j);
120  for (unsigned int i=0; i<rows(); ++i)
121  (*this)(i,j) *= hr;
122  (*this)(j,j) = hr;
123  for (unsigned int k=0; k<cols(); ++k)
124  {
125  if (k==j) continue;
126  for (unsigned int i=0; i<rows(); ++i)
127  {
128  if (i==j) continue;
129  (*this)(i,k) -= (*this)(i,j)*(*this)(j,k);
130  }
131  (*this)(j,k) *= -hr;
132  }
133  }
134  // column exchange
135  Row hv(rows());
136  for (unsigned int i=0; i<rows(); ++i)
137  {
138  for (unsigned int k=0; k<rows(); ++k)
139  hv[ p[k] ] = (*this)(i,k);
140  for (unsigned int k=0; k<rows(); ++k)
141  (*this)(i,k) = hv[k];
142  }
143  return true;
144  }
145 
146  private:
147  RealMatrix matrix_;
148  unsigned int cols_,rows_;
149  };
150 
151  template< class Field, bool aligned >
152  inline std::ostream &operator<<(std::ostream &out, const LFEMatrix<Field,aligned> &mat)
153  {
154  for (unsigned int r=0; r<mat.rows(); ++r)
155  {
156  out << field_cast<double>(mat(r,0));
157  for (unsigned int c=1; c<mat.cols(); ++c)
158  {
159  out << " , " << field_cast<double>(mat(r,c));
160  }
161  out << std::endl;
162  }
163  return out;
164  }
165 }
166 
167 #endif // #ifndef DUNE_LOCALFUNCTIONS_UTILITY_LFEMATRIX_HH