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 
59  template<typename DataType, typename LhsDataType, typename LhsMatrixType>
60  NekMatrix<typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType, StandardMatrixTag>
61  Multiply(const NekMatrix<LhsDataType, LhsMatrixType>& lhs,
62  const DataType& rhs)
63  {
64  typedef typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType ResultDataType;
65  NekMatrix<ResultDataType, StandardMatrixTag> result(lhs.GetRows(), lhs.GetColumns());
66  Multiply(result, lhs, rhs);
67  return result;
68  }
69 
71 
72  template<typename RhsDataType, typename RhsMatrixType, typename ResultDataType>
73  void Multiply(NekMatrix<ResultDataType, StandardMatrixTag>& result,
74  const ResultDataType& lhs,
76 
77  {
78  Multiply(result, rhs, lhs);
79  }
80 
82 
83  template<typename DataType, typename RhsDataType, typename RhsMatrixType>
84  NekMatrix<typename NekMatrix<RhsDataType, RhsMatrixType>::NumberType, StandardMatrixTag>
85  Multiply(const DataType& lhs,
87 
88  {
89  return Multiply(rhs, lhs);
90  }
91 
93 
94  template<typename LhsDataType>
96  typename boost::call_traits<LhsDataType>::const_reference rhs)
97  {
99  for( iterator iter = lhs.begin(); iter != lhs.end(); ++iter)
100  {
101  *iter *= rhs;
102  }
103  }
104 
106 
107  template<typename ResultType, typename LhsDataType, typename RhsDataType,
108  typename LhsMatrixType, typename RhsMatrixType>
109  void NekMultiplyDefaultImpl(NekMatrix<ResultType, StandardMatrixTag>& result,
110  const NekMatrix<LhsDataType, LhsMatrixType>& lhs,
111  const NekMatrix<RhsDataType, RhsMatrixType>& rhs)
112  {
113  ASSERTL1(lhs.GetColumns() == rhs.GetRows(), std::string("A left side matrix with column count ") +
114  std::to_string(lhs.GetColumns()) +
115  std::string(" and a right side matrix with row count ") +
116  std::to_string(rhs.GetRows()) + std::string(" can't be multiplied."));
117 
118  for(unsigned int i = 0; i < result.GetRows(); ++i)
119  {
120  for(unsigned int j = 0; j < result.GetColumns(); ++j)
121  {
122  ResultType t = ResultType(0);
123 
124  // Set the result(i,j) element.
125  for(unsigned int k = 0; k < lhs.GetColumns(); ++k)
126  {
127  t += lhs(i,k)*rhs(k,j);
128  }
129  result(i,j) = t;
130  }
131  }
132  }
133 
134  template<typename ResultType, typename LhsDataType, typename RhsDataType,
135  typename LhsMatrixType, typename RhsMatrixType>
139  {
140  NekMultiplyDefaultImpl(result, lhs, rhs);
141  }
142 
143  template<typename LhsDataType, typename RhsDataType, typename DataType,
144  typename LhsMatrixType, typename RhsMatrixType>
148  {
149  ASSERTL1(lhs.GetColumns() == rhs.GetRows(), std::string("A left side matrix with column count ") +
150  std::to_string(lhs.GetColumns()) +
151  std::string(" and a right side matrix with row count ") +
152  std::to_string(rhs.GetRows()) + std::string(" can't be multiplied."));
153 
154  result.SetSize(lhs.GetRows(), rhs.GetColumns());
155  if( lhs.GetType() == eFULL && rhs.GetType() == eFULL)
156  {
157  NekMultiplyFullMatrixFullMatrix(result, lhs, rhs);
158  }
159  else
160  {
161  NekMultiplyDefaultImpl(result, lhs, rhs);
162  }
163  }
164 
166 
167  template<typename DataType, typename RhsDataType, typename RhsMatrixType>
170  {
171  ASSERTL1(result.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts ") +
172  std::to_string(result.GetRows()) + std::string(" and ") +
173  std::to_string(rhs.GetRows()) + std::string(" can't be added."));
174  ASSERTL1(result.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts ") +
175  std::to_string(result.GetColumns()) + std::string(" and ") +
176  std::to_string(rhs.GetColumns()) + std::string(" can't be added."));
177 
178  for(unsigned int i = 0; i < rhs.GetRows(); ++i)
179  {
180  for(unsigned int j = 0; j < rhs.GetColumns(); ++j)
181  {
182  result(i,j) += rhs(i,j);
183  }
184  }
185  }
186 
187 
188  template<typename DataType, typename RhsDataType, typename RhsMatrixType>
191  {
192  ASSERTL1(result.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts ") +
193  std::to_string(result.GetRows()) + std::string(" and ") +
194  std::to_string(rhs.GetRows()) + std::string(" can't be added."));
195  ASSERTL1(result.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts ") +
196  std::to_string(result.GetColumns()) + std::string(" and ") +
197  std::to_string(rhs.GetColumns()) + std::string(" can't be added."));
198 
199  for(unsigned int i = 0; i < rhs.GetRows(); ++i)
200  {
201  for(unsigned int j = 0; j < rhs.GetColumns(); ++j)
202  {
203  result(i,j) = -result(i,j) + rhs(i,j);
204  }
205  }
206  }
207 
210 
211 
212  template<typename DataType, typename LhsDataType, typename LhsMatrixType, typename RhsDataType, typename RhsMatrixType>
213  void Add(NekMatrix<DataType, StandardMatrixTag>& result,
214  const NekMatrix<LhsDataType, LhsMatrixType>& lhs,
215  const NekMatrix<RhsDataType, RhsMatrixType>& rhs)
216  {
217  ASSERTL1(lhs.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts ") +
218  std::to_string(lhs.GetRows()) + std::string(" and ") +
219  std::to_string(rhs.GetRows()) + std::string(" can't be added."));
220  ASSERTL1(lhs.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts ") +
221  std::to_string(lhs.GetColumns()) + std::string(" and ") +
222  std::to_string(rhs.GetColumns()) + std::string(" can't be added."));
223 
224  for(unsigned int i = 0; i < lhs.GetRows(); ++i)
225  {
226  for(unsigned int j = 0; j < lhs.GetColumns(); ++j)
227  {
228  result(i,j) = lhs(i,j) + rhs(i,j);
229  }
230  }
231  }
232 
233  template<typename DataType, typename LhsDataType, typename LhsMatrixType, typename RhsDataType, typename RhsMatrixType>
237  {
238  ASSERTL1(lhs.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts ") +
239  std::to_string(lhs.GetRows()) + std::string(" and ") +
240  std::to_string(rhs.GetRows()) + std::string(" can't be added."));
241  ASSERTL1(lhs.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts ") +
242  std::to_string(lhs.GetColumns()) + std::string(" and ") +
243  std::to_string(rhs.GetColumns()) + std::string(" can't be added."));
244 
245  for(unsigned int i = 0; i < lhs.GetRows(); ++i)
246  {
247  for(unsigned int j = 0; j < lhs.GetColumns(); ++j)
248  {
249  result(i,j) = -lhs(i,j) + rhs(i,j);
250  }
251  }
252  }
253 
256 
257 
258  template<typename LhsDataType, typename LhsMatrixType, typename RhsDataType, typename RhsMatrixType>
262  {
263  typedef typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType NumberType;
264  NekMatrix<NumberType, StandardMatrixTag> result(lhs.GetRows(), lhs.GetColumns());
265  Add(result, lhs, rhs);
266  return result;
267  }
268 
270 
271  template<typename DataType, typename LhsDataType, typename LhsMatrixType, typename RhsDataType, typename RhsMatrixType>
275  {
276  ASSERTL1(lhs.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts ") +
277  std::to_string(lhs.GetRows()) + std::string(" and ") +
278  std::to_string(rhs.GetRows()) + std::string(" can't be subtracted."));
279  ASSERTL1(lhs.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts ") +
280  std::to_string(lhs.GetColumns()) + std::string(" and ") +
281  std::to_string(rhs.GetColumns()) + std::string(" can't be subtracted."));
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, typename RhsDataType, typename RhsMatrixType>
296  {
297  ASSERTL1(lhs.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts ") +
298  std::to_string(lhs.GetRows()) + std::string(" and ") +
299  std::to_string(rhs.GetRows()) + std::string(" can't be subtracted."));
300  ASSERTL1(lhs.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts ") +
301  std::to_string(lhs.GetColumns()) + std::string(" and ") +
302  std::to_string(rhs.GetColumns()) + std::string(" can't be subtracted."));
303 
304  for(unsigned int i = 0; i < lhs.GetRows(); ++i)
305  {
306  for(unsigned int j = 0; j < lhs.GetColumns(); ++j)
307  {
308  result(i,j) = -lhs(i,j) - rhs(i,j);
309  }
310  }
311  }
312 
315 
316 
317 
318  template<typename DataType, typename RhsDataType, typename RhsMatrixType>
321  {
322  ASSERTL1(result.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts ") +
323  std::to_string(result.GetRows()) + std::string(" and ") +
324  std::to_string(rhs.GetRows()) + std::string(" can't be subtracted."));
325  ASSERTL1(result.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts ") +
326  std::to_string(result.GetColumns()) + std::string(" and ") +
327  std::to_string(rhs.GetColumns()) + std::string(" can't be subtracted."));
328 
329  for(unsigned int i = 0; i < rhs.GetRows(); ++i)
330  {
331  for(unsigned int j = 0; j < rhs.GetColumns(); ++j)
332  {
333  result(i,j) -= rhs(i,j);
334  }
335  }
336  }
337 
338  template<typename DataType, typename RhsDataType, typename RhsMatrixType>
341  {
342  ASSERTL1(result.GetRows() == rhs.GetRows(), std::string("Matrices with different row counts ") +
343  std::to_string(result.GetRows()) + std::string(" and ") +
344  std::to_string(rhs.GetRows()) + std::string(" can't be subtracted."));
345  ASSERTL1(result.GetColumns() == rhs.GetColumns(), std::string("Matrices with different column counts ") +
346  std::to_string(result.GetColumns()) + std::string(" and ") +
347  std::to_string(rhs.GetColumns()) + std::string(" can't be subtracted."));
348 
349  for(unsigned int i = 0; i < rhs.GetRows(); ++i)
350  {
351  for(unsigned int j = 0; j < rhs.GetColumns(); ++j)
352  {
353  result(i,j) = -result(i,j) - rhs(i,j);
354  }
355  }
356  }
357 
360 
361  template<typename LhsDataType, typename LhsMatrixType, typename RhsDataType, typename RhsMatrixType>
365  {
366  typedef typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType NumberType;
367  NekMatrix<NumberType, StandardMatrixTag> result(lhs.GetRows(), lhs.GetColumns());
368  Subtract(result, lhs, rhs);
369  return result;
370  }
371 
373 }
374 
375 
void SubtractNegatedLhs(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
void MultiplyEqual(NekMatrix< LhsDataType, StandardMatrixTag > &lhs, typename boost::call_traits< LhsDataType >::const_reference rhs)
NEKTAR_GENERATE_EXPLICIT_FUNCTION_INSTANTIATION_TWO_MATRICES(Multiply, NEKTAR_ALL_MATRIX_TYPES, NEKTAR_ALL_MATRIX_TYPES,(1,(void)),(1,(DNekMat &)),(0,())) template< typename DataType
void NekMultiplyFullMatrixFullMatrix(NekMatrix< ResultType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
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)
void SubtractEqualNegatedLhs(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
double NekDouble
void AddNegatedLhs(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
unsigned int GetRows() const
Definition: MatrixBase.cpp:58
RhsMatrixType void NekMultiplyDefaultImpl(NekMatrix< ResultType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
void SetSize(unsigned int rows, unsigned int cols)
NEKTAR_GENERATE_EXPLICIT_FUNCTION_INSTANTIATION_SINGLE_MATRIX(Multiply, NEKTAR_ALL_MATRIX_TYPES,(1,(void)),(1,(DNekMat &)),(1,(const NekDouble &))) template< typename DataType
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