dune-localfunctions  2.2.0
lfematrix.hh
Go to the documentation of this file.
1 #ifndef DUNE_ALGLIB_MATRIX_HH
2 #define DUNE_ALGLIB_MATRIX_HH
3 
4 #include <cassert>
5 #include <vector>
6 
8 // #include <dune/localfunctions/utility/vector.hh>
9 
10 #if HAVE_ALGLIB
11 #include <alglib/amp.h>
12 #include <alglib/matinv.h>
13 #warning ALGLIB support is deprecated and will be dropped after DUNE 2.2 (cf. FS#931)
14 #endif
15 
16 namespace Dune
17 {
18 
19  template< class F, bool aligned = false >
20  class LFEMatrix;
21 
22 
23  template< class F, bool aligned >
24  class LFEMatrix
25  {
27  // typedef LFEVector< F > Row;
28  typedef std::vector< F > Row;
29  typedef std::vector<Row> RealMatrix;
30 
31  public:
32  typedef F Field;
33 
34  operator const RealMatrix & () const
35  {
36  return matrix_;
37  }
38 
39  operator RealMatrix & ()
40  {
41  return matrix_;
42  }
43 
44  template <class Vector>
45  void row( const unsigned int row, Vector &vec ) const
46  {
47  assert(row<rows());
48  for (int i=0;i<cols();++i)
49  field_cast(matrix_[row][i], vec[i]);
50  }
51 
52  const Field &operator() ( const unsigned int row, const unsigned int col ) const
53  {
54  assert(row<rows());
55  assert(col<cols());
56  return matrix_[ row ][ col ];
57  }
58 
59  Field &operator() ( const unsigned int row, const unsigned int col )
60  {
61  assert(row<rows());
62  assert(col<cols());
63  return matrix_[ row ][ col ];
64  }
65 
66  unsigned int rows () const
67  {
68  return rows_;
69  }
70 
71  unsigned int cols () const
72  {
73  return cols_;
74  }
75 
76  const Field *rowPtr ( const unsigned int row ) const
77  {
78  assert(row<rows());
79  return &(matrix_[row][0]);
80  }
81 
82  Field *rowPtr ( const unsigned int row )
83  {
84  assert(row<rows());
85  return &(matrix_[row][0]);
86  }
87 
88  void resize ( const unsigned int rows, const unsigned int cols )
89  {
90  matrix_.resize(rows);
91  for (unsigned int i=0;i<rows;++i)
92  matrix_[i].resize(cols);
93  rows_ = rows;
94  cols_ = cols;
95  }
96 
97  bool invert ()
98  {
99  assert( rows() == cols() );
100  std::vector<unsigned int> p(rows());
101  for (unsigned int j=0;j<rows();++j)
102  p[j] = j;
103  for (unsigned int j=0;j<rows();++j)
104  {
105  // pivot search
106  unsigned int r = j;
107  Field max = std::abs( (*this)(j,j) );
108  for (unsigned int i=j+1;i<rows();++i)
109  {
110  if ( std::abs( (*this)(i,j) ) > max )
111  {
112  max = std::abs( (*this)(i,j) );
113  r = i;
114  }
115  }
116  if (max == Zero<Field>())
117  return false;
118  // row swap
119  if (r > j)
120  {
121  for (unsigned int k=0;k<cols();++k)
122  std::swap( (*this)(j,k), (*this)(r,k) );
123  std::swap( p[j], p[r] );
124  }
125  // transformation
126  Field hr = Unity<Field>()/(*this)(j,j);
127  for (unsigned int i=0;i<rows();++i)
128  (*this)(i,j) *= hr;
129  (*this)(j,j) = hr;
130  for (unsigned int k=0;k<cols();++k)
131  {
132  if (k==j) continue;
133  for (unsigned int i=0;i<rows();++i)
134  {
135  if (i==j) continue;
136  (*this)(i,k) -= (*this)(i,j)*(*this)(j,k);
137  }
138  (*this)(j,k) *= -hr;
139  }
140  }
141  // column exchange
142  Row hv(rows());
143  for (unsigned int i=0;i<rows();++i)
144  {
145  for (unsigned int k=0;k<rows();++k)
146  hv[ p[k] ] = (*this)(i,k);
147  for (unsigned int k=0;k<rows();++k)
148  (*this)(i,k) = hv[k];
149  }
150  return true;
151  }
152 
153  private:
154  RealMatrix matrix_;
155  unsigned int cols_,rows_;
156  };
157 
158 #if HAVE_ALGLIB
159  template< unsigned int precision, bool aligned >
160  class LFEMatrix< amp::ampf< precision >, aligned >
161  {
162  public:
163  typedef amp::ampf< precision > Field;
164  private:
165  typedef LFEMatrix< amp::ampf< precision >, aligned > This;
166  typedef ap::template_2d_array< Field, aligned > RealMatrix;
167 
168  public:
169  operator const RealMatrix & () const
170  {
171  return matrix_;
172  }
173 
174  operator RealMatrix & ()
175  {
176  return matrix_;
177  }
178 
179  template <class Vector>
180  void row( const unsigned int row, Vector &vec ) const
181  {
182  assert(row<rows());
183  for (unsigned int i=0;i<cols();++i)
184  field_cast(matrix_(row,i), vec[i]);
185  }
186 
187  const Field &operator() ( const unsigned int row, const unsigned int col ) const
188  {
189  assert(row<rows());
190  assert(col<cols());
191  return matrix_( row, col );
192  }
193 
194  Field &operator() ( const unsigned int row, const unsigned int col )
195  {
196  assert(row<rows());
197  assert(col<cols());
198  return matrix_( row, col );
199  }
200 
201  unsigned int rows () const
202  {
203  return matrix_.gethighbound( 1 )+1;
204  }
205 
206  unsigned int cols () const
207  {
208  return matrix_.gethighbound( 2 )+1;
209  }
210 
211  const Field *rowPtr ( const unsigned int row ) const
212  {
213  assert(row<rows());
214  const int lastCol = matrix_.gethighbound( 2 );
215  ap::const_raw_vector< Field > rowVector = matrix_.getrow( row, 0, lastCol );
216  assert( (rowVector.GetStep() == 1) && (rowVector.GetLength() == lastCol+1) );
217  return rowVector.GetData();
218  }
219 
220  Field *rowPtr ( const unsigned int row )
221  {
222  assert(row<rows());
223  const int lastCol = matrix_.gethighbound( 2 );
224  ap::raw_vector< Field > rowVector = matrix_.getrow( row, 0, lastCol );
225  assert( (rowVector.GetStep() == 1) && (rowVector.GetLength() == lastCol+1) );
226  return rowVector.GetData();
227  }
228 
229  void resize ( const unsigned int rows, const unsigned int cols )
230  {
231  matrix_.setbounds( 0, rows-1, 0, cols-1 );
232  }
233 
234  bool invert ()
235  {
236  assert( rows() == cols() );
237  int info;
238  matinv::matinvreport< precision > report;
239  matinv::rmatrixinverse< precision >( matrix_, rows(), info, report );
240  return (info >= 0);
241  }
242 
243  private:
244  RealMatrix matrix_;
245  };
246 #endif
247 
248  template< class Field, bool aligned >
249  inline std::ostream &operator<<(std::ostream &out, const LFEMatrix<Field,aligned> &mat)
250  {
251  for (unsigned int r=0;r<mat.rows();++r)
252  {
253  out << field_cast<double>(mat(r,0));
254  for (unsigned int c=1;c<mat.cols();++c)
255  {
256  out << " , " << field_cast<double>(mat(r,c));
257  }
258  out << std::endl;
259  }
260  return out;
261  }
262 }
263 
264 #endif // #ifndef DUNE_ALGLIB_MATRIX_HH