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 
59  NEKTAR_ALL_MATRIX_TYPES_SINGLE, (1, (void)), (1, (SNekMat&)), (1,
60  (const NekSingle&)))
61 
62  template<typename DataType, typename LhsDataType, typename LhsMatrixType>
65  const DataType& rhs)
66  {
67  typedef typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType ResultDataType;
68  NekMatrix<ResultDataType, StandardMatrixTag> result(lhs.GetRows(), lhs.GetColumns());
69  Multiply(result, lhs, rhs);
70  return result;
71  }
72 
75  NEKTAR_ALL_MATRIX_TYPES_SINGLE, (1, (SNekMat)), (0, ()), (1,
76  (const NekSingle&)))
77 
78  template<typename RhsDataType, typename RhsMatrixType, typename ResultDataType>
80  const ResultDataType& lhs,
82 
83  {
84  Multiply(result, rhs, lhs);
85  }
86 
89  NEKTAR_ALL_MATRIX_TYPES_SINGLE, (1, (void)), (2, (SNekMat&,
90  const NekSingle&)), (0, ()))
91 
92  template<typename DataType, typename RhsDataType, typename RhsMatrixType>
93  NekMatrix<typename NekMatrix<RhsDataType, RhsMatrixType>::NumberType, StandardMatrixTag>
94  Multiply(const DataType& lhs,
95  const NekMatrix<RhsDataType, RhsMatrixType>& rhs)
96 
97  {
98  return Multiply(rhs, lhs);
99  }
100 
104  (1, (const NekSingle&)), (0, ()))
105 
106  template<typename LhsDataType>
107  void MultiplyEqual(NekMatrix<LhsDataType, StandardMatrixTag>& lhs,
108  typename boost::call_traits<LhsDataType>::const_reference rhs)
109  {
110  typedef typename NekMatrix<LhsDataType, StandardMatrixTag>::iterator iterator;
111  for( iterator iter = lhs.begin(); iter != lhs.end(); ++iter)
112  {
113  *iter *= rhs;
114  }
115  }
116 
119  (1, (SNekMat&)), (1, (void)), (0, ()), (1, (const NekSingle&)))
120 
121  template<typename ResultType, typename LhsDataType, typename RhsDataType,
122  typename LhsMatrixType, typename RhsMatrixType>
126  {
127  ASSERTL1(lhs.GetColumns() == rhs.GetRows(), std::string("A left side matrix with column count ") +
128  std::to_string(lhs.GetColumns()) +
129  std::string(" and a right side matrix with row count ") +
130  std::to_string(rhs.GetRows()) + std::string(" can't be multiplied."));
131 
132  for(unsigned int i = 0; i < result.GetRows(); ++i)
133  {
134  for(unsigned int j = 0; j < result.GetColumns(); ++j)
135  {
136  ResultType t = ResultType(0);
137 
138  // Set the result(i,j) element.
139  for(unsigned int k = 0; k < lhs.GetColumns(); ++k)
140  {
141  t += lhs(i,k)*rhs(k,j);
142  }
143  result(i,j) = t;
144  }
145  }
146  }
147 
148  template<typename ResultType, typename LhsDataType, typename RhsDataType,
149  typename LhsMatrixType, typename RhsMatrixType>
153  {
154  NekMultiplyDefaultImpl(result, lhs, rhs);
155  }
156 
157  template<typename LhsDataType, typename RhsDataType, typename DataType,
158  typename LhsMatrixType, typename RhsMatrixType>
162  {
163  ASSERTL1(lhs.GetColumns() == rhs.GetRows(), std::string("A left side matrix with column count ") +
164  std::to_string(lhs.GetColumns()) +
165  std::string(" and a right side matrix with row count ") +
166  std::to_string(rhs.GetRows()) + std::string(" can't be multiplied."));
167 
168  result.SetSize(lhs.GetRows(), rhs.GetColumns());
169  if( lhs.GetType() == eFULL && rhs.GetType() == eFULL)
170  {
171  NekMultiplyFullMatrixFullMatrix(result, lhs, rhs);
172  }
173  else
174  {
175  NekMultiplyDefaultImpl(result, lhs, rhs);
176  }
177  }
178 
182  (1, (void)), (1, (SNekMat&)), (0, ()))
183 
184  template<typename DataType, typename RhsDataType, typename RhsMatrixType>
185  void AddEqual(NekMatrix<DataType, StandardMatrixTag>& result,
186  const NekMatrix<RhsDataType, RhsMatrixType>& rhs)
187  {
188  ASSERTL1(result.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts ") +
189  std::to_string(result.GetRows()) + std::string(" and ") +
190  std::to_string(rhs.GetRows()) + std::string(" can't be added."));
191  ASSERTL1(result.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts ") +
192  std::to_string(result.GetColumns()) + std::string(" and ") +
193  std::to_string(rhs.GetColumns()) + std::string(" can't be added."));
194 
195  for(unsigned int i = 0; i < rhs.GetRows(); ++i)
196  {
197  for(unsigned int j = 0; j < rhs.GetColumns(); ++j)
198  {
199  result(i,j) += rhs(i,j);
200  }
201  }
202  }
203 
204 
205  template<typename DataType, typename RhsDataType, typename RhsMatrixType>
208  {
209  ASSERTL1(result.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts ") +
210  std::to_string(result.GetRows()) + std::string(" and ") +
211  std::to_string(rhs.GetRows()) + std::string(" can't be added."));
212  ASSERTL1(result.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts ") +
213  std::to_string(result.GetColumns()) + std::string(" and ") +
214  std::to_string(rhs.GetColumns()) + std::string(" can't be added."));
215 
216  for(unsigned int i = 0; i < rhs.GetRows(); ++i)
217  {
218  for(unsigned int j = 0; j < rhs.GetColumns(); ++j)
219  {
220  result(i,j) = -result(i,j) + rhs(i,j);
221  }
222  }
223  }
224 
227  NEKTAR_ALL_MATRIX_TYPES_SINGLE, (1, (void)), (1, (SNekMat&)), (0, ()))
231  (1, (SNekMat&)), (0, ()))
232 
233 
234  template<typename DataType, typename LhsDataType, typename LhsMatrixType, typename RhsDataType, typename RhsMatrixType>
235  void Add(NekMatrix<DataType, StandardMatrixTag>& result,
236  const NekMatrix<LhsDataType, LhsMatrixType>& lhs,
237  const NekMatrix<RhsDataType, RhsMatrixType>& rhs)
238  {
239  ASSERTL1(lhs.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts ") +
240  std::to_string(lhs.GetRows()) + std::string(" and ") +
241  std::to_string(rhs.GetRows()) + std::string(" can't be added."));
242  ASSERTL1(lhs.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts ") +
243  std::to_string(lhs.GetColumns()) + std::string(" and ") +
244  std::to_string(rhs.GetColumns()) + std::string(" can't be added."));
245 
246  for(unsigned int i = 0; i < lhs.GetRows(); ++i)
247  {
248  for(unsigned int j = 0; j < lhs.GetColumns(); ++j)
249  {
250  result(i,j) = lhs(i,j) + rhs(i,j);
251  }
252  }
253  }
254 
255  template<typename DataType, typename LhsDataType, typename LhsMatrixType, typename RhsDataType, typename RhsMatrixType>
259  {
260  ASSERTL1(lhs.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts ") +
261  std::to_string(lhs.GetRows()) + std::string(" and ") +
262  std::to_string(rhs.GetRows()) + std::string(" can't be added."));
263  ASSERTL1(lhs.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts ") +
264  std::to_string(lhs.GetColumns()) + std::string(" and ") +
265  std::to_string(rhs.GetColumns()) + std::string(" can't be added."));
266 
267  for(unsigned int i = 0; i < lhs.GetRows(); ++i)
268  {
269  for(unsigned int j = 0; j < lhs.GetColumns(); ++j)
270  {
271  result(i,j) = -lhs(i,j) + rhs(i,j);
272  }
273  }
274  }
275 
279  (1, (void)), (1, (SNekMat&)), (0, ()))
283  (1, (void)), (1, (SNekMat&)), (0, ()))
284 
285 
286  template<typename LhsDataType, typename LhsMatrixType, typename RhsDataType, typename RhsMatrixType>
287  NekMatrix<typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType, StandardMatrixTag>
288  Add(const NekMatrix<LhsDataType, LhsMatrixType>& lhs,
289  const NekMatrix<RhsDataType, RhsMatrixType>& rhs)
290  {
291  typedef typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType NumberType;
292  NekMatrix<NumberType, StandardMatrixTag> result(lhs.GetRows(), lhs.GetColumns());
293  Add(result, lhs, rhs);
294  return result;
295  }
296 
300  (1, (SNekMat)), (0, ()), (0, ()))
301 
302  template<typename DataType, typename LhsDataType, typename LhsMatrixType, typename RhsDataType, typename RhsMatrixType>
303  void Subtract(NekMatrix<DataType, StandardMatrixTag>& result,
304  const NekMatrix<LhsDataType, LhsMatrixType>& lhs,
305  const NekMatrix<RhsDataType, RhsMatrixType>& rhs)
306  {
307  ASSERTL1(lhs.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts ") +
308  std::to_string(lhs.GetRows()) + std::string(" and ") +
309  std::to_string(rhs.GetRows()) + std::string(" can't be subtracted."));
310  ASSERTL1(lhs.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts ") +
311  std::to_string(lhs.GetColumns()) + std::string(" and ") +
312  std::to_string(rhs.GetColumns()) + std::string(" can't be subtracted."));
313 
314  for(unsigned int i = 0; i < lhs.GetRows(); ++i)
315  {
316  for(unsigned int j = 0; j < lhs.GetColumns(); ++j)
317  {
318  result(i,j) = lhs(i,j) - rhs(i,j);
319  }
320  }
321  }
322 
323  template<typename DataType, typename LhsDataType, typename LhsMatrixType, typename RhsDataType, typename RhsMatrixType>
327  {
328  ASSERTL1(lhs.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts ") +
329  std::to_string(lhs.GetRows()) + std::string(" and ") +
330  std::to_string(rhs.GetRows()) + std::string(" can't be subtracted."));
331  ASSERTL1(lhs.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts ") +
332  std::to_string(lhs.GetColumns()) + std::string(" and ") +
333  std::to_string(rhs.GetColumns()) + std::string(" can't be subtracted."));
334 
335  for(unsigned int i = 0; i < lhs.GetRows(); ++i)
336  {
337  for(unsigned int j = 0; j < lhs.GetColumns(); ++j)
338  {
339  result(i,j) = -lhs(i,j) - rhs(i,j);
340  }
341  }
342  }
343 
347  (1, (void)), (1, (SNekMat&)), (0, ()))
351  NEKTAR_ALL_MATRIX_TYPES_SINGLE, (1, (void)), (1, (SNekMat&)), (0, ()))
352 
353 
354 
355  template<typename DataType, typename RhsDataType, typename RhsMatrixType>
356  void SubtractEqual(NekMatrix<DataType, StandardMatrixTag>& result,
357  const NekMatrix<RhsDataType, RhsMatrixType>& rhs)
358  {
359  ASSERTL1(result.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts ") +
360  std::to_string(result.GetRows()) + std::string(" and ") +
361  std::to_string(rhs.GetRows()) + std::string(" can't be subtracted."));
362  ASSERTL1(result.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts ") +
363  std::to_string(result.GetColumns()) + std::string(" and ") +
364  std::to_string(rhs.GetColumns()) + std::string(" can't be subtracted."));
365 
366  for(unsigned int i = 0; i < rhs.GetRows(); ++i)
367  {
368  for(unsigned int j = 0; j < rhs.GetColumns(); ++j)
369  {
370  result(i,j) -= rhs(i,j);
371  }
372  }
373  }
374 
375  template<typename DataType, typename RhsDataType, typename RhsMatrixType>
378  {
379  ASSERTL1(result.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts ") +
380  std::to_string(result.GetRows()) + std::string(" and ") +
381  std::to_string(rhs.GetRows()) + std::string(" can't be subtracted."));
382  ASSERTL1(result.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts ") +
383  std::to_string(result.GetColumns()) + std::string(" and ") +
384  std::to_string(rhs.GetColumns()) + std::string(" can't be subtracted."));
385 
386  for(unsigned int i = 0; i < rhs.GetRows(); ++i)
387  {
388  for(unsigned int j = 0; j < rhs.GetColumns(); ++j)
389  {
390  result(i,j) = -result(i,j) - rhs(i,j);
391  }
392  }
393  }
394 
397  NEKTAR_ALL_MATRIX_TYPES_SINGLE, (1, (void)), (1, (SNekMat&)), (0, ()))
401  (1, (void)), (1, (SNekMat&)), (0, ()))
402 
403  template<typename LhsDataType, typename LhsMatrixType, typename RhsDataType, typename RhsMatrixType>
404  NekMatrix<typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType, StandardMatrixTag>
405  Subtract(const NekMatrix<LhsDataType, LhsMatrixType>& lhs,
406  const NekMatrix<RhsDataType, RhsMatrixType>& rhs)
407  {
408  typedef typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType NumberType;
409  NekMatrix<NumberType, StandardMatrixTag> result(lhs.GetRows(), lhs.GetColumns());
410  Subtract(result, lhs, rhs);
411  return result;
412  }
413 
417  (1, (SNekMat)), (0, ()), (0, ()))
418 }
419 
420 
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:250
#define NEKTAR_ALL_MATRIX_TYPES
unsigned int GetRows() const
Definition: MatrixBase.cpp:58
unsigned int GetColumns() const
Definition: MatrixBase.cpp:77
void SetSize(unsigned int rows, unsigned int cols)
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)
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)