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
38namespace Nektar
39{
40template <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
64template <typename DataType, typename LhsDataType, typename LhsMatrixType>
66 StandardMatrixTag>
67Multiply(const NekMatrix<LhsDataType, LhsMatrixType> &lhs, const DataType &rhs)
68{
70 ResultDataType;
72 lhs.GetColumns());
73 Multiply(result, lhs, rhs);
74 return result;
75}
76
79 (1, (const NekDouble &)))
82 (1, (const NekSingle &)))
83
84template <typename RhsDataType, typename RhsMatrixType, typename ResultDataType>
86 const ResultDataType &lhs,
88
89{
90 Multiply(result, rhs, lhs);
91}
92
95 (2, (DNekMat &, const NekDouble &)), (0, ()))
98 (2, (SNekMat &, const NekSingle &)), (0, ()))
99
100template <typename DataType, typename RhsDataType, typename RhsMatrixType>
101NekMatrix<typename NekMatrix<RhsDataType, RhsMatrixType>::NumberType,
102 StandardMatrixTag>
103Multiply(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
116template <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
136template <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
165template <typename ResultType, typename LhsDataType, typename RhsDataType,
166 typename LhsMatrixType, typename RhsMatrixType>
171{
172 NekMultiplyDefaultImpl(result, lhs, rhs);
173}
174
175template <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
206template <typename DataType, typename RhsDataType, typename RhsMatrixType>
207void 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
230template <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
266template <typename DataType, typename LhsDataType, typename LhsMatrixType,
267 typename RhsDataType, typename RhsMatrixType>
268void 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
292template <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
331template <typename LhsDataType, typename LhsMatrixType, typename RhsDataType,
332 typename RhsMatrixType>
333NekMatrix<typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType,
334 StandardMatrixTag>
335Add(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
353template <typename DataType, typename LhsDataType, typename LhsMatrixType,
354 typename RhsDataType, typename RhsMatrixType>
355void 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
379template <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
418template <typename DataType, typename RhsDataType, typename RhsMatrixType>
419void 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
442template <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
479template <typename LhsDataType, typename LhsMatrixType, typename RhsDataType,
480 typename RhsMatrixType>
481NekMatrix<typename NekMatrix<LhsDataType, LhsMatrixType>::NumberType,
482 StandardMatrixTag>
483Subtract(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:242
#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)
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
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)
SNekMat const NekSingle &void NekMultiplyDefaultImpl(NekMatrix< ResultType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, 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)