35#ifndef _BLAZE_MATH_EXPRESSIONS_TSMATTSMATMULTEXPR_H_
36#define _BLAZE_MATH_EXPRESSIONS_TSMATTSMATMULTEXPR_H_
105template<
typename MT1
108 :
public MatMatMultExpr< SparseMatrix< TSMatTSMatMultExpr<MT1,MT2>, true > >
136 template<
typename T1,
typename T2,
typename T3 >
137 static constexpr bool CanExploitSymmetry_v =
138 ( IsRowMajorMatrix_v<T1> && IsSymmetric_v<T2> && IsSymmetric_v<T3> );
148 template<
typename T1,
typename T2,
typename T3 >
149 static constexpr bool IsEvaluationRequired_v =
207 if( IsDiagonal_v<MT1> ) {
210 else if( IsDiagonal_v<MT2> ) {
213 else if( IsTriangular_v<MT1> || IsTriangular_v<MT2> ) {
214 const size_t begin( ( IsUpper_v<MT1> )
215 ?( ( IsLower_v<MT2> )
216 ?(
max( ( IsStrictlyUpper_v<MT1> ? i+1UL : i )
217 , ( IsStrictlyLower_v<MT2> ? j+1UL : j ) ) )
218 :( IsStrictlyUpper_v<MT1> ? i+1UL : i ) )
219 :( ( IsLower_v<MT2> )
220 ?( IsStrictlyLower_v<MT2> ? j+1UL : j )
222 const size_t end( ( IsLower_v<MT1> )
223 ?( ( IsUpper_v<MT2> )
224 ?(
min( ( IsStrictlyLower_v<MT1> ? i : i+1UL )
225 , ( IsStrictlyUpper_v<MT2> ? j : j+1UL ) ) )
226 :( IsStrictlyLower_v<MT1> ? i : i+1UL ) )
227 :( ( IsUpper_v<MT2> )
228 ?( IsStrictlyUpper_v<MT2> ? j : j+1UL )
229 :(
lhs_.columns() ) ) );
253 if( i >=
lhs_.rows() ) {
256 if( j >=
rhs_.columns() ) {
268 inline size_t rows() const noexcept {
279 return rhs_.columns();
299 inline size_t nonZeros(
size_t i )
const noexcept {
331 template<
typename T >
332 inline bool canAlias(
const T* alias )
const noexcept {
333 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
343 template<
typename T >
344 inline bool isAliased(
const T* alias )
const noexcept {
345 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
355 return (
rows() *
columns() >= SMP_TSMATTSMATMULT_THRESHOLD );
378 template<
typename MT
398 TSMatTSMatMultExpr::selectAssignKernel( *lhs, A, B );
417 template<
typename MT3
420 static inline void selectAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
422 for(
size_t j=0UL; j<C.columns(); ++j ) {
423 const auto rend( B.end(j) );
424 for(
auto relem=B.begin(j); relem!=rend; ++relem ) {
425 const auto lend( A.end( relem->index() ) );
426 for(
auto lelem=A.begin( relem->index() ); lelem!=lend; ++lelem )
430 C(lelem->index(),j) = lelem->value() * relem->value();
433 C(lelem->index(),j) += lelem->value() * relem->value();
455 template<
typename MT >
456 friend inline auto assign( SparseMatrix<MT,false>& lhs,
const TSMatTSMatMultExpr& rhs )
457 -> DisableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
470 (*lhs).reserve( tmp.nonZeros() );
489 template<
typename MT >
490 friend inline void assign( SparseMatrix<MT,true>& lhs,
const TSMatTSMatMultExpr& rhs )
508 size_t nonzeros( 0UL );
510 for(
size_t j=0UL; j<(*lhs).columns(); ++j ) {
511 const auto rend( B.end(j) );
512 for(
auto relem=B.begin(j); relem!=rend; ++relem ) {
513 nonzeros += A.nonZeros( relem->index() );
517 if( nonzeros > (*lhs).rows() * (*lhs).columns() ) {
518 nonzeros = (*lhs).rows() * (*lhs).columns();
521 (*lhs).reserve( nonzeros );
525 SmallArray<ElementType,128UL> values ( (*lhs).rows(),
ElementType() );
526 SmallArray<bool,128UL> valid ( (*lhs).rows(),
false );
527 SmallArray<size_t,128UL> indices( (*lhs).rows(), 0UL );
528 size_t minIndex(
inf ), maxIndex( 0UL );
530 for(
size_t j=0UL; j<(*lhs).columns(); ++j )
532 const auto rend( B.end(j) );
533 for(
auto relem=B.begin(j); relem!=rend; ++relem )
535 const auto lend( A.end( relem->index() ) );
536 for(
auto lelem=A.begin( relem->index() ); lelem!=lend; ++lelem )
538 if( !valid[lelem->index()] ) {
539 values[lelem->index()] = lelem->value() * relem->value();
540 valid [lelem->index()] =
true;
541 indices[nonzeros] = lelem->index();
543 if( lelem->index() < minIndex ) minIndex = lelem->index();
544 if( lelem->index() > maxIndex ) maxIndex = lelem->index();
547 values[lelem->index()] += lelem->value() * relem->value();
558 if( ( nonzeros + nonzeros ) < ( maxIndex - minIndex ) )
560 std::sort( indices.begin(), indices.begin() + nonzeros );
562 for(
size_t i=0UL; i<nonzeros; ++i )
564 const size_t index( indices[i] );
566 (*lhs).append( index, j, values[index] );
567 reset( values[index] );
570 reset( valid[index] );
574 for(
size_t i=minIndex; i<=maxIndex; ++i )
577 (*lhs).append( i, j, values[i] );
590 (*lhs).finalize( j );
611 template<
typename MT >
613 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
622 assign( *lhs,
trans( rhs.lhs_ ) *
trans( rhs.rhs_ ) );
640 template<
typename MT
642 friend inline auto addAssign( DenseMatrix<MT,SO>& lhs,
const TSMatTSMatMultExpr& rhs )
643 -> DisableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
660 TSMatTSMatMultExpr::selectAddAssignKernel( *lhs, A, B );
679 template<
typename MT3
682 static inline void selectAddAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
684 for(
size_t j=0UL; j<C.columns(); ++j ) {
685 const auto rend( B.end(j) );
686 for(
auto relem=B.begin(j); relem!=rend; ++relem ) {
687 const auto lend( A.end( relem->index() ) );
688 for(
auto lelem=A.begin( relem->index() ); lelem!=lend; ++lelem ) {
689 C(lelem->index(),j) += lelem->value() * relem->value();
712 template<
typename MT >
714 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
723 addAssign( *lhs,
trans( rhs.lhs_ ) *
trans( rhs.rhs_ ) );
745 template<
typename MT
747 friend inline auto subAssign( DenseMatrix<MT,SO>& lhs,
const TSMatTSMatMultExpr& rhs )
748 -> DisableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
765 TSMatTSMatMultExpr::selectSubAssignKernel( *lhs, A, B );
784 template<
typename MT3
787 static inline void selectSubAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
789 for(
size_t j=0UL; j<C.columns(); ++j ) {
790 const auto rend( B.end(j) );
791 for(
auto relem=B.begin(j); relem!=rend; ++relem ) {
792 const auto lend( A.end( relem->index() ) );
793 for(
auto lelem=A.begin( relem->index() ); lelem!=lend; ++lelem ) {
794 C(lelem->index(),j) -= lelem->value() * relem->value();
818 template<
typename MT >
820 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
829 subAssign( *lhs,
trans( rhs.lhs_ ) *
trans( rhs.rhs_ ) );
851 template<
typename MT
853 friend inline void schurAssign( DenseMatrix<MT,SO>& lhs,
const TSMatTSMatMultExpr& rhs )
865 schurAssign( *lhs, tmp );
898 template<
typename MT
901 -> EnableIf_t< IsEvaluationRequired_v<MT,MT1,MT2> >
938 template<
typename MT >
940 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
970 template<
typename MT
973 -> EnableIf_t< IsEvaluationRequired_v<MT,MT1,MT2> >
1011 template<
typename MT >
1013 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
1047 template<
typename MT
1050 -> EnableIf_t< IsEvaluationRequired_v<MT,MT1,MT2> >
1088 template<
typename MT >
1090 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
1121 template<
typename MT
1188template<
typename MT1
1190 ,
DisableIf_t< ( ( IsIdentity_v<MT1> || IsIdentity_v<MT2> ) &&
1191 IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > ) ||
1192 ( IsIdentity_v<MT1> && IsIdentity_v<MT2> ) ||
1193 ( IsZero_v<MT1> || IsZero_v<MT2> ) >* =
nullptr >
1194inline const TSMatTSMatMultExpr<MT1,MT2>
1195 tsmattsmatmult(
const SparseMatrix<MT1,true>& lhs,
const SparseMatrix<MT2,true>& rhs )
1201 return TSMatTSMatMultExpr<MT1,MT2>( *lhs, *rhs );
1221template<
typename MT1
1223 , EnableIf_t< !IsIdentity_v<MT1> && IsIdentity_v<MT2> &&
1224 IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > >* =
nullptr >
1226 tsmattsmatmult(
const SparseMatrix<MT1,true>& lhs,
const SparseMatrix<MT2,true>& rhs )
1254template<
typename MT1
1256 , EnableIf_t< IsIdentity_v<MT1> && !IsIdentity_v<MT2> &&
1257 IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > >* =
nullptr >
1259 tsmattsmatmult(
const SparseMatrix<MT1,true>& lhs,
const SparseMatrix<MT2,true>& rhs )
1286template<
typename MT1
1288 , EnableIf_t< IsIdentity_v<MT1> && IsIdentity_v<MT2> >* =
nullptr >
1289inline decltype(
auto)
1290 tsmattsmatmult(
const SparseMatrix<MT1,true>& lhs,
const SparseMatrix<MT2,true>& rhs )
1298 using ReturnType =
const MultTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
1303 return ReturnType( (*lhs).rows() );
1323template<
typename MT1
1325 , EnableIf_t< IsZero_v<MT1> || IsZero_v<MT2> >* =
nullptr >
1326inline decltype(
auto)
1327 tsmattsmatmult(
const SparseMatrix<MT1,true>& lhs,
const SparseMatrix<MT2,true>& rhs )
1333 using ReturnType =
const MultTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
1338 return ReturnType( (*lhs).rows(), (*rhs).columns() );
1371template<
typename MT1
1373inline decltype(
auto)
1378 if( (*lhs).columns() != (*rhs).rows() ) {
1382 return tsmattsmatmult( *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.
Constraints on the storage order of matrix types.
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 IsBuiltin 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 IsRowMajorMatrix 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.
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
Base class for sparse matrices.
Definition: SparseMatrix.h:77
Expression object for transpose sparse matrix-transpose sparse matrix multiplications.
Definition: TSMatTSMatMultExpr.h:110
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:163
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatTSMatMultExpr.h:203
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: TSMatTSMatMultExpr.h:362
If_t< IsExpression_v< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:173
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: TSMatTSMatMultExpr.h:165
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: TSMatTSMatMultExpr.h:361
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: TSMatTSMatMultExpr.h:332
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: TSMatTSMatMultExpr.h:178
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: TSMatTSMatMultExpr.h:354
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatTSMatMultExpr.h:167
ResultType_t< MT2 > RT2
Result type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:114
TSMatTSMatMultExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the TSMatTSMatMultExpr class.
Definition: TSMatTSMatMultExpr.h:188
LeftOperand leftOperand() const noexcept
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatTSMatMultExpr.h:310
constexpr size_t nonZeros() const noexcept
Returns the number of non-zero elements in the sparse matrix.
Definition: TSMatTSMatMultExpr.h:288
MultTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:162
CompositeType_t< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:115
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:164
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: TSMatTSMatMultExpr.h:252
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: TSMatTSMatMultExpr.h:268
RightOperand rightOperand() const noexcept
Returns the right-hand side transpose sparse matrix operand.
Definition: TSMatTSMatMultExpr.h:320
static constexpr bool evaluateRight
Compilation switch for the composite type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:126
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSMatTSMatMultExpr.h:166
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: TSMatTSMatMultExpr.h:278
If_t< IsExpression_v< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:170
CompositeType_t< MT2 > CT2
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:116
static constexpr bool evaluateLeft
Compilation switch for the composite type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:121
ResultType_t< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatMultExpr.h:113
size_t nonZeros(size_t i) const noexcept
Returns the number of non-zero elements in the specified row.
Definition: TSMatTSMatMultExpr.h:299
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: TSMatTSMatMultExpr.h:344
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_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_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: ColumnMajorMatrix.h:61
#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.