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<
83  NekMatrix<NekMatrix<NekDouble, StandardMatrixTag>, ScaledMatrixTag>,
84  BlockMatrixTag> &lhs,
85  const NekVector<double> &rhs);
86 
88  NekVector<NekSingle> &result,
89  const NekMatrix<
90  NekMatrix<NekMatrix<NekSingle, StandardMatrixTag>, ScaledMatrixTag>,
91  BlockMatrixTag> &lhs,
92  const NekVector<NekSingle> &rhs);
93 
94 ////////////////////////////////////////////////////////////////////////////////
95 // Matrix-Constant Multiplication
96 ////////////////////////////////////////////////////////////////////////////////
97 template <typename ResultDataType, typename LhsDataType, typename LhsMatrixType>
98 void Multiply(NekMatrix<ResultDataType, StandardMatrixTag> &result,
99  const NekMatrix<LhsDataType, LhsMatrixType> &lhs,
100  const ResultDataType &rhs);
101 
102 template <typename DataType, typename LhsDataType, typename LhsMatrixType>
103 NekMatrix<typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType,
104  StandardMatrixTag>
105 Multiply(const NekMatrix<LhsDataType, LhsMatrixType> &lhs, const DataType &rhs);
106 
107 template <typename RhsDataType, typename RhsMatrixType, typename ResultDataType>
108 void Multiply(NekMatrix<ResultDataType, StandardMatrixTag> &result,
109  const ResultDataType &lhs,
110  const NekMatrix<RhsDataType, RhsMatrixType> &rhs);
111 
112 template <typename DataType, typename RhsDataType, typename RhsMatrixType>
113 NekMatrix<typename NekMatrix<RhsDataType, RhsMatrixType>::NumberType,
114  StandardMatrixTag>
115 Multiply(const DataType &lhs, const NekMatrix<RhsDataType, RhsMatrixType> &rhs);
116 
117 template <typename DataType, typename RhsDataType, typename RhsMatrixType>
118 NekMatrix<typename NekMatrix<RhsDataType, RhsMatrixType>::NumberType,
119  StandardMatrixTag>
120 operator*(const DataType &lhs, const NekMatrix<RhsDataType, RhsMatrixType> &rhs)
121 {
122  return Multiply(lhs, rhs);
123 }
124 
125 template <typename DataType, typename RhsDataType, typename RhsMatrixType>
126 NekMatrix<typename NekMatrix<RhsDataType, RhsMatrixType>::NumberType,
127  StandardMatrixTag>
128 operator*(const NekMatrix<RhsDataType, RhsMatrixType> &lhs, const DataType &rhs)
129 {
130  return Multiply(lhs, rhs);
131 }
132 
133 template <typename LhsDataType>
134 void MultiplyEqual(
135  NekMatrix<LhsDataType, StandardMatrixTag> &lhs,
136  typename boost::call_traits<LhsDataType>::const_reference rhs);
137 
138 ///////////////////////////////////////////////////////////////////
139 // Matrix-Matrix Multipliation
140 //////////////////////////////////////////////////////////////////
141 
142 template <typename LhsDataType, typename RhsDataType, typename LhsMatrixType,
143  typename RhsMatrixType>
148  typename std::enable_if<
151  0)
152 {
153  boost::ignore_unused(p);
154 
155  ASSERTL1(lhs.GetType() == eFULL && rhs.GetType() == eFULL,
156  "Only full matrices are supported.");
157 
158  unsigned int M = lhs.GetRows();
159  unsigned int N = rhs.GetColumns();
160  unsigned int K = lhs.GetColumns();
161 
162  unsigned int LDA = M;
163  if (lhs.GetTransposeFlag() == 'T')
164  {
165  LDA = K;
166  }
167 
168  unsigned int LDB = K;
169  if (rhs.GetTransposeFlag() == 'T')
170  {
171  LDB = N;
172  }
173 
174  Blas::Gemm(lhs.GetTransposeFlag(), rhs.GetTransposeFlag(), M, N, K,
175  lhs.Scale() * rhs.Scale(), lhs.GetRawPtr(), LDA,
176  rhs.GetRawPtr(), LDB, 0.0, result.GetRawPtr(),
177  result.GetRows());
178 }
179 
180 template <typename LhsDataType, typename RhsDataType, typename DataType,
181  typename LhsMatrixType, typename RhsMatrixType>
182 void Multiply(NekMatrix<DataType, StandardMatrixTag> &result,
183  const NekMatrix<LhsDataType, LhsMatrixType> &lhs,
184  const NekMatrix<RhsDataType, RhsMatrixType> &rhs);
185 
186 template <typename RhsInnerType, typename RhsMatrixType>
190  typename std::enable_if<
191  std::is_same<RawType_t<typename NekMatrix<
192  RhsInnerType, RhsMatrixType>::NumberType>,
193  RhsInnerType>::value &&
195  0)
196 {
197  boost::ignore_unused(t);
198  ASSERTL0(result.GetType() == eFULL && rhs.GetType() == eFULL,
199  "Only full matrices supported.");
200  unsigned int M = result.GetRows();
201  unsigned int N = rhs.GetColumns();
202  unsigned int K = result.GetColumns();
203 
204  unsigned int LDA = M;
205  if (result.GetTransposeFlag() == 'T')
206  {
207  LDA = K;
208  }
209 
210  unsigned int LDB = K;
211  if (rhs.GetTransposeFlag() == 'T')
212  {
213  LDB = N;
214  }
215  RhsInnerType scale = rhs.Scale();
216  Array<OneD, RhsInnerType> &buf = result.GetTempSpace();
217  Blas::Gemm(result.GetTransposeFlag(), rhs.GetTransposeFlag(), M, N, K,
218  scale, result.GetRawPtr(), LDA, rhs.GetRawPtr(), LDB, 0.0,
219  buf.data(), result.GetRows());
220  result.SetSize(result.GetRows(), rhs.GetColumns());
221  result.SwapTempAndDataBuffers();
222 }
223 
224 template <typename DataType, typename RhsInnerType, typename RhsMatrixType>
228  typename std::enable_if<
229  !std::is_same<RawType_t<typename NekMatrix<
230  RhsInnerType, RhsMatrixType>::NumberType>,
231  DataType>::value ||
233  0)
234 {
235  boost::ignore_unused(t);
236  ASSERTL1(result.GetColumns() == rhs.GetRows(),
237  std::string("A left side matrix with column count ") +
238  std::to_string(result.GetColumns()) +
239  std::string(" and a right side matrix with row count ") +
240  std::to_string(rhs.GetRows()) +
241  std::string(" can't be multiplied."));
243  result.GetColumns());
244 
245  for (unsigned int i = 0; i < result.GetRows(); ++i)
246  {
247  for (unsigned int j = 0; j < result.GetColumns(); ++j)
248  {
249  DataType t = DataType(0);
250 
251  // Set the result(i,j) element.
252  for (unsigned int k = 0; k < result.GetColumns(); ++k)
253  {
254  t += result(i, k) * rhs(k, j);
255  }
256  temp(i, j) = t;
257  }
258  }
259 
260  result = temp;
261 }
262 
263 template <typename LhsDataType, typename RhsDataType, typename LhsMatrixType,
264  typename RhsMatrixType>
265 NekMatrix<typename std::remove_const<
266  typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType>::type,
267  StandardMatrixTag>
270 {
271  typedef typename std::remove_const<
273  NumberType;
274  NekMatrix<NumberType, StandardMatrixTag> result(lhs.GetRows(),
275  rhs.GetColumns());
276  Multiply(result, lhs, rhs);
277  return result;
278 }
279 
280 template <typename LhsDataType, typename RhsDataType, typename LhsMatrixType,
281  typename RhsMatrixType>
282 NekMatrix<typename std::remove_const<
283  typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType>::type,
284  StandardMatrixTag>
287 {
288  return Multiply(lhs, rhs);
289 }
290 
291 ///////////////////////////////////////////////////////////////////
292 // Addition
293 ///////////////////////////////////////////////////////////////////
294 
295 template <typename DataType, typename RhsDataType, typename RhsMatrixType>
296 void AddEqual(NekMatrix<DataType, StandardMatrixTag> &result,
297  const NekMatrix<RhsDataType, RhsMatrixType> &rhs);
298 
299 template <typename DataType, typename LhsDataType, typename LhsMatrixType,
300  typename RhsDataType, typename RhsMatrixType>
301 void Add(NekMatrix<DataType, StandardMatrixTag> &result,
302  const NekMatrix<LhsDataType, LhsMatrixType> &lhs,
303  const NekMatrix<RhsDataType, RhsMatrixType> &rhs);
304 
305 template <typename LhsDataType, typename LhsMatrixType, typename RhsDataType,
306  typename RhsMatrixType>
307 NekMatrix<typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType,
308  StandardMatrixTag>
309 Add(const NekMatrix<LhsDataType, LhsMatrixType> &lhs,
310  const NekMatrix<RhsDataType, RhsMatrixType> &rhs);
311 
312 template <typename LhsDataType, typename LhsMatrixType, typename RhsDataType,
313  typename RhsMatrixType>
314 NekMatrix<typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType,
315  StandardMatrixTag>
318 {
319  return Add(lhs, rhs);
320 }
321 
322 template <typename DataType, typename LhsDataType, typename LhsMatrixType,
323  typename RhsDataType, typename RhsMatrixType>
324 void AddNegatedLhs(NekMatrix<DataType, StandardMatrixTag> &result,
325  const NekMatrix<LhsDataType, LhsMatrixType> &lhs,
326  const NekMatrix<RhsDataType, RhsMatrixType> &rhs);
327 
328 template <typename DataType, typename RhsDataType, typename RhsMatrixType>
329 void AddEqualNegatedLhs(NekMatrix<DataType, StandardMatrixTag> &result,
330  const NekMatrix<RhsDataType, RhsMatrixType> &rhs);
331 
332 ////////////////////////////////////////////////////////////////////////////////
333 // Subtraction
334 ////////////////////////////////////////////////////////////////////////////////
335 template <typename DataType, typename LhsDataType, typename LhsMatrixType,
336  typename RhsDataType, typename RhsMatrixType>
337 void Subtract(NekMatrix<DataType, StandardMatrixTag> &result,
338  const NekMatrix<LhsDataType, LhsMatrixType> &lhs,
339  const NekMatrix<RhsDataType, RhsMatrixType> &rhs);
340 
341 template <typename DataType, typename LhsDataType, typename LhsMatrixType,
342  typename RhsDataType, typename RhsMatrixType>
343 void SubtractNegatedLhs(NekMatrix<DataType, StandardMatrixTag> &result,
344  const NekMatrix<LhsDataType, LhsMatrixType> &lhs,
345  const NekMatrix<RhsDataType, RhsMatrixType> &rhs);
346 
347 template <typename DataType, typename RhsDataType, typename RhsMatrixType>
348 void SubtractEqual(NekMatrix<DataType, StandardMatrixTag> &result,
349  const NekMatrix<RhsDataType, RhsMatrixType> &rhs);
350 
351 template <typename DataType, typename RhsDataType, typename RhsMatrixType>
352 void SubtractEqualNegatedLhs(NekMatrix<DataType, StandardMatrixTag> &result,
353  const NekMatrix<RhsDataType, RhsMatrixType> &rhs);
354 
355 template <typename LhsDataType, typename LhsMatrixType, typename RhsDataType,
356  typename RhsMatrixType>
357 NekMatrix<typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType,
358  StandardMatrixTag>
359 Subtract(const NekMatrix<LhsDataType, LhsMatrixType> &lhs,
360  const NekMatrix<RhsDataType, RhsMatrixType> &rhs);
361 
362 template <typename LhsDataType, typename LhsMatrixType, typename RhsDataType,
363  typename RhsMatrixType>
364 NekMatrix<typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType,
365  StandardMatrixTag>
368 {
369  return Subtract(lhs, rhs);
370 }
371 
372 }
373 
374 #endif
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
#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
unsigned int GetRows() const
Definition: MatrixBase.cpp:58
unsigned int GetColumns() const
Definition: MatrixBase.cpp:77
static void Gemm(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 op(A)[m x k], op(B)[k x n], C[m x n] DGEMM perfo...
Definition: Blas.hpp:365
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:1
SNekMat SNekMat void SubtractEqual(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
NekVector< DataType > operator*(const NekMatrix< LhsDataType, MatrixType > &lhs, const NekVector< DataType > &rhs)
void AddEqualNegatedLhs(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
SNekMat void AddEqual(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
void Subtract(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
Array< OneD, DataType > operator+(const Array< OneD, DataType > &lhs, typename Array< OneD, DataType >::size_type offset)
void Multiply(NekMatrix< ResultDataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const ResultDataType &rhs)
void NekMultiplyFullMatrixFullMatrix(NekMatrix< ResultType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
void AddNegatedLhs(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
void DiagonalBlockFullScalMatrixMultiply(NekVector< double > &result, const NekMatrix< NekMatrix< NekMatrix< NekDouble, StandardMatrixTag >, ScaledMatrixTag >, BlockMatrixTag > &lhs, const NekVector< double > &rhs)
void SubtractEqualNegatedLhs(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
typename RawType< T >::type RawType_t
Definition: RawType.hpp:76
const NekSingle void MultiplyEqual(NekMatrix< LhsDataType, StandardMatrixTag > &lhs, typename boost::call_traits< LhsDataType >::const_reference rhs)
void SubtractNegatedLhs(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
NekMatrix< typename NekMatrix< LhsDataType, LhsMatrixType >::NumberType, StandardMatrixTag > operator-(const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
SNekMat SNekMat void Add(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)