Nektar++
MatrixOperations.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: MatrixOperations.cpp
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 
37 
38 namespace Nektar
39 {
40 template <typename ResultDataType, typename LhsDataType, typename LhsMatrixType>
43  const ResultDataType &rhs)
44 {
45  // TODO - optimize for the different matrix types.
46  int n = lhs.GetRows();
47  int m = lhs.GetColumns();
48  for (unsigned int i = 0; i < n; ++i)
49  {
50  for (unsigned int j = 0; j < m; ++j)
51  {
52  result(i, j) = lhs(i, j) * rhs;
53  }
54  }
55 }
56 
58  Multiply, NEKTAR_ALL_MATRIX_TYPES, (1, (void)), (1, (DNekMat &)),
59  (1, (const NekDouble &)))
62  (1, (const NekSingle &)))
63 
64 template <typename DataType, typename LhsDataType, typename LhsMatrixType>
66  StandardMatrixTag>
67 Multiply(const NekMatrix<LhsDataType, LhsMatrixType> &lhs, const DataType &rhs)
68 {
70  ResultDataType;
72  lhs.GetColumns());
73  Multiply(result, lhs, rhs);
74  return result;
75 }
76 
78  Multiply, NEKTAR_ALL_MATRIX_TYPES, (1, (DNekMat)), (0, ()),
79  (1, (const NekDouble &)))
82  (1, (const NekSingle &)))
83 
84 template <typename RhsDataType, typename RhsMatrixType, typename ResultDataType>
86  const ResultDataType &lhs,
88 
89 {
90  Multiply(result, rhs, lhs);
91 }
92 
94  Multiply, NEKTAR_ALL_MATRIX_TYPES, (1, (void)),
95  (2, (DNekMat &, const NekDouble &)), (0, ()))
98  (2, (SNekMat &, const NekSingle &)), (0, ()))
99 
100 template <typename DataType, typename RhsDataType, typename RhsMatrixType>
101 NekMatrix<typename NekMatrix<RhsDataType, RhsMatrixType>::NumberType,
102  StandardMatrixTag>
103 Multiply(const DataType &lhs, const NekMatrix<RhsDataType, RhsMatrixType> &rhs)
104 
105 {
106  return Multiply(rhs, lhs);
107 }
108 
110  Multiply, NEKTAR_ALL_MATRIX_TYPES, (1, (DNekMat)), (1, (const NekDouble &)),
111  (0, ()))
114  (1, (const NekSingle &)), (0, ()))
115 
116 template <typename LhsDataType>
118  NekMatrix<LhsDataType, StandardMatrixTag> &lhs,
119  typename boost::call_traits<LhsDataType>::const_reference rhs)
120 {
121  typedef
123  for (iterator iter = lhs.begin(); iter != lhs.end(); ++iter)
124  {
125  *iter *= rhs;
126  }
127 }
128 
130  MultiplyEqual, (1, (DNekMat &)), (1, (void)), (0, ()),
131  (1, (const NekDouble &)))
133  MultiplyEqual, (1, (SNekMat &)), (1, (void)), (0, ()),
134  (1, (const NekSingle &)))
135 
136 template <typename ResultType, typename LhsDataType, typename RhsDataType,
137  typename LhsMatrixType, typename RhsMatrixType>
141 {
142  ASSERTL1(lhs.GetColumns() == rhs.GetRows(),
143  std::string("A left side matrix with column count ") +
144  std::to_string(lhs.GetColumns()) +
145  std::string(" and a right side matrix with row count ") +
146  std::to_string(rhs.GetRows()) +
147  std::string(" can't be multiplied."));
148 
149  for (unsigned int i = 0; i < result.GetRows(); ++i)
150  {
151  for (unsigned int j = 0; j < result.GetColumns(); ++j)
152  {
153  ResultType t = ResultType(0);
154 
155  // Set the result(i,j) element.
156  for (unsigned int k = 0; k < lhs.GetColumns(); ++k)
157  {
158  t += lhs(i, k) * rhs(k, j);
159  }
160  result(i, j) = t;
161  }
162  }
163 }
164 
165 template <typename ResultType, typename LhsDataType, typename RhsDataType,
166  typename LhsMatrixType, typename RhsMatrixType>
171 {
172  NekMultiplyDefaultImpl(result, lhs, rhs);
173 }
174 
175 template <typename LhsDataType, typename RhsDataType, typename DataType,
176  typename LhsMatrixType, typename RhsMatrixType>
180 {
181  ASSERTL1(lhs.GetColumns() == rhs.GetRows(),
182  std::string("A left side matrix with column count ") +
183  std::to_string(lhs.GetColumns()) +
184  std::string(" and a right side matrix with row count ") +
185  std::to_string(rhs.GetRows()) +
186  std::string(" can't be multiplied."));
187 
188  result.SetSize(lhs.GetRows(), rhs.GetColumns());
189  if (lhs.GetType() == eFULL && rhs.GetType() == eFULL)
190  {
191  NekMultiplyFullMatrixFullMatrix(result, lhs, rhs);
192  }
193  else
194  {
195  NekMultiplyDefaultImpl(result, lhs, rhs);
196  }
197 }
198 
201  (1, (DNekMat &)), (0, ()))
204  (1, (void)), (1, (SNekMat &)), (0, ()))
205 
206 template <typename DataType, typename RhsDataType, typename RhsMatrixType>
207 void AddEqual(NekMatrix<DataType, StandardMatrixTag> &result,
208  const NekMatrix<RhsDataType, RhsMatrixType> &rhs)
209 {
210  ASSERTL1(result.GetRows() == rhs.GetRows(),
211  std::string("Matrices with different row counts ") +
212  std::to_string(result.GetRows()) + std::string(" and ") +
213  std::to_string(rhs.GetRows()) +
214  std::string(" can't be added."));
215  ASSERTL1(result.GetColumns() == rhs.GetColumns(),
216  std::string("Matrices with different column counts ") +
217  std::to_string(result.GetColumns()) + std::string(" and ") +
218  std::to_string(rhs.GetColumns()) +
219  std::string(" can't be added."));
220 
221  for (unsigned int i = 0; i < rhs.GetRows(); ++i)
222  {
223  for (unsigned int j = 0; j < rhs.GetColumns(); ++j)
224  {
225  result(i, j) += rhs(i, j);
226  }
227  }
228 }
229 
230 template <typename DataType, typename RhsDataType, typename RhsMatrixType>
233 {
234  ASSERTL1(result.GetRows() == rhs.GetRows(),
235  std::string("Matrices with different row counts ") +
236  std::to_string(result.GetRows()) + std::string(" and ") +
237  std::to_string(rhs.GetRows()) +
238  std::string(" can't be added."));
239  ASSERTL1(result.GetColumns() == rhs.GetColumns(),
240  std::string("Matrices with different column counts ") +
241  std::to_string(result.GetColumns()) + std::string(" and ") +
242  std::to_string(rhs.GetColumns()) +
243  std::string(" can't be added."));
244 
245  for (unsigned int i = 0; i < rhs.GetRows(); ++i)
246  {
247  for (unsigned int j = 0; j < rhs.GetColumns(); ++j)
248  {
249  result(i, j) = -result(i, j) + rhs(i, j);
250  }
251  }
252 }
253 
255  AddEqual, NEKTAR_ALL_MATRIX_TYPES, (1, (void)), (1, (DNekMat &)), (0, ()))
257  AddEqual, NEKTAR_ALL_MATRIX_TYPES_SINGLE, (1, (void)), (1, (SNekMat &)),
258  (0, ()))
260  AddEqualNegatedLhs, NEKTAR_ALL_MATRIX_TYPES, (1, (void)), (1, (DNekMat &)),
261  (0, ()))
264  (1, (SNekMat &)), (0, ()))
265 
266 template <typename DataType, typename LhsDataType, typename LhsMatrixType,
267  typename RhsDataType, typename RhsMatrixType>
268 void Add(NekMatrix<DataType, StandardMatrixTag> &result,
269  const NekMatrix<LhsDataType, LhsMatrixType> &lhs,
270  const NekMatrix<RhsDataType, RhsMatrixType> &rhs)
271 {
272  ASSERTL1(lhs.GetRows() == rhs.GetRows(),
273  std::string("Matrices with different row counts ") +
274  std::to_string(lhs.GetRows()) + std::string(" and ") +
275  std::to_string(rhs.GetRows()) +
276  std::string(" can't be added."));
277  ASSERTL1(lhs.GetColumns() == rhs.GetColumns(),
278  std::string("Matrices with different column counts ") +
279  std::to_string(lhs.GetColumns()) + std::string(" and ") +
280  std::to_string(rhs.GetColumns()) +
281  std::string(" can't be added."));
282 
283  for (unsigned int i = 0; i < lhs.GetRows(); ++i)
284  {
285  for (unsigned int j = 0; j < lhs.GetColumns(); ++j)
286  {
287  result(i, j) = lhs(i, j) + rhs(i, j);
288  }
289  }
290 }
291 
292 template <typename DataType, typename LhsDataType, typename LhsMatrixType,
293  typename RhsDataType, typename RhsMatrixType>
297 {
298  ASSERTL1(lhs.GetRows() == rhs.GetRows(),
299  std::string("Matrices with different row counts ") +
300  std::to_string(lhs.GetRows()) + std::string(" and ") +
301  std::to_string(rhs.GetRows()) +
302  std::string(" can't be added."));
303  ASSERTL1(lhs.GetColumns() == rhs.GetColumns(),
304  std::string("Matrices with different column counts ") +
305  std::to_string(lhs.GetColumns()) + std::string(" and ") +
306  std::to_string(rhs.GetColumns()) +
307  std::string(" can't be added."));
308 
309  for (unsigned int i = 0; i < lhs.GetRows(); ++i)
310  {
311  for (unsigned int j = 0; j < lhs.GetColumns(); ++j)
312  {
313  result(i, j) = -lhs(i, j) + rhs(i, j);
314  }
315  }
316 }
317 
320  (1, (DNekMat &)), (0, ()))
323  (1, (void)), (1, (SNekMat &)), (0, ()))
326  (1, (void)), (1, (DNekMat &)), (0, ()))
329  NEKTAR_ALL_MATRIX_TYPES_SINGLE, (1, (void)), (1, (SNekMat &)), (0, ()))
330 
331 template <typename LhsDataType, typename LhsMatrixType, typename RhsDataType,
332  typename RhsMatrixType>
333 NekMatrix<typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType,
334  StandardMatrixTag>
335 Add(const NekMatrix<LhsDataType, LhsMatrixType> &lhs,
336  const NekMatrix<RhsDataType, RhsMatrixType> &rhs)
337 {
338  typedef
340  NekMatrix<NumberType, StandardMatrixTag> result(lhs.GetRows(),
341  lhs.GetColumns());
342  Add(result, lhs, rhs);
343  return result;
344 }
345 
348  (0, ()), (0, ()))
351  (1, (SNekMat)), (0, ()), (0, ()))
352 
353 template <typename DataType, typename LhsDataType, typename LhsMatrixType,
354  typename RhsDataType, typename RhsMatrixType>
355 void Subtract(NekMatrix<DataType, StandardMatrixTag> &result,
356  const NekMatrix<LhsDataType, LhsMatrixType> &lhs,
357  const NekMatrix<RhsDataType, RhsMatrixType> &rhs)
358 {
359  ASSERTL1(lhs.GetRows() == rhs.GetRows(),
360  std::string("Matrices with different row counts ") +
361  std::to_string(lhs.GetRows()) + std::string(" and ") +
362  std::to_string(rhs.GetRows()) +
363  std::string(" can't be subtracted."));
364  ASSERTL1(lhs.GetColumns() == rhs.GetColumns(),
365  std::string("Matrices with different column counts ") +
366  std::to_string(lhs.GetColumns()) + std::string(" and ") +
367  std::to_string(rhs.GetColumns()) +
368  std::string(" can't be subtracted."));
369 
370  for (unsigned int i = 0; i < lhs.GetRows(); ++i)
371  {
372  for (unsigned int j = 0; j < lhs.GetColumns(); ++j)
373  {
374  result(i, j) = lhs(i, j) - rhs(i, j);
375  }
376  }
377 }
378 
379 template <typename DataType, typename LhsDataType, typename LhsMatrixType,
380  typename RhsDataType, typename RhsMatrixType>
384 {
385  ASSERTL1(lhs.GetRows() == rhs.GetRows(),
386  std::string("Matrices with different row counts ") +
387  std::to_string(lhs.GetRows()) + std::string(" and ") +
388  std::to_string(rhs.GetRows()) +
389  std::string(" can't be subtracted."));
390  ASSERTL1(lhs.GetColumns() == rhs.GetColumns(),
391  std::string("Matrices with different column counts ") +
392  std::to_string(lhs.GetColumns()) + std::string(" and ") +
393  std::to_string(rhs.GetColumns()) +
394  std::string(" can't be subtracted."));
395 
396  for (unsigned int i = 0; i < lhs.GetRows(); ++i)
397  {
398  for (unsigned int j = 0; j < lhs.GetColumns(); ++j)
399  {
400  result(i, j) = -lhs(i, j) - rhs(i, j);
401  }
402  }
403 }
404 
407  (1, (DNekMat &)), (0, ()))
410  (1, (void)), (1, (SNekMat &)), (0, ()))
413  (1, (void)), (1, (DNekMat &)), (0, ()))
416  NEKTAR_ALL_MATRIX_TYPES_SINGLE, (1, (void)), (1, (SNekMat &)), (0, ()))
417 
418 template <typename DataType, typename RhsDataType, typename RhsMatrixType>
419 void SubtractEqual(NekMatrix<DataType, StandardMatrixTag> &result,
420  const NekMatrix<RhsDataType, RhsMatrixType> &rhs)
421 {
422  ASSERTL1(result.GetRows() == rhs.GetRows(),
423  std::string("Matrices with different row counts ") +
424  std::to_string(result.GetRows()) + std::string(" and ") +
425  std::to_string(rhs.GetRows()) +
426  std::string(" can't be subtracted."));
427  ASSERTL1(result.GetColumns() == rhs.GetColumns(),
428  std::string("Matrices with different column counts ") +
429  std::to_string(result.GetColumns()) + std::string(" and ") +
430  std::to_string(rhs.GetColumns()) +
431  std::string(" can't be subtracted."));
432 
433  for (unsigned int i = 0; i < rhs.GetRows(); ++i)
434  {
435  for (unsigned int j = 0; j < rhs.GetColumns(); ++j)
436  {
437  result(i, j) -= rhs(i, j);
438  }
439  }
440 }
441 
442 template <typename DataType, typename RhsDataType, typename RhsMatrixType>
445 {
446  ASSERTL1(result.GetRows() == rhs.GetRows(),
447  std::string("Matrices with different row counts ") +
448  std::to_string(result.GetRows()) + std::string(" and ") +
449  std::to_string(rhs.GetRows()) +
450  std::string(" can't be subtracted."));
451  ASSERTL1(result.GetColumns() == rhs.GetColumns(),
452  std::string("Matrices with different column counts ") +
453  std::to_string(result.GetColumns()) + std::string(" and ") +
454  std::to_string(rhs.GetColumns()) +
455  std::string(" can't be subtracted."));
456 
457  for (unsigned int i = 0; i < rhs.GetRows(); ++i)
458  {
459  for (unsigned int j = 0; j < rhs.GetColumns(); ++j)
460  {
461  result(i, j) = -result(i, j) - rhs(i, j);
462  }
463  }
464 }
465 
467  SubtractEqual, NEKTAR_ALL_MATRIX_TYPES, (1, (void)), (1, (DNekMat &)),
468  (0, ()))
471  (1, (SNekMat &)), (0, ()))
474  (1, (DNekMat &)), (0, ()))
477  (1, (SNekMat &)), (0, ()))
478 
479 template <typename LhsDataType, typename LhsMatrixType, typename RhsDataType,
480  typename RhsMatrixType>
481 NekMatrix<typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType,
482  StandardMatrixTag>
483 Subtract(const NekMatrix<LhsDataType, LhsMatrixType> &lhs,
484  const NekMatrix<RhsDataType, RhsMatrixType> &rhs)
485 {
486  typedef
488  NekMatrix<NumberType, StandardMatrixTag> result(lhs.GetRows(),
489  lhs.GetColumns());
490  Subtract(result, lhs, rhs);
491  return result;
492 }
493 
496  (0, ()), (0, ()))
499  (1, (SNekMat)), (0, ()), (0, ()))
500 } // namespace Nektar
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:249
#define NEKTAR_ALL_MATRIX_TYPES
unsigned int GetRows() const
Definition: MatrixBase.cpp:65
unsigned int GetColumns() const
Definition: MatrixBase.cpp:84
void SetSize(unsigned int rows, unsigned int cols)
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
SNekMat SNekMat void SubtractEqual(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
SNekMat NEKTAR_GENERATE_EXPLICIT_FUNCTION_INSTANTIATION_SINGLE_MATRIX(AddEqualNegatedLhs, NEKTAR_ALL_MATRIX_TYPES,(1,(void)),(1,(DNekMat &)),(0,())) NEKTAR_GENERATE_EXPLICIT_FUNCTION_INSTANTIATION_SINGLE_MATRIX(AddEqualNegatedLhs
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)
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)
NEKTAR_ALL_MATRIX_TYPES_SINGLE
SNekMat const NekSingle &void NekMultiplyDefaultImpl(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 SubtractEqualNegatedLhs(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
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)
SNekMat NEKTAR_GENERATE_EXPLICIT_FUNCTION_INSTANTIATION_TWO_MATRICES(AddNegatedLhs, NEKTAR_ALL_MATRIX_TYPES, NEKTAR_ALL_MATRIX_TYPES,(1,(void)),(1,(DNekMat &)),(0,())) NEKTAR_GENERATE_EXPLICIT_FUNCTION_INSTANTIATION_TWO_MATRICES(AddNegatedLhs
double NekDouble
SNekMat SNekMat void Add(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)