35#ifndef _BLAZE_MATH_EXPRESSIONS_SMATSMATMULTEXPR_H_
36#define _BLAZE_MATH_EXPRESSIONS_SMATSMATMULTEXPR_H_
104template<
typename MT1
107 :
public MatMatMultExpr< SparseMatrix< SMatSMatMultExpr<MT1,MT2>, false > >
135 template<
typename T1,
typename T2,
typename T3 >
136 static constexpr bool CanExploitSymmetry_v =
137 ( IsColumnMajorMatrix_v<T1> && IsSymmetric_v<T2> && IsSymmetric_v<T3> );
147 template<
typename T1,
typename T2,
typename T3 >
148 static constexpr bool IsEvaluationRequired_v =
206 if( IsDiagonal_v<MT1> ) {
209 else if( IsDiagonal_v<MT2> ) {
212 else if( IsTriangular_v<MT1> || IsTriangular_v<MT2> ) {
213 const size_t begin( ( IsUpper_v<MT1> )
214 ?( ( IsLower_v<MT2> )
215 ?(
max( ( IsStrictlyUpper_v<MT1> ? i+1UL : i )
216 , ( IsStrictlyLower_v<MT2> ? j+1UL : j ) ) )
217 :( IsStrictlyUpper_v<MT1> ? i+1UL : i ) )
218 :( ( IsLower_v<MT2> )
219 ?( IsStrictlyLower_v<MT2> ? j+1UL : j )
221 const size_t end( ( IsLower_v<MT1> )
222 ?( ( IsUpper_v<MT2> )
223 ?(
min( ( IsStrictlyLower_v<MT1> ? i : i+1UL )
224 , ( IsStrictlyUpper_v<MT2> ? j : j+1UL ) ) )
225 :( IsStrictlyLower_v<MT1> ? i : i+1UL ) )
226 :( ( IsUpper_v<MT2> )
227 ?( IsStrictlyUpper_v<MT2> ? j : j+1UL )
228 :(
lhs_.columns() ) ) );
252 if( i >=
lhs_.rows() ) {
255 if( j >=
rhs_.columns() ) {
267 inline size_t rows() const noexcept {
278 return rhs_.columns();
298 inline size_t nonZeros(
size_t i )
const noexcept {
330 template<
typename T >
331 inline bool canAlias(
const T* alias )
const noexcept {
332 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
342 template<
typename T >
343 inline bool isAliased(
const T* alias )
const noexcept {
344 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
354 return (
rows() *
columns() >= SMP_SMATSMATMULT_THRESHOLD );
377 template<
typename MT
397 SMatSMatMultExpr::selectAssignKernel( *lhs, A, B );
415 template<
typename MT3
418 static inline void selectAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
420 for(
size_t i=0UL; i<C.rows(); ++i ) {
421 const auto lend( A.end(i) );
422 for(
auto lelem=A.begin(i); lelem!=lend; ++lelem ) {
423 const auto rend( B.end( lelem->index() ) );
424 for(
auto relem=B.begin( lelem->index() ); relem!=rend; ++relem )
428 C(i,relem->index()) = lelem->value() * relem->value();
431 C(i,relem->index()) += lelem->value() * relem->value();
453 template<
typename MT >
454 friend inline void assign( SparseMatrix<MT,false>& lhs,
const SMatSMatMultExpr& rhs )
472 size_t nonzeros( 0UL );
474 for(
size_t i=0UL; i<(*lhs).rows(); ++i ) {
475 const auto lend( A.end(i) );
476 for(
auto lelem=A.begin(i); lelem!=lend; ++lelem ) {
477 nonzeros += B.nonZeros( lelem->index() );
481 if( nonzeros > (*lhs).rows() * (*lhs).columns() ) {
482 nonzeros = (*lhs).rows() * (*lhs).columns();
485 (*lhs).reserve( nonzeros );
489 SmallArray<ElementType,128UL> values ( (*lhs).columns(),
ElementType() );
490 SmallArray<bool,128UL> valid ( (*lhs).columns(),
false );
491 SmallArray<size_t,128UL> indices( (*lhs).columns(), 0UL );
492 size_t minIndex(
inf ), maxIndex( 0UL );
494 for(
size_t i=0UL; i<(*lhs).rows(); ++i )
496 const auto lend( A.end(i) );
497 for(
auto lelem=A.begin(i); lelem!=lend; ++lelem )
499 const auto rend( B.end( lelem->index() ) );
500 for(
auto relem=B.begin( lelem->index() ); relem!=rend; ++relem )
502 if( !valid[relem->index()] ) {
503 values[relem->index()] = lelem->value() * relem->value();
504 valid [relem->index()] =
true;
505 indices[nonzeros] = relem->index();
507 if( relem->index() < minIndex ) minIndex = relem->index();
508 if( relem->index() > maxIndex ) maxIndex = relem->index();
511 values[relem->index()] += lelem->value() * relem->value();
522 if( ( nonzeros + nonzeros ) < ( maxIndex - minIndex ) )
524 std::sort( indices.begin(), indices.begin() + nonzeros );
526 for(
size_t j=0UL; j<nonzeros; ++j )
528 const size_t index( indices[j] );
530 (*lhs).append( i, index, values[index] );
531 reset( values[index] );
534 reset( valid[index] );
538 for(
size_t j=minIndex; j<=maxIndex; ++j )
541 (*lhs).append( i, j, values[j] );
554 (*lhs).finalize( i );
573 template<
typename MT >
574 friend inline auto assign( SparseMatrix<MT,true>& lhs,
const SMatSMatMultExpr& rhs )
575 -> DisableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
588 (*lhs).reserve( tmp.nonZeros() );
609 template<
typename MT >
610 friend inline auto assign( Matrix<MT,true>& lhs,
const SMatSMatMultExpr& rhs )
611 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
620 assign( *lhs,
trans( rhs.lhs_ ) *
trans( rhs.rhs_ ) );
638 template<
typename MT
640 friend inline auto addAssign( DenseMatrix<MT,SO>& lhs,
const SMatSMatMultExpr& rhs )
641 -> DisableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
658 SMatSMatMultExpr::selectAddAssignKernel( *lhs, A, B );
677 template<
typename MT3
680 static inline void selectAddAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
682 for(
size_t i=0UL; i<C.rows(); ++i ) {
683 const auto lend( A.end(i) );
684 for(
auto lelem=A.begin(i); lelem!=lend; ++lelem ) {
685 const auto rend( B.end( lelem->index() ) );
686 for(
auto relem=B.begin( lelem->index() ); relem!=rend; ++relem ) {
687 C(i,relem->index()) += lelem->value() * relem->value();
710 template<
typename MT >
711 friend inline auto addAssign( Matrix<MT,true>& lhs,
const SMatSMatMultExpr& rhs )
712 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
721 addAssign( *lhs,
trans( rhs.lhs_ ) *
trans( rhs.rhs_ ) );
743 template<
typename MT
745 friend inline auto subAssign( DenseMatrix<MT,SO>& lhs,
const SMatSMatMultExpr& rhs )
746 -> DisableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
763 SMatSMatMultExpr::selectSubAssignKernel( *lhs, A, B );
782 template<
typename MT3
785 static inline void selectSubAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
787 for(
size_t i=0UL; i<C.rows(); ++i ) {
788 const auto lend( A.end(i) );
789 for(
auto lelem=A.begin(i); lelem!=lend; ++lelem ) {
790 const auto rend( B.end( lelem->index() ) );
791 for(
auto relem=B.begin( lelem->index() ); relem!=rend; ++relem ) {
792 C(i,relem->index()) -= lelem->value() * relem->value();
815 template<
typename MT >
816 friend inline auto subAssign( Matrix<MT,true>& lhs,
const SMatSMatMultExpr& rhs )
817 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
826 subAssign( *lhs,
trans( rhs.lhs_ ) *
trans( rhs.rhs_ ) );
848 template<
typename MT
850 friend inline void schurAssign( DenseMatrix<MT,SO>& lhs,
const SMatSMatMultExpr& rhs )
862 schurAssign( *lhs, tmp );
894 template<
typename MT
897 -> EnableIf_t< IsEvaluationRequired_v<MT,MT1,MT2> >
934 template<
typename MT >
936 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
966 template<
typename MT
969 -> EnableIf_t< IsEvaluationRequired_v<MT,MT1,MT2> >
1006 template<
typename MT >
1008 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
1042 template<
typename MT
1045 -> EnableIf_t< IsEvaluationRequired_v<MT,MT1,MT2> >
1082 template<
typename MT >
1084 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
1115 template<
typename MT
1183template<
typename MT1
1185 ,
DisableIf_t< ( ( IsIdentity_v<MT1> || IsIdentity_v<MT2> ) &&
1186 IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > ) ||
1187 ( IsIdentity_v<MT1> && IsIdentity_v<MT2> ) ||
1188 ( IsZero_v<MT1> || IsZero_v<MT2> ) >* =
nullptr >
1189inline const SMatSMatMultExpr<MT1,MT2>
1190 smatsmatmult(
const SparseMatrix<MT1,false>& lhs,
const SparseMatrix<MT2,false>& rhs )
1196 return SMatSMatMultExpr<MT1,MT2>( *lhs, *rhs );
1216template<
typename MT1
1218 , EnableIf_t< !IsIdentity_v<MT1> && IsIdentity_v<MT2> &&
1219 IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > >* =
nullptr >
1221 smatsmatmult(
const SparseMatrix<MT1,false>& lhs,
const SparseMatrix<MT2,false>& rhs )
1249template<
typename MT1
1251 , EnableIf_t< IsIdentity_v<MT1> && !IsIdentity_v<MT2> &&
1252 IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > >* =
nullptr >
1254 smatsmatmult(
const SparseMatrix<MT1,false>& lhs,
const SparseMatrix<MT2,false>& rhs )
1281template<
typename MT1
1283 , EnableIf_t< IsIdentity_v<MT1> && IsIdentity_v<MT2> >* =
nullptr >
1284inline decltype(
auto)
1285 smatsmatmult(
const SparseMatrix<MT1,false>& lhs,
const SparseMatrix<MT2,false>& rhs )
1293 using ReturnType =
const MultTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
1298 return ReturnType( (*lhs).rows() );
1317template<
typename MT1
1319 , EnableIf_t< IsZero_v<MT1> || IsZero_v<MT2> >* =
nullptr >
1320inline decltype(
auto)
1321 smatsmatmult(
const SparseMatrix<MT1,false>& lhs,
const SparseMatrix<MT2,false>& rhs )
1327 using ReturnType =
const MultTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
1332 return ReturnType( (*lhs).rows(), (*rhs).columns() );
1365template<
typename MT1
1367inline decltype(
auto)
1372 if( (*lhs).columns() != (*rhs).rows() ) {
1376 return smatsmatmult( *lhs, *rhs );
Header file for auxiliary alias declarations.
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.
Definition: Aliases.h:110
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.
Definition: Aliases.h:450
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.
Definition: Aliases.h:190
typename T::OppositeType OppositeType_t
Alias declaration for nested OppositeType type definitions.
Definition: Aliases.h:310
typename T::TransposeType TransposeType_t
Alias declaration for nested TransposeType type definitions.
Definition: Aliases.h:550
Header file for run time assertion macros.
Header file for the blaze::checked and blaze::unchecked instances.
Header file for the EnableIf class template.
Header file for the function trace functionality.
Constraint on the data type.
Header file for the If class template.
Numerical infinity for built-in data types.
Header file for the IntegralConstant class template.
Header file for the IsColumnMajorMatrix type trait.
Header file for the isDefault shim.
Header file for the IsDiagonal type trait.
Header file for the IsExpression type trait class.
Header file for the IsIdentity type trait.
Header file for the IsLower type trait.
Header file for the IsResizable type trait.
Header file for the IsStrictlyLower type trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Header file for the IsTriangular type trait.
Header file for the IsUpper type trait.
Header file for the MAYBE_UNUSED function template.
Header file for the multiplication trait.
Constraints on the storage order of matrix types.
Header file for the SmallArray implementation.
Constraint on the data type.
Constraint on the data type.
Base class for dense matrices.
Definition: DenseMatrix.h:82
Expression object for sparse matrix-sparse matrix multiplications.
Definition: SMatSMatMultExpr.h:109
const ElementType ReturnType
Return type for expression template evaluations.
Definition: SMatSMatMultExpr.h:165
ResultType_t< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatSMatMultExpr.h:112
If_t< IsExpression_v< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: SMatSMatMultExpr.h:172
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SMatSMatMultExpr.h:343
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SMatSMatMultExpr.h:331
static constexpr bool evaluateRight
Compilation switch for the composite type of the right-hand side sparse matrix expression.
Definition: SMatSMatMultExpr.h:125
size_t nonZeros(size_t i) const noexcept
Returns the number of non-zero elements in the specified row.
Definition: SMatSMatMultExpr.h:298
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: SMatSMatMultExpr.h:360
MultTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: SMatSMatMultExpr.h:161
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatSMatMultExpr.h:251
ResultType_t< MT2 > RT2
Result type of the right-hand side sparse matrix expression.
Definition: SMatSMatMultExpr.h:113
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: SMatSMatMultExpr.h:177
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: SMatSMatMultExpr.h:353
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatSMatMultExpr.h:162
RightOperand rightOperand() const noexcept
Returns the right-hand side sparse matrix operand.
Definition: SMatSMatMultExpr.h:319
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: SMatSMatMultExpr.h:309
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatSMatMultExpr.h:202
If_t< IsExpression_v< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatSMatMultExpr.h:169
CompositeType_t< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatSMatMultExpr.h:114
static constexpr bool evaluateLeft
Compilation switch for the composite type of the left-hand side sparse matrix expression.
Definition: SMatSMatMultExpr.h:120
SMatSMatMultExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the SMatSMatMultExpr class.
Definition: SMatSMatMultExpr.h:187
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SMatSMatMultExpr.h:163
CompositeType_t< MT2 > CT2
Composite type of the right-hand side sparse matrix expression.
Definition: SMatSMatMultExpr.h:115
constexpr size_t nonZeros() const noexcept
Returns the number of non-zero elements in the sparse matrix.
Definition: SMatSMatMultExpr.h:287
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: SMatSMatMultExpr.h:164
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: SMatSMatMultExpr.h:361
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SMatSMatMultExpr.h:277
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SMatSMatMultExpr.h:267
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatSMatMultExpr.h:166
Base class for sparse matrices.
Definition: SparseMatrix.h:77
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
Header file for the SparseMatrix base class.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:137
decltype(auto) min(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise minimum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1339
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1375
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:766
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:812
bool isDefault(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the given diagonal matrix is in default state.
Definition: DiagonalMatrix.h:169
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: RowMajorMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.
Definition: RequiresEvaluation.h:81
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATMULTEXPR(T1, T2)
Constraint on the data type.
Definition: MatMatMultExpr.h:103
#define BLAZE_CONSTRAINT_MUST_NOT_BE_ZERO_TYPE(T)
Constraint on the data type.
Definition: Zero.h:81
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.
Definition: SparseMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_BE_IDENTITY_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Identity.h:60
#define BLAZE_CONSTRAINT_MUST_BE_ZERO_TYPE(T)
Constraint on the data type.
Definition: Zero.h:61
typename MultTrait< T1, T2 >::Type MultTrait_t
Auxiliary alias declaration for the MultTrait class template.
Definition: MultTrait.h:165
constexpr bool IsResizable_v
Auxiliary variable template for the IsResizable type trait.
Definition: IsResizable.h:136
constexpr Infinity inf
Global Infinity instance.
Definition: Infinity.h:1080
constexpr void reset(Matrix< MT, SO > &matrix)
Resetting the given matrix.
Definition: Matrix.h:806
MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:584
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:518
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:137
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
auto smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:194
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
decltype(auto) subvector(Vector< VT, TF > &, RSAs...)
Creating a view on a specific subvector of the given vector.
Definition: Subvector.h:158
constexpr bool IsSame_v
Auxiliary variable template for the IsSame type trait.
Definition: IsSame.h:159
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
typename If< Condition >::template Type< T1, T2 > If_t
Auxiliary alias template for the If class template.
Definition: If.h:108
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.
Definition: Exception.h:331
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.
Definition: Exception.h:235
typename EnableIf<!Condition, T >::Type DisableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:175
#define BLAZE_FUNCTION_TRACE
Function trace macro.
Definition: FunctionTrace.h:94
constexpr Unchecked unchecked
Global Unchecked instance.
Definition: Check.h:146
Header file for the exception macros of the math module.
Header file for all forward declarations for expression class templates.
Header file for the reset shim.
Header file for the serial shim.
Base class for all compute expression templates.
Definition: Computation.h:68
Base class for all matrix/matrix multiplication expression templates.
Definition: MatMatMultExpr.h:71
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
Header file for the IsZero type trait.
Header file for the RequiresEvaluation type trait.
Header file for basic type definitions.
Header file for the generic max algorithm.
Header file for the generic min algorithm.