Nektar++
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
StandardMatrix.hpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: StandardMatrix.hpp
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description: Interface classes for matrices
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #ifndef NEKTAR_LIB_UTILITIES_LINEAR_ALGEBRA_STANDARD_MATRIX_HPP
36 #define NEKTAR_LIB_UTILITIES_LINEAR_ALGEBRA_STANDARD_MATRIX_HPP
37 
39 
44 
47 
48 namespace Nektar
49 {
50  /// \brief Standard Matrix
51  /// \param DataType The type stored in each element.
52  ///
53  /// Matrices are stored in column major order to make it easier to interoperate with
54  /// Blas and Lapack.
55  template<typename DataType>
56  class NekMatrix<DataType, StandardMatrixTag> : public Matrix<DataType>
57  {
58  public:
61  typedef DataType NumberType;
62  typedef const DataType& ConstGetValueType;
63  typedef DataType GetValueType;
64 
65  public:
66 
67  template<typename T, typename MatrixType>
68  class iterator_impl
69  {
70  public:
71  typedef T value_type;
72 
73  template<typename Z>
74  struct TagType
75  {
76  typedef std::forward_iterator_tag type;
77  };
78 
79  template<typename Z>
80  struct TagType<const Z>
81  {
82  typedef std::input_iterator_tag type;
83  };
84 
86  typedef unsigned int difference_type;
87  typedef typename boost::call_traits<value_type>::reference reference;
88  typedef typename boost::call_traits<value_type>::const_reference const_reference;
89  typedef typename std::remove_reference<value_type>::type* pointer;
90 
91  public:
92  iterator_impl(pointer d, pointer e, bool isEnd = false) :
93  m_data(d),
94  m_end(e),
95  m_curRow(std::numeric_limits<unsigned int>::max()),
96  m_curColumn(std::numeric_limits<unsigned int>::max()),
97  m_matrix(NULL),
98  m_curIndex(std::numeric_limits<unsigned int>::max()),
99  m_transpose('N')
100  {
101  if( isEnd )
102  {
103  m_data = m_end;
104  }
105  }
106 
107  iterator_impl(MatrixType* m, char transpose, bool isEnd = false) :
108  m_data(NULL),
109  m_end(NULL),
110  m_curRow(0),
111  m_curColumn(0),
112  m_matrix(m),
113  m_curIndex(0),
114  m_transpose(transpose)
115  {
116  if( isEnd )
117  {
118  m_curRow = std::numeric_limits<unsigned int>::max();
119  m_curColumn = std::numeric_limits<unsigned int>::max();
120  m_curIndex = std::numeric_limits<unsigned int>::max();
121  }
122  }
123 
124  iterator_impl(const iterator_impl<T, MatrixType>& rhs) :
125  m_data(rhs.m_data),
126  m_end(rhs.m_end),
127  m_curRow(rhs.m_curRow),
128  m_curColumn(rhs.m_curColumn),
129  m_matrix(rhs.m_matrix),
130  m_curIndex(rhs.m_curIndex),
131  m_transpose(rhs.m_transpose)
132  {
133  }
134 
135  iterator_impl<T, MatrixType>& operator=(const iterator_impl<T, MatrixType>& rhs)
136  {
137  m_data = rhs.m_data;
138  m_end = rhs.m_end;
139  m_curRow = rhs.m_curRow;
140  m_curColumn = rhs.m_curColumn;
141  m_matrix = rhs.m_matrix;
142  m_curIndex = rhs.m_curIndex;
143  m_transpose = rhs.m_transpose;
144  return *this;
145  }
146 
148  {
149  if( m_data )
150  {
151  ASSERTL1(m_data < m_end, "Attempt to dereference matrix iterator after its end.");
152  return *m_data;
153  }
154  else
155  {
156  return m_matrix->GetPtr()[m_curIndex];
157  }
158  }
159 
161  {
162  if( m_data )
163  {
164  ASSERTL1(m_data < m_end, "Attempt to dereference matrix iterator after its end.");
165  return *m_data;
166  }
167  else
168  {
169  return m_matrix->GetPtr()[m_curIndex];
170  }
171  }
172 
173  /// \brief Prefix increment operator.
174  iterator_impl<T, MatrixType>& operator++()
175  {
176  if( m_data )
177  {
178  ++m_data;
179  }
180  else
181  {
182  std::tie(m_curRow, m_curColumn) =
183  m_matrix->Advance(m_curRow, m_curColumn, m_transpose);
184  if( m_curRow == std::numeric_limits<unsigned int>::max() )
185  {
186  m_curIndex = m_curRow;
187  }
188  else
189  {
190  m_curIndex = m_matrix->CalculateIndex(m_curRow, m_curColumn, m_transpose);
191  }
192  }
193  return *this;
194  }
195 
196  /// \postfix increment operator.
197  iterator_impl<T, MatrixType> operator++(int)
198  {
199  iterator_impl<T, MatrixType> result = *this;
200  ++(*this);
201  return result;
202  }
203 
204  bool operator==(const iterator_impl<T, MatrixType>& rhs)
205  {
206  return m_data == rhs.m_data &&
207  m_end == rhs.m_end &&
208  m_curRow == rhs.m_curRow &&
209  m_curColumn == rhs.m_curColumn &&
210  m_matrix == rhs.m_matrix &&
211  m_curIndex == rhs.m_curIndex &&
212  m_transpose == rhs.m_transpose;
213  }
214 
215  bool operator!=(const iterator_impl<T, MatrixType>& rhs)
216  {
217  return !(*this == rhs);
218  }
219 
220  private:
221  // Used when the matrix is not transposed
222  T* m_data;
223  T* m_end;
224 
225  // Used when the matrix is transposed.
226  unsigned int m_curRow;
227  unsigned int m_curColumn;
229  unsigned int m_curIndex;
231  };
232 
233  public:
234  /// \brief Creates an empty matrix.
236 
237  /// \brief Creates a rows by columns matrix.
238  /// \brief rows The number of rows in the matrix.
239  /// \brief columns The number of columns in the matrix.
240  LIB_UTILITIES_EXPORT NekMatrix(unsigned int rows, unsigned int columns, MatrixStorage policy = eFULL,
241  unsigned int subDiagonals = std::numeric_limits<unsigned int>::max(),
242  unsigned int superDiagonals = std::numeric_limits<unsigned int>::max());
243 
244  LIB_UTILITIES_EXPORT NekMatrix(unsigned int rows, unsigned int columns,
245  MatrixStorage policy,
246  unsigned int subDiagonals,
247  unsigned int superDiagonals,
248  unsigned int capacity);
249 
250  /// \brief Creates a rows by columns matrix.
251  /// \brief rows The number of rows in the matrix.
252  /// \brief columns The number of columns in the matrix.
253  /// \brief initValue The value used to initialize each element.
254  /// \brief policySpecificData Data the is specific to the storage type assigned to this matrix.
255  /// Check MatrixStoragePolicy<StorageType> to see if the StoragePolicy
256  /// for this matrix has policy specific data.
257  LIB_UTILITIES_EXPORT NekMatrix(unsigned int rows, unsigned int columns, typename boost::call_traits<DataType>::const_reference initValue,
258  MatrixStorage policy = eFULL,
259  unsigned int subDiagonals = std::numeric_limits<unsigned int>::max(),
260  unsigned int superDiagonals = std::numeric_limits<unsigned int>::max());
261 
262  /// \brief Creates a rows by columns matrix.
263  /// \brief rows The number of rows in the matrix.
264  /// \brief columns The number of columns in the matrix.
265  /// \brief data An array of data use to initialize the matrix.
266  /// \brief policySpecificData Data the is specific to the storage type assigned to this matrix.
267  /// Check MatrixStoragePolicy<StorageType> to see if the StoragePolicy
268  /// for this matrix has policy specific data.
269  LIB_UTILITIES_EXPORT NekMatrix(unsigned int rows, unsigned int columns, const DataType* data,
270  MatrixStorage policy = eFULL,
271  unsigned int subDiagonals = std::numeric_limits<unsigned int>::max(),
272  unsigned int superDiagonals = std::numeric_limits<unsigned int>::max());
273 
274  /// \brief Creates a rows by columns matrix.
275  /// \brief rows The number of rows in the matrix.
276  /// \brief columns The number of columns in the matrix.
277  /// \brief d An array of data used to initialize the matrix. Values from d are copied into the matrix.
278  /// \brief policySpecificData Data the is specific to the storage type assigned to this matrix.
279  /// Check MatrixStoragePolicy<StorageType> to see if the StoragePolicy
280  /// for this matrix has policy specific data.
281  LIB_UTILITIES_EXPORT NekMatrix(unsigned int rows, unsigned int columns, const Array<OneD, const DataType>& d,
282  MatrixStorage policy = eFULL,
283  unsigned int subDiagonals = std::numeric_limits<unsigned int>::max(),
284  unsigned int superDiagonals = std::numeric_limits<unsigned int>::max());
285 
286  /// \brief Creates a rows by columns matrix.
287  /// \brief rows The number of rows in the matrix.
288  /// \brief columns The number of columns in the matrix.
289  /// \brief d An array of data used to initialize the matrix. If wrapperType is eCopy, then
290  /// each element is copied from d to the matrix. If wrapperType is eWrapper, then
291  /// the matrix uses d directly as its matrix data and no copies are made.
292  /// \brief policySpecificData Data the is specific to the storage type assigned to this matrix.
293  /// Check MatrixStoragePolicy<StorageType> to see if the StoragePolicy
294  /// for this matrix has policy specific data.
295  LIB_UTILITIES_EXPORT NekMatrix(unsigned int rows, unsigned int columns, const Array<OneD, DataType>& d, PointerWrapper wrapperType = eCopy,
296  MatrixStorage policy = eFULL,
297  unsigned int subDiagonals = std::numeric_limits<unsigned int>::max(),
298  unsigned int superDiagonals = std::numeric_limits<unsigned int>::max());
299 
301 
302  LIB_UTILITIES_EXPORT ThisType& operator=(const ThisType& rhs);
303 
304  LIB_UTILITIES_EXPORT ThisType& operator=(const DataType& rhs);
305 
306  template<typename InnerMatrixType>
308  {
309  BaseType::operator=(rhs);
310  m_numberOfSubDiagonals = rhs.GetNumberOfSubDiagonals();
311  m_numberOfSuperDiagonals = rhs.GetNumberOfSuperDiagonals();
312 
313  ResizeDataArrayIfNeeded();
314 
315  unsigned int requiredStorageSize = GetRequiredStorageSize();
316  DataType scale = rhs.Scale();
317 
318  DataType* lhs_array = m_data.data();
319  const DataType* rhs_array = rhs.GetRawPtr();
320 
321  for(unsigned int i = 0; i < requiredStorageSize; ++i)
322  {
323  lhs_array[i] = scale*rhs_array[i];
324  }
325 
326  return *this;
327 
328  }
329 
330 
331  /// \brief Returns the element value at the given row and column.
332  LIB_UTILITIES_EXPORT ConstGetValueType operator()(unsigned int row, unsigned int column) const;
333 
334  class Proxy
335  {
336  public:
337  Proxy() : m_value(defaultReturnValue) {}
338  explicit Proxy(DataType& value) : m_value(value) {}
339  Proxy(const Proxy& rhs) : m_value(rhs.m_value) {}
340  Proxy& operator=(const Proxy& rhs)
341  {
342  m_value = rhs.m_value;
343  return *this;
344  }
345 
346  DataType& operator*() { return m_value; }
347  const DataType& operator*() const { return m_value; }
348  operator DataType&() { return m_value; }
349  operator const DataType&() const { return m_value; }
350  void operator=(const DataType& newValue)
351  {
352  if( &m_value != &defaultReturnValue )
353  {
354  m_value = newValue;
355  }
356  }
357 
358  private:
359  DataType& m_value;
360  static DataType defaultReturnValue;
361  };
362 
363  /// \brief Returns the element value at the given row and column.
364  /// \brief row The element's row.
365  /// \brief column The element's column.
366  /// \brief transpose If transpose = 'N', then the return value is element [row, column].
367  /// If transpose = 'T', then the return value is element [column, row].
368  LIB_UTILITIES_EXPORT ConstGetValueType operator()(unsigned int row, unsigned int column, char transpose) const;
369 
370  LIB_UTILITIES_EXPORT unsigned int GetRequiredStorageSize() const;
371 
372  LIB_UTILITIES_EXPORT unsigned int CalculateIndex(unsigned int row, unsigned int col, const char transpose) const;
373 
374  /// \brief Returns the element value at the given row and column.
375  LIB_UTILITIES_EXPORT typename boost::call_traits<DataType>::const_reference GetValue(unsigned int row, unsigned int column) const;
376 
377  /// \brief Returns the element value at the given row and column.
378  /// \brief row The element's row.
379  /// \brief column The element's column.
380  /// \brief transpose If transpose = 'N', then the return value is element [row, column].
381  /// If transpose = 'T', then the return value is element [column, row].
382  LIB_UTILITIES_EXPORT ConstGetValueType GetValue(unsigned int row, unsigned int column, char transpose) const;
383 
385 
386  /// \brief Returns the scaling used by this matrix.
387  ///
388  /// Since this matrix is not a scaled matrix, this method always returns 1.
389  LIB_UTILITIES_EXPORT DataType Scale() const;
390 
391  LIB_UTILITIES_EXPORT const DataType* GetRawPtr() const;
392 
393  typedef iterator_impl<const DataType, const ThisType> const_iterator;
394  typedef iterator_impl<DataType, ThisType> iterator;
395 
397 
398  LIB_UTILITIES_EXPORT iterator begin(char transpose);
399 
401  LIB_UTILITIES_EXPORT iterator end(char transpose);
402 
403  LIB_UTILITIES_EXPORT const_iterator begin() const;
404 
405  LIB_UTILITIES_EXPORT const_iterator begin(char transpose) const;
406 
408 
409  LIB_UTILITIES_EXPORT const_iterator end(char transpose) const;
410 
411 
412  LIB_UTILITIES_EXPORT unsigned int GetStorageSize() const;
413 
414  // Banded matrices only.
415  // Get the specified number of sub diagonals, or calculate the
416  // number if this object has not been initialized.
417  LIB_UTILITIES_EXPORT unsigned int GetNumberOfSubDiagonals() const;
418 
419  LIB_UTILITIES_EXPORT unsigned int GetNumberOfSuperDiagonals() const;
420 
421  LIB_UTILITIES_EXPORT unsigned int CalculateNumberOfRows() const;
422 
423  /// \brief Returns true if the this matrix and rhs are equivalent.
424  ///
425  /// Two matrices are equivalent if they have the same size and each element
426  /// is the same.
428 
429  LIB_UTILITIES_EXPORT PointerWrapper GetWrapperType() const;
430 
431  LIB_UTILITIES_EXPORT std::tuple<unsigned int, unsigned int>
432  Advance(unsigned int curRow, unsigned int curColumn) const;
433 
434  LIB_UTILITIES_EXPORT std::tuple<unsigned int, unsigned int>
435  Advance(unsigned int curRow, unsigned int curColumn, char transpose) const;
436 
437  LIB_UTILITIES_EXPORT static ThisType CreateWrapper(const ThisType& rhs);
438 
439  LIB_UTILITIES_EXPORT static std::shared_ptr<ThisType> CreateWrapper(const std::shared_ptr<ThisType>& rhs);
440 
441  LIB_UTILITIES_EXPORT void SetSize(unsigned int rows, unsigned int cols);
442 
443  LIB_UTILITIES_EXPORT Proxy operator()(unsigned int row, unsigned int column);
444 
445 
446  LIB_UTILITIES_EXPORT Proxy operator()(unsigned int row, unsigned int column, char transpose);
447 
448  LIB_UTILITIES_EXPORT void SetValue(unsigned int row, unsigned int column, typename boost::call_traits<DataType>::const_reference d);
449 
450  LIB_UTILITIES_EXPORT void SetValue(unsigned int row, unsigned int column, typename boost::call_traits<DataType>::const_reference d, char transpose);
451 
453 
454  LIB_UTILITIES_EXPORT DataType* GetRawPtr();
455 
456 
457 
458  LIB_UTILITIES_EXPORT DataType AbsMaxtoMinEigenValueRatio(void);
459 
460  LIB_UTILITIES_EXPORT void EigenSolve(Array<OneD, DataType> &EigValReal,
461  Array<OneD, DataType> &EigValImag,
462  Array<OneD, DataType> &EigVecs);
463 
464  LIB_UTILITIES_EXPORT void Invert();
465 
467 
468  LIB_UTILITIES_EXPORT void SwapTempAndDataBuffers();
469 
470  LIB_UTILITIES_EXPORT ThisType& operator*=(const NumberType& s);
471 
473 
474  protected:
475  LIB_UTILITIES_EXPORT NekMatrix(const ThisType& rhs, PointerWrapper wrapperType);
476 
478 
479  LIB_UTILITIES_EXPORT void RemoveExcessCapacity();
480 
481  LIB_UTILITIES_EXPORT void ResizeDataArrayIfNeeded(unsigned int requiredStorageSize);
482 
483  LIB_UTILITIES_EXPORT void ResizeDataArrayIfNeeded();
484 
485 
486  private:
487  LIB_UTILITIES_EXPORT void PerformCopyConstruction(const ThisType& rhs);
488 
489  LIB_UTILITIES_EXPORT virtual typename boost::call_traits<DataType>::value_type v_GetValue(unsigned int row, unsigned int column) const;
490 
491  LIB_UTILITIES_EXPORT virtual unsigned int v_GetStorageSize() const ;
492 
493  // We need to rethink class structure a little. This shouldn't be necessary.
494  LIB_UTILITIES_EXPORT virtual void v_SetValue(unsigned int row, unsigned int column, typename boost::call_traits<DataType>::const_reference d);
495 
498 
499  // Only used by banded matrices.
502 
503  // Used during chained matrix multiplication as workspace.
505  };
506 
507 
508  template<typename DataType>
510 
511  template<typename DataType>
514 
515  template<typename DataType>
517 }
518 
519 #endif //NEKTAR_LIB_UTILITIES_LINEAR_ALGEBRA_STANDARD_MATRIX_HPP
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:250
#define LIB_UTILITIES_EXPORT
1D Array of constant elements with garbage collection and bounds checking.
Definition: SharedArray.hpp:59
boost::call_traits< value_type >::const_reference const_reference
bool operator!=(const iterator_impl< T, MatrixType > &rhs)
std::remove_reference< value_type >::type * pointer
boost::call_traits< value_type >::reference reference
iterator_impl< T, MatrixType > operator++(int)
\postfix increment operator.
iterator_impl< T, MatrixType > & operator++()
Prefix increment operator.
iterator_impl< T, MatrixType > & operator=(const iterator_impl< T, MatrixType > &rhs)
bool operator==(const iterator_impl< T, MatrixType > &rhs)
iterator_impl(MatrixType *m, char transpose, bool isEnd=false)
iterator_impl(const iterator_impl< T, MatrixType > &rhs)
NekMatrix< DataType, StandardMatrixTag > ThisType
iterator_impl< const DataType, const ThisType > const_iterator
iterator_impl< DataType, ThisType > iterator
ThisType & operator=(const NekMatrix< InnerMatrixType, ScaledMatrixTag > &rhs)
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:1
bool operator==(const Array< OneD, T1 > &lhs, const Array< OneD, T2 > &rhs)
NekMatrix< InnerMatrixType, BlockMatrixTag > Transpose(NekMatrix< InnerMatrixType, BlockMatrixTag > &rhs)
void NegateInPlace(NekVector< DataType > &v)
Definition: NekVector.cpp:1184
NekMatrix< typename NekMatrix< LhsDataType, LhsMatrixType >::NumberType, StandardMatrixTag > operator-(const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
PointerWrapper
Specifies if the pointer passed to a NekMatrix or NekVector is copied into an internal representation...