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)
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 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 double alpha =
lhs.Scale();
109 const double* a =
lhs.GetRawPtr();
110 int lda = kl + ku + 1;
111 const double* x =
rhs;
116 Blas::Dgbmv(
'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 LhsInnerMatrixType>
202 unsigned int numberOfBlockRows =
lhs.GetNumberOfBlockRows();
204 const double* 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 double* resultWrapper = result_ptr + curResultRow;
247 const double* 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();
264 const double* rhs_ptr =
rhs.GetRawPtr();
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);
306 double* resultWrapper = result_ptr + curResultRow;
307 const double* rhsWrapper = rhs_ptr + curWrapperRow;
310 const unsigned int* size = block->GetSize();
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 int vectorSize =
lhs.GetColumns();
328 int n =
lhs.GetRows();
329 const double* a =
lhs.GetRawPtr();
342 for(
unsigned int i = 0; i <
lhs.GetColumns(); ++i)
344 result[i] *=
lhs.Scale();
348 template<
typename DataType,
typename LhsDataType,
typename MatrixType>
353 for(
unsigned int i = 0; i <
lhs.GetRows(); ++i)
355 DataType accum = DataType(0);
356 for(
unsigned int j = 0; j <= i; ++j)
368 int vectorSize =
lhs.GetColumns();
370 int n =
lhs.GetRows();
371 const double* a =
lhs.GetRawPtr();
384 for(
unsigned int i = 0; i <
lhs.GetColumns(); ++i)
386 result[i] *=
lhs.Scale();
390 template<
typename DataType,
typename LhsDataType,
typename MatrixType>
395 for(
unsigned int i = 0; i <
lhs.GetRows(); ++i)
397 DataType accum = DataType(0);
398 for(
unsigned int j = i; j <
lhs.GetColumns(); ++j)
406 template<
typename InnerMatrixType,
typename MatrixTag>
410 boost::ignore_unused(
p);
412 const unsigned int* size =
lhs.GetSize();
414 double alpha =
lhs.Scale();
415 const double* a =
lhs.GetRawPtr();
416 const double* x =
rhs;
422 Blas::Dspmv(
'U', size[0], alpha, a, x, incx, beta, y, incy);
425 template<
typename InnerMatrixType,
typename MatrixTag>
429 boost::ignore_unused(
p);
434 template<
typename InnerMatrixType,
typename MatrixTag>
438 boost::ignore_unused(
p);
440 const unsigned int* size =
lhs.GetSize();
442 char t =
lhs.GetTransposeFlag();
444 double alpha =
lhs.Scale();
445 const double* a =
lhs.GetRawPtr();
447 const double* x =
rhs;
453 Blas::Dgemv(t, size[0], size[1], alpha, a, lda, x, incx, beta, y, incy);
456 template<
typename InnerMatrixType,
typename MatrixTag>
460 boost::ignore_unused(
p);
465 template<
typename DataType,
typename LhsDataType,
typename MatrixType>
470 switch(
lhs.GetType())
498 template<
typename DataType,
typename LhsDataType,
typename MatrixType>
504 ASSERTL1(
lhs.GetColumns() ==
rhs.GetRows(), std::string(
"A left side matrix with column count ") +
505 std::to_string(
lhs.GetColumns()) +
506 std::string(
" and a right side vector with row count ") +
507 std::to_string(
rhs.GetRows()) + std::string(
" can't be multiplied."));
513 template<
typename DataType,
typename LhsInnerMatrixType>
530 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_BLOCK_MATRIX_TYPES
unsigned int GetDimension() const
Returns the number of dimensions for the point.
unsigned int GetRows() const
static void Dgemv(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 Dgbmv(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 Dspmv(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.
static void Dtpmv(const char &uplo, const char &trans, const char &diag, const int &n, const double *ap, double *x, const int &incx)
void NekMultiplyUpperTriangularMatrix(NekDouble *result, const NekMatrix< NekDouble, StandardMatrixTag > &lhs, const NekDouble *rhs)
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs
void NekMultiplyFullMatrix(NekDouble *result, const NekMatrix< InnerMatrixType, MatrixTag > &lhs, const NekDouble *rhs, typename std::enable_if< CanGetRawPtr< NekMatrix< InnerMatrixType, MatrixTag > >::value >::type *p=0)
void NekMultiplyBandedMatrix(NekDouble *result, const NekMatrix< LhsDataType, MatrixType > &lhs, const NekDouble *rhs, typename std::enable_if< CanGetRawPtr< NekMatrix< LhsDataType, MatrixType > >::value >::type *p=0)
void NekMultiplyLowerTriangularMatrix(NekDouble *result, const NekMatrix< NekDouble, StandardMatrixTag > &lhs, const NekDouble *rhs)
void Multiply(NekMatrix< ResultDataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const ResultDataType &rhs)
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)
NEKTAR_GENERATE_EXPLICIT_FUNCTION_INSTANTIATION_SINGLE_MATRIX(Multiply, NEKTAR_ALL_MATRIX_TYPES,(1,(void)),(1,(DNekMat &)),(1,(const NekDouble &))) template< typename DataType
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)
void NekMultiplySymmetricMatrix(NekDouble *result, const NekMatrix< InnerMatrixType, MatrixTag > &lhs, const NekDouble *rhs, typename std::enable_if< CanGetRawPtr< NekMatrix< InnerMatrixType, MatrixTag > >::value >::type *p=0)
void DiagonalBlockMatrixMultiply(NekVector< double > &result, const NekMatrix< LhsInnerMatrixType, BlockMatrixTag > &lhs, const NekVector< double > &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.