43template <
typename DataType,
typename LhsDataType,
typename MatrixType>
48 for (
unsigned int i = 0; i < lhs.GetRows(); ++i)
50 DataType accum = DataType(0);
51 for (
unsigned int j = 0; j < lhs.GetColumns(); ++j)
53 accum += lhs(i, j) * rhs[j];
59template <
typename DataType,
typename LhsDataType,
typename MatrixType>
64 int n = lhs.GetRows();
65 for (
unsigned int i = 0; i < n; ++i)
67 result[i] = lhs(i, i) * rhs[i];
71template <
typename DataType,
typename LhsDataType>
76 int n = lhs.GetRows();
77 const DataType *mat_ptr = lhs.GetRawPtr();
81template <
typename DataType,
typename LhsDataType,
typename MatrixType>
85 [[maybe_unused]]
typename std::enable_if<
89 int m = lhs.GetRows();
90 int n = lhs.GetColumns();
91 int kl = lhs.GetNumberOfSubDiagonals();
92 int ku = lhs.GetNumberOfSuperDiagonals();
93 DataType alpha = lhs.Scale();
94 const DataType *a = lhs.GetRawPtr();
95 int lda = kl + ku + 1;
96 const DataType *x = rhs;
101 Blas::Gbmv(
'N', m, n, kl, ku, alpha, a, lda, x, incx,
beta, y, incy);
104template <
typename DataType,
typename LhsDataType>
106 [[maybe_unused]] DataType *result,
108 [[maybe_unused]]
const DataType *rhs,
109 [[maybe_unused]]
typename std::enable_if<
114 "Banded block matrix multiplication not yet implemented");
117template <
typename DataType,
typename LhsInnerMatrixType>
123 unsigned int numberOfBlockRows = lhs.GetNumberOfBlockRows();
124 unsigned int numberOfBlockColumns = lhs.GetNumberOfBlockColumns();
125 DataType *result_ptr = result.
GetRawPtr();
126 const DataType *rhs_ptr = rhs.
GetRawPtr();
128 for (
unsigned int i = 0; i < result.
GetDimension(); ++i)
130 result_ptr[i] = DataType(0);
133 DataType *temp_ptr = temp.
get();
135 unsigned int curResultRow = 0;
136 for (
unsigned int blockRow = 0; blockRow < numberOfBlockRows; ++blockRow)
138 unsigned int rowsInBlock = lhs.GetNumberOfRowsInBlockRow(blockRow);
142 curResultRow += lhs.GetNumberOfRowsInBlockRow(blockRow - 1);
145 if (rowsInBlock == 0)
150 DataType *resultWrapper = result_ptr + curResultRow;
152 unsigned int curWrapperRow = 0;
153 for (
unsigned int blockColumn = 0; blockColumn < numberOfBlockColumns;
156 if (blockColumn != 0)
159 lhs.GetNumberOfColumnsInBlockColumn(blockColumn - 1);
162 const LhsInnerMatrixType *block =
163 lhs.GetBlockPtr(blockRow, blockColumn);
169 unsigned int columnsInBlock =
170 lhs.GetNumberOfColumnsInBlockColumn(blockColumn);
171 if (columnsInBlock == 0)
176 const DataType *rhsWrapper = rhs_ptr + curWrapperRow;
177 Multiply(temp_ptr, *block, rhsWrapper);
178 for (
unsigned int i = 0; i < rowsInBlock; ++i)
180 resultWrapper[i] += temp_ptr[i];
186template <
typename DataType,
typename LhsInnerMatrixType>
192 unsigned int numberOfBlockRows = lhs.GetNumberOfBlockRows();
193 DataType *result_ptr = result.
GetRawPtr();
194 const DataType *rhs_ptr = rhs.
GetRawPtr();
198 lhs.GetBlockSizes(rowSizes, colSizes);
200 unsigned int curResultRow = 0;
201 unsigned int curWrapperRow = 0;
202 unsigned int rowsInBlock = 0;
203 unsigned int columnsInBlock = 0;
204 for (
unsigned int blockRow = 0; blockRow < numberOfBlockRows; ++blockRow)
206 curResultRow += rowsInBlock;
207 curWrapperRow += columnsInBlock;
210 rowsInBlock = rowSizes[blockRow] + 1;
211 columnsInBlock = colSizes[blockRow] + 1;
215 rowsInBlock = rowSizes[blockRow] - rowSizes[blockRow - 1];
216 columnsInBlock = colSizes[blockRow] - colSizes[blockRow - 1];
219 if (rowsInBlock == 0)
223 if (columnsInBlock == 0)
225 std::fill(result.
begin() + curResultRow,
226 result.
begin() + curResultRow + rowsInBlock, 0.0);
230 const LhsInnerMatrixType *block = lhs.GetBlockPtr(blockRow, blockRow);
236 DataType *resultWrapper = result_ptr + curResultRow;
237 const DataType *rhsWrapper = rhs_ptr + curWrapperRow;
238 Multiply(resultWrapper, *block, rhsWrapper);
240 curResultRow += rowsInBlock;
241 if (curResultRow < result.
GetRows())
243 std::fill(result.
begin() + curResultRow, result.
end(), 0.0);
251 BlockMatrixTag> &lhs,
254 unsigned int numberOfBlockRows = lhs.GetNumberOfBlockRows();
260 lhs.GetBlockSizes(rowSizes, colSizes);
262 unsigned int curResultRow = 0;
263 unsigned int curWrapperRow = 0;
264 unsigned int rowsInBlock = 0;
265 unsigned int columnsInBlock = 0;
266 for (
unsigned int blockRow = 0; blockRow < numberOfBlockRows; ++blockRow)
268 curResultRow += rowsInBlock;
269 curWrapperRow += columnsInBlock;
272 rowsInBlock = rowSizes[blockRow] + 1;
273 columnsInBlock = colSizes[blockRow] + 1;
277 rowsInBlock = rowSizes[blockRow] - rowSizes[blockRow - 1];
278 columnsInBlock = colSizes[blockRow] - colSizes[blockRow - 1];
281 if (rowsInBlock == 0)
285 if (columnsInBlock == 0)
287 std::fill(result.
begin() + curResultRow,
288 result.
begin() + curResultRow + rowsInBlock, 0.0);
292 const DNekScalMat *block = lhs.GetBlockPtr(blockRow, blockRow);
298 double *resultWrapper = result_ptr + curResultRow;
299 const double *rhsWrapper = rhs_ptr + curWrapperRow;
302 const unsigned int *size = block->GetSize();
303 Blas::Gemv(
'N', size[0], size[1], block->Scale(), block->GetRawPtr(),
304 size[0], rhsWrapper, 1, 0.0, resultWrapper, 1);
306 curResultRow += rowsInBlock;
307 if (curResultRow < result.
GetRows())
309 std::fill(result.
begin() + curResultRow, result.
end(), 0.0);
317 BlockMatrixTag> &lhs,
320 unsigned int numberOfBlockRows = lhs.GetNumberOfBlockRows();
326 lhs.GetBlockSizes(rowSizes, colSizes);
328 unsigned int curResultRow = 0;
329 unsigned int curWrapperRow = 0;
330 unsigned int rowsInBlock = 0;
331 unsigned int columnsInBlock = 0;
332 for (
unsigned int blockRow = 0; blockRow < numberOfBlockRows; ++blockRow)
334 curResultRow += rowsInBlock;
335 curWrapperRow += columnsInBlock;
338 rowsInBlock = rowSizes[blockRow] + 1;
339 columnsInBlock = colSizes[blockRow] + 1;
343 rowsInBlock = rowSizes[blockRow] - rowSizes[blockRow - 1];
344 columnsInBlock = colSizes[blockRow] - colSizes[blockRow - 1];
347 if (rowsInBlock == 0)
351 if (columnsInBlock == 0)
353 std::fill(result.
begin() + curResultRow,
354 result.
begin() + curResultRow + rowsInBlock, 0.0);
358 const SNekScalMat *block = lhs.GetBlockPtr(blockRow, blockRow);
364 NekSingle *resultWrapper = result_ptr + curResultRow;
365 const NekSingle *rhsWrapper = rhs_ptr + curWrapperRow;
368 const unsigned int *size = block->GetSize();
369 Blas::Gemv(
'N', size[0], size[1], block->Scale(), block->GetRawPtr(),
370 size[0], rhsWrapper, 1, 0.0, resultWrapper, 1);
372 curResultRow += rowsInBlock;
373 if (curResultRow < result.
GetRows())
375 std::fill(result.
begin() + curResultRow, result.
end(), 0.0);
379template <
typename DataType>
385 std::copy(rhs, rhs + vectorSize, result);
388 DataType *x = result;
394template <
typename DataType>
403 for (
unsigned int i = 0; i < lhs.GetColumns(); ++i)
405 result[i] *= lhs.Scale();
409template <
typename DataType,
typename LhsDataType,
typename MatrixType>
414 for (
unsigned int i = 0; i < lhs.GetRows(); ++i)
416 DataType accum = DataType(0);
417 for (
unsigned int j = 0; j <= i; ++j)
419 accum += lhs(i, j) * rhs[j];
425template <
typename DataType>
431 std::copy(rhs, rhs + vectorSize, result);
434 DataType *x = result;
440template <
typename DataType>
449 for (
unsigned int i = 0; i < lhs.GetColumns(); ++i)
451 result[i] *= lhs.Scale();
455template <
typename DataType,
typename LhsDataType,
typename MatrixType>
460 for (
unsigned int i = 0; i < lhs.GetRows(); ++i)
462 DataType accum = DataType(0);
463 for (
unsigned int j = i; j < lhs.GetColumns(); ++j)
465 accum += lhs(i, j) * rhs[j];
471template <
typename DataType,
typename InnerMatrixType,
typename MatrixTag>
475 [[maybe_unused]]
typename std::enable_if<
479 const unsigned int *size = lhs.GetSize();
481 DataType alpha = lhs.Scale();
482 const DataType *a = lhs.GetRawPtr();
483 const DataType *x = rhs;
486 DataType *y = result;
492template <
typename DataType,
typename InnerMatrixType,
typename MatrixTag>
496 [[maybe_unused]]
typename std::enable_if<
503template <
typename DataType,
typename InnerMatrixType,
typename MatrixTag>
507 [[maybe_unused]]
typename std::enable_if<
511 const unsigned int *size = lhs.GetSize();
513 char t = lhs.GetTransposeFlag();
515 DataType alpha = lhs.Scale();
516 const DataType *a = lhs.GetRawPtr();
518 const DataType *x = rhs;
521 DataType *y = result;
524 Blas::Gemv(t, size[0], size[1], alpha, a, lda, x, incx,
beta, y, incy);
527template <
typename DataType,
typename InnerMatrixType,
typename MatrixTag>
531 [[maybe_unused]]
typename std::enable_if<
538template <
typename DataType,
typename LhsDataType,
typename MatrixType>
542 switch (lhs.GetType())
570template <
typename DataType,
typename LhsDataType,
typename MatrixType>
577 std::string(
"A left side matrix with column count ") +
578 std::to_string(lhs.GetColumns()) +
579 std::string(
" and a right side vector with row count ") +
580 std::to_string(rhs.
GetRows()) +
581 std::string(
" can't be multiplied."));
592template <
typename DataType,
typename LhsInnerMatrixType>
614template <
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,.
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 DiagonalBlockMatrixMultiply(NekVector< DataType > &result, const NekMatrix< LhsInnerMatrixType, BlockMatrixTag > &lhs, const NekVector< DataType > &rhs)
NEKTAR_BLOCK_MATRIX_TYPES_SINGLE
void NekMultiplySymmetricMatrix(DataType *result, const NekMatrix< InnerMatrixType, MatrixTag > &lhs, const DataType *rhs, typename std::enable_if< CanGetRawPtr< NekMatrix< InnerMatrixType, MatrixTag > >::value >::type *p=nullptr)
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 DiagonalBlockFullScalMatrixMultiply(NekVector< double > &result, const NekMatrix< NekMatrix< NekMatrix< NekDouble, StandardMatrixTag >, ScaledMatrixTag >, BlockMatrixTag > &lhs, const NekVector< double > &rhs)
void NekMultiplyUnspecializedMatrixType(DataType *result, const NekMatrix< LhsDataType, MatrixType > &lhs, const DataType *rhs)
void NekMultiplyFullMatrix(DataType *result, const NekMatrix< InnerMatrixType, MatrixTag > &lhs, const DataType *rhs, typename std::enable_if< CanGetRawPtr< NekMatrix< InnerMatrixType, MatrixTag > >::value >::type *p=nullptr)
@ 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 NekMultiplyBandedMatrix(DataType *result, const NekMatrix< LhsDataType, MatrixType > &lhs, const DataType *rhs, typename std::enable_if< CanGetRawPtr< NekMatrix< LhsDataType, MatrixType > >::value >::type *p=nullptr)
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.