Nektar++
MatrixOperations.hpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: MatrixOperations.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: Defines the global functions needed for matrix operations.
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #ifndef NEKTAR_LIB_UTILITIES_LINEAR_ALGEBRA_MATRIX_OPERATIONS_DECLARATIONS_HPP
36 #define NEKTAR_LIB_UTILITIES_LINEAR_ALGEBRA_MATRIX_OPERATIONS_DECLARATIONS_HPP
37 
38 #include <boost/core/ignore_unused.hpp>
39 
40 // Since this file defines all of the operations for all combination of matrix
41 // types, we have to include all matrix specializations first.
42 
50 
51 #include <string>
52 #include <type_traits>
53 
54 namespace Nektar
55 {
56 ////////////////////////////////////////////////////////////////////////////////
57 // Matrix-Vector Multiplication
58 ////////////////////////////////////////////////////////////////////////////////
59 template <typename DataType, typename LhsDataType, typename MatrixType>
60 NekVector<DataType> Multiply(const NekMatrix<LhsDataType, MatrixType> &lhs,
61  const NekVector<DataType> &rhs);
62 
63 template <typename DataType, typename LhsDataType, typename MatrixType>
64 void Multiply(NekVector<DataType> &result,
65  const NekMatrix<LhsDataType, MatrixType> &lhs,
66  const NekVector<DataType> &rhs);
67 
68 template <typename DataType, typename LhsInnerMatrixType>
69 void Multiply(NekVector<DataType> &result,
70  const NekMatrix<LhsInnerMatrixType, BlockMatrixTag> &lhs,
71  const NekVector<DataType> &rhs);
72 
73 template <typename DataType, typename LhsDataType, typename MatrixType>
75  const NekVector<DataType> &rhs)
76 {
77  return Multiply(lhs, rhs);
78 }
79 
81  NekVector<double> &result,
82  const NekMatrix<
84  BlockMatrixTag> &lhs,
85  const NekVector<double> &rhs);
86 
87 ////////////////////////////////////////////////////////////////////////////////
88 // Matrix-Constant Multiplication
89 ////////////////////////////////////////////////////////////////////////////////
90 template <typename ResultDataType, typename LhsDataType, typename LhsMatrixType>
93  const ResultDataType &rhs);
94 
95 template <typename DataType, typename LhsDataType, typename LhsMatrixType>
97  StandardMatrixTag>
98 Multiply(const NekMatrix<LhsDataType, LhsMatrixType> &lhs, const DataType &rhs);
99 
100 template <typename RhsDataType, typename RhsMatrixType, typename ResultDataType>
102  const ResultDataType &lhs,
104 
105 template <typename DataType, typename RhsDataType, typename RhsMatrixType>
107  StandardMatrixTag>
108 Multiply(const DataType &lhs, const NekMatrix<RhsDataType, RhsMatrixType> &rhs);
109 
110 template <typename DataType, typename RhsDataType, typename RhsMatrixType>
112  StandardMatrixTag>
113 operator*(const DataType &lhs, const NekMatrix<RhsDataType, RhsMatrixType> &rhs)
114 {
115  return Multiply(lhs, rhs);
116 }
117 
118 template <typename DataType, typename RhsDataType, typename RhsMatrixType>
120  StandardMatrixTag>
121 operator*(const NekMatrix<RhsDataType, RhsMatrixType> &lhs, const DataType &rhs)
122 {
123  return Multiply(lhs, rhs);
124 }
125 
126 template <typename LhsDataType>
127 void MultiplyEqual(
129  typename boost::call_traits<LhsDataType>::const_reference rhs);
130 
131 ///////////////////////////////////////////////////////////////////
132 // Matrix-Matrix Multipliation
133 //////////////////////////////////////////////////////////////////
134 
135 template <typename LhsDataType, typename RhsDataType, typename LhsMatrixType,
136  typename RhsMatrixType>
141  typename std::enable_if<
144  0)
145 {
146  boost::ignore_unused(p);
147 
148  ASSERTL1(lhs.GetType() == eFULL && rhs.GetType() == eFULL,
149  "Only full matrices are supported.");
150 
151  unsigned int M = lhs.GetRows();
152  unsigned int N = rhs.GetColumns();
153  unsigned int K = lhs.GetColumns();
154 
155  unsigned int LDA = M;
156  if (lhs.GetTransposeFlag() == 'T')
157  {
158  LDA = K;
159  }
160 
161  unsigned int LDB = K;
162  if (rhs.GetTransposeFlag() == 'T')
163  {
164  LDB = N;
165  }
166 
167  Blas::Dgemm(lhs.GetTransposeFlag(), rhs.GetTransposeFlag(), M, N, K,
168  lhs.Scale() * rhs.Scale(), lhs.GetRawPtr(), LDA,
169  rhs.GetRawPtr(), LDB, 0.0, result.GetRawPtr(),
170  result.GetRows());
171 }
172 
173 template <typename LhsDataType, typename RhsDataType, typename DataType,
174  typename LhsMatrixType, typename RhsMatrixType>
178 
179 template <typename RhsInnerType, typename RhsMatrixType>
183  typename std::enable_if<
184  std::is_same<RawType_t<typename NekMatrix<
185  RhsInnerType, RhsMatrixType>::NumberType>,
186  double>::value &&
188  0)
189 {
190  boost::ignore_unused(t);
191  ASSERTL0(result.GetType() == eFULL && rhs.GetType() == eFULL,
192  "Only full matrices supported.");
193  unsigned int M = result.GetRows();
194  unsigned int N = rhs.GetColumns();
195  unsigned int K = result.GetColumns();
196 
197  unsigned int LDA = M;
198  if (result.GetTransposeFlag() == 'T')
199  {
200  LDA = K;
201  }
202 
203  unsigned int LDB = K;
204  if (rhs.GetTransposeFlag() == 'T')
205  {
206  LDB = N;
207  }
208  double scale = rhs.Scale();
209  Array<OneD, double> &buf = result.GetTempSpace();
210  Blas::Dgemm(result.GetTransposeFlag(), rhs.GetTransposeFlag(), M, N, K,
211  scale, result.GetRawPtr(), LDA, rhs.GetRawPtr(), LDB, 0.0,
212  buf.data(), result.GetRows());
213  result.SetSize(result.GetRows(), rhs.GetColumns());
214  result.SwapTempAndDataBuffers();
215 }
216 
217 template <typename DataType, typename RhsInnerType, typename RhsMatrixType>
221  typename std::enable_if<
222  !std::is_same<RawType_t<typename NekMatrix<
223  RhsInnerType, RhsMatrixType>::NumberType>,
224  double>::value ||
226  0)
227 {
228  boost::ignore_unused(t);
229  ASSERTL1(result.GetColumns() == rhs.GetRows(),
230  std::string("A left side matrix with column count ") +
231  std::to_string(result.GetColumns()) +
232  std::string(" and a right side matrix with row count ") +
233  std::to_string(rhs.GetRows()) +
234  std::string(" can't be multiplied."));
236  result.GetColumns());
237 
238  for (unsigned int i = 0; i < result.GetRows(); ++i)
239  {
240  for (unsigned int j = 0; j < result.GetColumns(); ++j)
241  {
242  DataType t = DataType(0);
243 
244  // Set the result(i,j) element.
245  for (unsigned int k = 0; k < result.GetColumns(); ++k)
246  {
247  t += result(i, k) * rhs(k, j);
248  }
249  temp(i, j) = t;
250  }
251  }
252 
253  result = temp;
254 }
255 
256 template <typename LhsDataType, typename RhsDataType, typename LhsMatrixType,
257  typename RhsMatrixType>
258 NekMatrix<typename std::remove_const<
260  StandardMatrixTag>
263 {
264  typedef typename std::remove_const<
266  NumberType;
267  NekMatrix<NumberType, StandardMatrixTag> result(lhs.GetRows(),
268  rhs.GetColumns());
269  Multiply(result, lhs, rhs);
270  return result;
271 }
272 
273 template <typename LhsDataType, typename RhsDataType, typename LhsMatrixType,
274  typename RhsMatrixType>
275 NekMatrix<typename std::remove_const<
277  StandardMatrixTag>
280 {
281  return Multiply(lhs, rhs);
282 }
283 
284 ///////////////////////////////////////////////////////////////////
285 // Addition
286 ///////////////////////////////////////////////////////////////////
287 
288 template <typename DataType, typename RhsDataType, typename RhsMatrixType>
291 
292 template <typename DataType, typename LhsDataType, typename LhsMatrixType,
293  typename RhsDataType, typename RhsMatrixType>
297 
298 template <typename LhsDataType, typename LhsMatrixType, typename RhsDataType,
299  typename RhsMatrixType>
301  StandardMatrixTag>
304 
305 template <typename LhsDataType, typename LhsMatrixType, typename RhsDataType,
306  typename RhsMatrixType>
307 NekMatrix<typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType,
308  StandardMatrixTag>
311 {
312  return Add(lhs, rhs);
313 }
314 
315 template <typename DataType, typename LhsDataType, typename LhsMatrixType,
316  typename RhsDataType, typename RhsMatrixType>
320 
321 template <typename DataType, typename RhsDataType, typename RhsMatrixType>
324 
325 ////////////////////////////////////////////////////////////////////////////////
326 // Subtraction
327 ////////////////////////////////////////////////////////////////////////////////
328 template <typename DataType, typename LhsDataType, typename LhsMatrixType,
329  typename RhsDataType, typename RhsMatrixType>
333 
334 template <typename DataType, typename LhsDataType, typename LhsMatrixType,
335  typename RhsDataType, typename RhsMatrixType>
339 
340 template <typename DataType, typename RhsDataType, typename RhsMatrixType>
343 
344 template <typename DataType, typename RhsDataType, typename RhsMatrixType>
347 
348 template <typename LhsDataType, typename LhsMatrixType, typename RhsDataType,
349  typename RhsMatrixType>
350 NekMatrix<typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType,
351  StandardMatrixTag>
354 
355 template <typename LhsDataType, typename LhsMatrixType, typename RhsDataType,
356  typename RhsMatrixType>
357 NekMatrix<typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType,
358  StandardMatrixTag>
361 {
362  return Subtract(lhs, rhs);
363 }
364 
365 }
366 
367 #endif
void SubtractNegatedLhs(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
void DiagonalBlockFullScalMatrixMultiply(NekVector< double > &result, const NekMatrix< NekMatrix< NekMatrix< NekDouble, StandardMatrixTag >, ScaledMatrixTag >, BlockMatrixTag > &lhs, const NekVector< double > &rhs)
void MultiplyEqual(NekMatrix< LhsDataType, StandardMatrixTag > &lhs, typename boost::call_traits< LhsDataType >::const_reference rhs)
void NekMultiplyFullMatrixFullMatrix(NekMatrix< ResultType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
static void Dgemm(const char &transa, const char &transb, const int &m, const int &n, const int &k, const double &alpha, const double *a, const int &lda, const double *b, const int &ldb, const double &beta, double *c, const int &ldc)
BLAS level 3: Matrix-matrix multiply C = A x B where A[m x n], B[n x k], C[m x k].
Definition: Blas.hpp:213
StandardMatrixTag & lhs
RhsMatrixType void AddEqual(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
void Multiply(NekMatrix< ResultDataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const ResultDataType &rhs)
unsigned int GetColumns() const
Definition: MatrixBase.cpp:77
void AddEqualNegatedLhs(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
DNekMat void SubtractEqual(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
NekVector< DataType > operator*(const NekMatrix< LhsDataType, MatrixType > &lhs, const NekVector< DataType > &rhs)
void SubtractEqualNegatedLhs(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
#define LIB_UTILITIES_EXPORT
void AddNegatedLhs(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
unsigned int GetRows() const
Definition: MatrixBase.cpp:58
NekMatrix< typename NekMatrix< LhsDataType, LhsMatrixType >::NumberType, StandardMatrixTag > operator-(const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
DNekMat void Add(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs
RhsMatrixType void Subtract(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:250
Array< OneD, DataType > operator+(const Array< OneD, DataType > &lhs, size_t offset)
typename RawType< T >::type RawType_t
Definition: RawType.hpp:76