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.