37#include <boost/core/ignore_unused.hpp>
45template <
typename DataType,
typename LhsDataType,
typename MatrixType>
50 for (
unsigned int i = 0; i < lhs.GetRows(); ++i)
52 DataType accum = DataType(0);
53 for (
unsigned int j = 0; j < lhs.GetColumns(); ++j)
55 accum += lhs(i, j) * rhs[j];
61template <
typename DataType,
typename LhsDataType,
typename MatrixType>
66 int n = lhs.GetRows();
67 for (
unsigned int i = 0; i < n; ++i)
69 result[i] = lhs(i, i) * rhs[i];
73template <
typename DataType,
typename LhsDataType>
78 int n = lhs.GetRows();
79 const DataType *mat_ptr = lhs.GetRawPtr();
83template <
typename DataType,
typename LhsDataType,
typename MatrixType>
87 typename std::enable_if<
90 boost::ignore_unused(
p);
92 int m = lhs.GetRows();
93 int n = lhs.GetColumns();
94 int kl = lhs.GetNumberOfSubDiagonals();
95 int ku = lhs.GetNumberOfSuperDiagonals();
96 DataType alpha = lhs.Scale();
97 const DataType *a = lhs.GetRawPtr();
98 int lda = kl + ku + 1;
99 const DataType *x = rhs;
102 DataType *y = result;
104 Blas::Gbmv(
'N', m, n, kl, ku, alpha, a, lda, x, incx,
beta, y, incy);
107template <
typename DataType,
typename LhsDataType>
111 typename std::enable_if<
115 boost::ignore_unused(result, lhs, rhs,
p);
118 "Banded block matrix multiplication not yet implemented");
121template <
typename DataType,
typename LhsInnerMatrixType>
127 unsigned int numberOfBlockRows = lhs.GetNumberOfBlockRows();
128 unsigned int numberOfBlockColumns = lhs.GetNumberOfBlockColumns();
129 DataType *result_ptr = result.
GetRawPtr();
130 const DataType *rhs_ptr = rhs.
GetRawPtr();
132 for (
unsigned int i = 0; i < result.
GetDimension(); ++i)
134 result_ptr[i] = DataType(0);
137 DataType *temp_ptr = temp.
get();
139 unsigned int curResultRow = 0;
140 for (
unsigned int blockRow = 0; blockRow < numberOfBlockRows; ++blockRow)
142 unsigned int rowsInBlock = lhs.GetNumberOfRowsInBlockRow(blockRow);
146 curResultRow += lhs.GetNumberOfRowsInBlockRow(blockRow - 1);
149 if (rowsInBlock == 0)
154 DataType *resultWrapper = result_ptr + curResultRow;
156 unsigned int curWrapperRow = 0;
157 for (
unsigned int blockColumn = 0; blockColumn < numberOfBlockColumns;
160 if (blockColumn != 0)
163 lhs.GetNumberOfColumnsInBlockColumn(blockColumn - 1);
166 const LhsInnerMatrixType *block =
167 lhs.GetBlockPtr(blockRow, blockColumn);
173 unsigned int columnsInBlock =
174 lhs.GetNumberOfColumnsInBlockColumn(blockColumn);
175 if (columnsInBlock == 0)
180 const DataType *rhsWrapper = rhs_ptr + curWrapperRow;
181 Multiply(temp_ptr, *block, rhsWrapper);
182 for (
unsigned int i = 0; i < rowsInBlock; ++i)
184 resultWrapper[i] += temp_ptr[i];
190template <
typename DataType,
typename LhsInnerMatrixType>
196 unsigned int numberOfBlockRows = lhs.GetNumberOfBlockRows();
197 DataType *result_ptr = result.
GetRawPtr();
198 const DataType *rhs_ptr = rhs.
GetRawPtr();
202 lhs.GetBlockSizes(rowSizes, colSizes);
204 unsigned int curResultRow = 0;
205 unsigned int curWrapperRow = 0;
206 unsigned int rowsInBlock = 0;
207 unsigned int columnsInBlock = 0;
208 for (
unsigned int blockRow = 0; blockRow < numberOfBlockRows; ++blockRow)
210 curResultRow += rowsInBlock;
211 curWrapperRow += columnsInBlock;
214 rowsInBlock = rowSizes[blockRow] + 1;
215 columnsInBlock = colSizes[blockRow] + 1;
219 rowsInBlock = rowSizes[blockRow] - rowSizes[blockRow - 1];
220 columnsInBlock = colSizes[blockRow] - colSizes[blockRow - 1];
223 if (rowsInBlock == 0)
227 if (columnsInBlock == 0)
229 std::fill(result.
begin() + curResultRow,
230 result.
begin() + curResultRow + rowsInBlock, 0.0);
234 const LhsInnerMatrixType *block = lhs.GetBlockPtr(blockRow, blockRow);
240 DataType *resultWrapper = result_ptr + curResultRow;
241 const DataType *rhsWrapper = rhs_ptr + curWrapperRow;
242 Multiply(resultWrapper, *block, rhsWrapper);
244 curResultRow += rowsInBlock;
245 if (curResultRow < result.
GetRows())
247 std::fill(result.
begin() + curResultRow, result.
end(), 0.0);
255 BlockMatrixTag> &lhs,
258 unsigned int numberOfBlockRows = lhs.GetNumberOfBlockRows();
264 lhs.GetBlockSizes(rowSizes, colSizes);
266 unsigned int curResultRow = 0;
267 unsigned int curWrapperRow = 0;
268 unsigned int rowsInBlock = 0;
269 unsigned int columnsInBlock = 0;
270 for (
unsigned int blockRow = 0; blockRow < numberOfBlockRows; ++blockRow)
272 curResultRow += rowsInBlock;
273 curWrapperRow += columnsInBlock;
276 rowsInBlock = rowSizes[blockRow] + 1;
277 columnsInBlock = colSizes[blockRow] + 1;
281 rowsInBlock = rowSizes[blockRow] - rowSizes[blockRow - 1];
282 columnsInBlock = colSizes[blockRow] - colSizes[blockRow - 1];
285 if (rowsInBlock == 0)
289 if (columnsInBlock == 0)
291 std::fill(result.
begin() + curResultRow,
292 result.
begin() + curResultRow + rowsInBlock, 0.0);
296 const DNekScalMat *block = lhs.GetBlockPtr(blockRow, blockRow);
302 double *resultWrapper = result_ptr + curResultRow;
303 const double *rhsWrapper = rhs_ptr + curWrapperRow;
306 const unsigned int *size = block->GetSize();
307 Blas::Gemv(
'N', size[0], size[1], block->Scale(), block->GetRawPtr(),
308 size[0], rhsWrapper, 1, 0.0, resultWrapper, 1);
310 curResultRow += rowsInBlock;
311 if (curResultRow < result.
GetRows())
313 std::fill(result.
begin() + curResultRow, result.
end(), 0.0);
321 BlockMatrixTag> &lhs,
324 unsigned int numberOfBlockRows = lhs.GetNumberOfBlockRows();
330 lhs.GetBlockSizes(rowSizes, colSizes);
332 unsigned int curResultRow = 0;
333 unsigned int curWrapperRow = 0;
334 unsigned int rowsInBlock = 0;
335 unsigned int columnsInBlock = 0;
336 for (
unsigned int blockRow = 0; blockRow < numberOfBlockRows; ++blockRow)
338 curResultRow += rowsInBlock;
339 curWrapperRow += columnsInBlock;
342 rowsInBlock = rowSizes[blockRow] + 1;
343 columnsInBlock = colSizes[blockRow] + 1;
347 rowsInBlock = rowSizes[blockRow] - rowSizes[blockRow - 1];
348 columnsInBlock = colSizes[blockRow] - colSizes[blockRow - 1];
351 if (rowsInBlock == 0)
355 if (columnsInBlock == 0)
357 std::fill(result.
begin() + curResultRow,
358 result.
begin() + curResultRow + rowsInBlock, 0.0);
362 const SNekScalMat *block = lhs.GetBlockPtr(blockRow, blockRow);
368 NekSingle *resultWrapper = result_ptr + curResultRow;
369 const NekSingle *rhsWrapper = rhs_ptr + curWrapperRow;
372 const unsigned int *size = block->GetSize();
373 Blas::Gemv(
'N', size[0], size[1], block->Scale(), block->GetRawPtr(),
374 size[0], rhsWrapper, 1, 0.0, resultWrapper, 1);
376 curResultRow += rowsInBlock;
377 if (curResultRow < result.
GetRows())
379 std::fill(result.
begin() + curResultRow, result.
end(), 0.0);
383template <
typename DataType>
389 std::copy(rhs, rhs + vectorSize, result);
392 DataType *x = result;
398template <
typename DataType>
407 for (
unsigned int i = 0; i < lhs.GetColumns(); ++i)
409 result[i] *= lhs.Scale();
413template <
typename DataType,
typename LhsDataType,
typename MatrixType>
418 for (
unsigned int i = 0; i < lhs.GetRows(); ++i)
420 DataType accum = DataType(0);
421 for (
unsigned int j = 0; j <= i; ++j)
423 accum += lhs(i, j) * rhs[j];
429template <
typename DataType>
435 std::copy(rhs, rhs + vectorSize, result);
438 DataType *x = result;
444template <
typename DataType>
453 for (
unsigned int i = 0; i < lhs.GetColumns(); ++i)
455 result[i] *= lhs.Scale();
459template <
typename DataType,
typename LhsDataType,
typename MatrixType>
464 for (
unsigned int i = 0; i < lhs.GetRows(); ++i)
466 DataType accum = DataType(0);
467 for (
unsigned int j = i; j < lhs.GetColumns(); ++j)
469 accum += lhs(i, j) * rhs[j];
475template <
typename DataType,
typename InnerMatrixType,
typename MatrixTag>
479 typename std::enable_if<
483 boost::ignore_unused(
p);
485 const unsigned int *size = lhs.GetSize();
487 DataType alpha = lhs.Scale();
488 const DataType *a = lhs.GetRawPtr();
489 const DataType *x = rhs;
492 DataType *y = result;
498template <
typename DataType,
typename InnerMatrixType,
typename MatrixTag>
502 typename std::enable_if<
506 boost::ignore_unused(
p);
511template <
typename DataType,
typename InnerMatrixType,
typename MatrixTag>
515 typename std::enable_if<
519 boost::ignore_unused(
p);
521 const unsigned int *size = lhs.GetSize();
523 char t = lhs.GetTransposeFlag();
525 DataType alpha = lhs.Scale();
526 const DataType *a = lhs.GetRawPtr();
528 const DataType *x = rhs;
531 DataType *y = result;
534 Blas::Gemv(t, size[0], size[1], alpha, a, lda, x, incx,
beta, y, incy);
537template <
typename DataType,
typename InnerMatrixType,
typename MatrixTag>
541 typename std::enable_if<
545 boost::ignore_unused(
p);
550template <
typename DataType,
typename LhsDataType,
typename MatrixType>
554 switch (lhs.GetType())
582template <
typename DataType,
typename LhsDataType,
typename MatrixType>
589 std::string(
"A left side matrix with column count ") +
590 std::to_string(lhs.GetColumns()) +
591 std::string(
" and a right side vector with row count ") +
592 std::to_string(rhs.
GetRows()) +
593 std::string(
" can't be multiplied."));
604template <
typename DataType,
typename LhsInnerMatrixType>
626template <
typename DataType,
typename LhsDataType,
typename MatrixType>
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
#define NEKTAR_STANDARD_AND_SCALED_MATRICES
#define NEKTAR_ALL_MATRIX_TYPES
#define NEKTAR_BLOCK_MATRIX_TYPES
unsigned int GetRows() const
char GetTransposeFlag() const
unsigned int GetColumns() const
const DataType * GetRawPtr() const
unsigned int GetDimension() const
Returns the number of dimensions for the point.
unsigned int GetRows() const
static void Gemv(const char &trans, const int &m, const int &n, const double &alpha, const double *a, const int &lda, const double *x, const int &incx, const double &beta, double *y, const int &incy)
BLAS level 2: Matrix vector multiply y = alpha A x plus beta y where A[m x n].
static void Gbmv(const char &trans, const int &m, const int &n, const int &kl, const int &ku, const double &alpha, const double *a, const int &lda, const double *x, const int &incx, const double &beta, double *y, const int &incy)
BLAS level 2: Matrix vector multiply y = alpha A x plus beta y where A[m x n] is banded.
static void Tpmv(const char &uplo, const char &trans, const char &diag, const int &n, const double *ap, double *x, const int &incx)
BLAS level 2: Matrix vector multiply x = alpha A x where A[n x n].
static void Spmv(const char &uplo, const int &n, const double &alpha, const double *a, const double *x, const int &incx, const double &beta, double *y, const int &incy)
BLAS level 2: Matrix vector multiply y = alpha A x plus beta y where A[n x n] is symmetric packed.
@ beta
Gauss Radau pinned at x=-1,.
The above copyright notice and this permission notice shall be included.
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 NekMultiplyFullMatrix(DataType *result, const NekMatrix< InnerMatrixType, MatrixTag > &lhs, const DataType *rhs, typename std::enable_if< CanGetRawPtr< NekMatrix< InnerMatrixType, MatrixTag > >::value >::type *p=0)
void DiagonalBlockMatrixMultiply(NekVector< DataType > &result, const NekMatrix< LhsInnerMatrixType, BlockMatrixTag > &lhs, const NekVector< DataType > &rhs)
NEKTAR_BLOCK_MATRIX_TYPES_SINGLE
void Multiply(NekMatrix< ResultDataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const ResultDataType &rhs)
void NekMultiplyLowerTriangularMatrix(DataType *result, const NekMatrix< DataType, StandardMatrixTag > &lhs, const DataType *rhs)
NEKTAR_ALL_MATRIX_TYPES_SINGLE
void NekMultiplyDiagonalMatrix(DataType *result, const NekMatrix< LhsDataType, MatrixType > &lhs, const DataType *rhs)
void NekMultiplySymmetricMatrix(DataType *result, const NekMatrix< InnerMatrixType, MatrixTag > &lhs, const DataType *rhs, typename std::enable_if< CanGetRawPtr< NekMatrix< InnerMatrixType, MatrixTag > >::value >::type *p=0)
void DiagonalBlockFullScalMatrixMultiply(NekVector< double > &result, const NekMatrix< NekMatrix< NekMatrix< NekDouble, StandardMatrixTag >, ScaledMatrixTag >, BlockMatrixTag > &lhs, const NekVector< double > &rhs)
void NekMultiplyBandedMatrix(DataType *result, const NekMatrix< LhsDataType, MatrixType > &lhs, const DataType *rhs, typename std::enable_if< CanGetRawPtr< NekMatrix< LhsDataType, MatrixType > >::value >::type *p=0)
void NekMultiplyUnspecializedMatrixType(DataType *result, const NekMatrix< LhsDataType, MatrixType > &lhs, const DataType *rhs)
@ eLOWER_TRIANGULAR_BANDED
@ eUPPER_TRIANGULAR_BANDED
void FullBlockMatrixMultiply(NekVector< DataType > &result, const NekMatrix< LhsInnerMatrixType, BlockMatrixTag > &lhs, const NekVector< DataType > &rhs)
NEKTAR_STANDARD_AND_SCALED_MATRICES_SINGLE
void NekMultiplyUpperTriangularMatrix(DataType *result, const NekMatrix< DataType, StandardMatrixTag > &lhs, const DataType *rhs)
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.