35 #include <type_traits>
37 #include <boost/core/ignore_unused.hpp>
57 template<
typename DataType,
typename LhsDataType,
typename MatrixType>
62 for(
unsigned int i = 0; i < lhs.GetRows(); ++i)
64 DataType accum = DataType(0);
65 for(
unsigned int j = 0; j < lhs.GetColumns(); ++j)
67 accum += lhs(i,j)*rhs[j];
73 template<
typename DataType,
typename LhsDataType,
typename MatrixType>
78 int n = lhs.GetRows();
79 for(
unsigned int i = 0; i < n; ++i)
81 result[i] = lhs(i,i)*rhs[i];
85 template<
typename DataType,
typename LhsDataType>
90 int n = lhs.GetRows();
91 const DataType* mat_ptr = lhs.GetRawPtr();
95 template<
typename DataType,
typename LhsDataType,
typename MatrixType>
99 typename std::enable_if<
102 boost::ignore_unused(
p);
104 int m = lhs.GetRows();
105 int n = lhs.GetColumns();
106 int kl = lhs.GetNumberOfSubDiagonals();
107 int ku = lhs.GetNumberOfSuperDiagonals();
108 DataType alpha = lhs.Scale();
109 const DataType* a = lhs.GetRawPtr();
110 int lda = kl + ku + 1;
111 const DataType* x = rhs;
114 DataType* y = result;
116 Blas::Gbmv(
'N', m, n, kl, ku, alpha, a, lda, x, incx, beta, y, incy);
120 template<
typename DataType,
typename LhsDataType>
124 typename std::enable_if<
127 boost::ignore_unused(result, lhs, rhs,
p);
132 template<
typename DataType,
typename LhsInnerMatrixType>
137 unsigned int numberOfBlockRows = lhs.GetNumberOfBlockRows();
138 unsigned int numberOfBlockColumns = lhs.GetNumberOfBlockColumns();
139 DataType* result_ptr = result.
GetRawPtr();
140 const DataType* rhs_ptr = rhs.
GetRawPtr();
144 result_ptr[i] = DataType(0);
147 DataType* temp_ptr = temp.
get();
149 unsigned int curResultRow = 0;
150 for(
unsigned int blockRow = 0; blockRow < numberOfBlockRows; ++blockRow)
152 unsigned int rowsInBlock = lhs.GetNumberOfRowsInBlockRow(blockRow);
156 curResultRow += lhs.GetNumberOfRowsInBlockRow(blockRow-1);
159 if( rowsInBlock == 0 )
164 DataType* resultWrapper = result_ptr + curResultRow;
166 unsigned int curWrapperRow = 0;
167 for(
unsigned int blockColumn = 0; blockColumn < numberOfBlockColumns; ++blockColumn)
169 if( blockColumn != 0 )
171 curWrapperRow += lhs.GetNumberOfColumnsInBlockColumn(blockColumn-1);
175 const LhsInnerMatrixType* block = lhs.GetBlockPtr(blockRow, blockColumn);
181 unsigned int columnsInBlock = lhs.GetNumberOfColumnsInBlockColumn(blockColumn);
182 if( columnsInBlock == 0 )
187 const DataType* rhsWrapper = rhs_ptr + curWrapperRow;
188 Multiply(temp_ptr, *block, rhsWrapper);
189 for(
unsigned int i = 0; i < rowsInBlock; ++i)
191 resultWrapper[i] += temp_ptr[i];
197 template<
typename DataType,
typename LhsInnerMatrixType>
202 unsigned int numberOfBlockRows = lhs.GetNumberOfBlockRows();
203 DataType* result_ptr = result.
GetRawPtr();
204 const DataType* rhs_ptr = rhs.
GetRawPtr();
208 lhs.GetBlockSizes(rowSizes, colSizes);
210 unsigned int curResultRow = 0;
211 unsigned int curWrapperRow = 0;
212 unsigned int rowsInBlock = 0;
213 unsigned int columnsInBlock = 0;
214 for(
unsigned int blockRow = 0; blockRow < numberOfBlockRows; ++blockRow)
216 curResultRow += rowsInBlock;
217 curWrapperRow += columnsInBlock;
220 rowsInBlock = rowSizes[blockRow] + 1;
221 columnsInBlock = colSizes[blockRow] + 1;
225 rowsInBlock = rowSizes[blockRow] - rowSizes[blockRow-1];
226 columnsInBlock = colSizes[blockRow] - colSizes[blockRow-1];
229 if( rowsInBlock == 0)
233 if( columnsInBlock == 0)
235 std::fill(result.
begin()+curResultRow,
236 result.
begin()+curResultRow + rowsInBlock, 0.0);
240 const LhsInnerMatrixType* block = lhs.GetBlockPtr(blockRow, blockRow);
246 DataType* resultWrapper = result_ptr + curResultRow;
247 const DataType* rhsWrapper = rhs_ptr + curWrapperRow;
248 Multiply(resultWrapper, *block, rhsWrapper);
251 curResultRow += rowsInBlock;
252 if (curResultRow < result.
GetRows())
254 std::fill(result.
begin()+curResultRow, result.
end(), 0.0);
262 unsigned int numberOfBlockRows = lhs.GetNumberOfBlockRows();
268 lhs.GetBlockSizes(rowSizes, colSizes);
270 unsigned int curResultRow = 0;
271 unsigned int curWrapperRow = 0;
272 unsigned int rowsInBlock = 0;
273 unsigned int columnsInBlock = 0;
274 for(
unsigned int blockRow = 0; blockRow < numberOfBlockRows; ++blockRow)
276 curResultRow += rowsInBlock;
277 curWrapperRow += columnsInBlock;
280 rowsInBlock = rowSizes[blockRow] + 1;
281 columnsInBlock = colSizes[blockRow] + 1;
285 rowsInBlock = rowSizes[blockRow] - rowSizes[blockRow-1];
286 columnsInBlock = colSizes[blockRow] - colSizes[blockRow-1];
289 if( rowsInBlock == 0)
293 if( columnsInBlock == 0)
295 std::fill(result.
begin()+curResultRow,
296 result.
begin()+curResultRow + rowsInBlock, 0.0);
300 const DNekScalMat* block = lhs.GetBlockPtr(blockRow, blockRow);
306 double* resultWrapper = result_ptr + curResultRow;
307 const double* rhsWrapper = rhs_ptr + curWrapperRow;
310 const unsigned int* size = block->GetSize();
311 Blas::Gemv(
'N', size[0], size[1], block->Scale(),
312 block->GetRawPtr(), size[0], rhsWrapper, 1,
313 0.0, resultWrapper, 1);
315 curResultRow += rowsInBlock;
316 if (curResultRow < result.
GetRows())
318 std::fill(result.
begin()+curResultRow, result.
end(), 0.0);
326 unsigned int numberOfBlockRows = lhs.GetNumberOfBlockRows();
332 lhs.GetBlockSizes(rowSizes, colSizes);
334 unsigned int curResultRow = 0;
335 unsigned int curWrapperRow = 0;
336 unsigned int rowsInBlock = 0;
337 unsigned int columnsInBlock = 0;
338 for(
unsigned int blockRow = 0; blockRow < numberOfBlockRows; ++blockRow)
340 curResultRow += rowsInBlock;
341 curWrapperRow += columnsInBlock;
344 rowsInBlock = rowSizes[blockRow] + 1;
345 columnsInBlock = colSizes[blockRow] + 1;
349 rowsInBlock = rowSizes[blockRow] - rowSizes[blockRow-1];
350 columnsInBlock = colSizes[blockRow] - colSizes[blockRow-1];
353 if( rowsInBlock == 0)
357 if( columnsInBlock == 0)
359 std::fill(result.
begin()+curResultRow,
360 result.
begin()+curResultRow + rowsInBlock, 0.0);
364 const SNekScalMat* block = lhs.GetBlockPtr(blockRow, blockRow);
370 NekSingle* resultWrapper = result_ptr + curResultRow;
371 const NekSingle* rhsWrapper = rhs_ptr + curWrapperRow;
374 const unsigned int* size = block->GetSize();
375 Blas::Gemv(
'N', size[0], size[1], block->Scale(),
376 block->GetRawPtr(), size[0], rhsWrapper, 1,
377 0.0, resultWrapper, 1);
379 curResultRow += rowsInBlock;
380 if (curResultRow < result.
GetRows())
382 std::fill(result.
begin()+curResultRow, result.
end(), 0.0);
386 template<
typename DataType>
395 DataType* x = result;
401 template<
typename DataType>
408 for(
unsigned int i = 0; i < lhs.GetColumns(); ++i)
410 result[i] *= lhs.Scale();
414 template<
typename DataType,
typename LhsDataType,
typename MatrixType>
419 for(
unsigned int i = 0; i < lhs.GetRows(); ++i)
421 DataType accum = DataType(0);
422 for(
unsigned int j = 0; j <= i; ++j)
424 accum += lhs(i,j)*rhs[j];
430 template<
typename DataType>
439 DataType* x = result;
445 template<
typename DataType>
452 for(
unsigned int i = 0; i < lhs.GetColumns(); ++i)
454 result[i] *= lhs.Scale();
458 template<
typename DataType,
typename LhsDataType,
typename MatrixType>
463 for(
unsigned int i = 0; i < lhs.GetRows(); ++i)
465 DataType accum = DataType(0);
466 for(
unsigned int j = i; j < lhs.GetColumns(); ++j)
468 accum += lhs(i,j)*rhs[j];
474 template<
typename DataType,
typename InnerMatrixType,
typename MatrixTag>
478 boost::ignore_unused(
p);
480 const unsigned int* size = lhs.GetSize();
482 DataType alpha = lhs.Scale();
483 const DataType* a = lhs.GetRawPtr();
484 const DataType* x = rhs;
487 DataType* y = result;
490 Blas::Spmv(
'U', size[0], alpha, a, x, incx, beta, y, incy);
493 template<
typename DataType,
typename InnerMatrixType,
typename MatrixTag>
497 boost::ignore_unused(
p);
502 template<
typename DataType,
typename InnerMatrixType,
typename MatrixTag>
506 boost::ignore_unused(
p);
508 const unsigned int* size = lhs.GetSize();
510 char t = lhs.GetTransposeFlag();
512 DataType alpha = lhs.Scale();
513 const DataType* a = lhs.GetRawPtr();
515 const DataType* x = rhs;
518 DataType* y = result;
521 Blas::Gemv(t, size[0], size[1], alpha, a, lda, x, incx, beta, y, incy);
524 template<
typename DataType,
typename InnerMatrixType,
typename MatrixTag>
528 boost::ignore_unused(
p);
533 template<
typename DataType,
typename LhsDataType,
typename MatrixType>
538 switch(lhs.GetType())
566 template<
typename DataType,
typename LhsDataType,
typename MatrixType>
572 ASSERTL1(lhs.GetColumns() == rhs.
GetRows(), std::string(
"A left side matrix with column count ") +
573 std::to_string(lhs.GetColumns()) +
574 std::string(
" and a right side vector with row count ") +
575 std::to_string(rhs.
GetRows()) + std::string(
" can't be multiplied."));
582 template<typename DataType, typename LhsInnerMatrixType>
584 const
NekMatrix<LhsInnerMatrixType, BlockMatrixTag>& lhs,
600 template<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 = A x 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)
static void Tpmv(const char &uplo, const char &trans, const char &diag, const int &n, const double *ap, double *x, const int &incx)
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 = A x where A is symmetric packed.
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.