35 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATDMATMULTEXPR_H_ 36 #define _BLAZE_MATH_EXPRESSIONS_TSMATDMATMULTEXPR_H_ 122 template<
typename MT1
128 class TSMatDMatMultExpr
129 :
public MatMatMultExpr< DenseMatrix< TSMatDMatMultExpr<MT1,MT2,SF,HF,LF,UF>, false > >
130 ,
private Computation
144 static constexpr
bool evaluateLeft = ( IsComputation_v<MT1> || RequiresEvaluation_v<MT1> );
149 static constexpr
bool evaluateRight = ( IsComputation_v<MT2> || RequiresEvaluation_v<MT2> );
153 static constexpr
bool SYM = ( SF && !( HF || LF || UF ) );
154 static constexpr
bool HERM = ( HF && !( LF || UF ) );
155 static constexpr
bool LOW = ( LF || ( ( SF || HF ) && UF ) );
156 static constexpr
bool UPP = ( UF || ( ( SF || HF ) && LF ) );
166 template<
typename T1,
typename T2,
typename T3 >
167 static constexpr
bool CanExploitSymmetry_v = IsSymmetric_v<T2>;
177 template<
typename T1,
typename T2,
typename T3 >
178 static constexpr
bool IsEvaluationRequired_v =
188 template<
typename T1,
typename T2,
typename T3 >
189 static constexpr
bool UseOptimizedKernel_v =
190 ( useOptimizedKernels &&
192 !IsResizable_v< ElementType_t<T1> > &&
193 !IsResizable_v<ET1> );
202 template<
typename T1,
typename T2,
typename T3 >
203 static constexpr
bool UseDefaultKernel_v = !UseOptimizedKernel_v<T1,T2,T3>;
300 if( IsDiagonal_v<MT1> ) {
303 else if( IsDiagonal_v<MT2> ) {
306 else if( IsTriangular_v<MT1> || IsTriangular_v<MT2> ) {
307 const size_t begin( ( IsUpper_v<MT1> )
308 ?( ( IsLower_v<MT2> )
309 ?(
max( ( IsStrictlyUpper_v<MT1> ? i+1UL : i )
310 , ( IsStrictlyLower_v<MT2> ? j+1UL : j ) ) )
311 :( IsStrictlyUpper_v<MT1> ? i+1UL : i ) )
312 :( ( IsLower_v<MT2> )
313 ?( IsStrictlyLower_v<MT2> ? j+1UL : j )
315 const size_t end( ( IsLower_v<MT1> )
316 ?( ( IsUpper_v<MT2> )
317 ?(
min( ( IsStrictlyLower_v<MT1> ? i : i+1UL )
318 , ( IsStrictlyUpper_v<MT2> ? j : j+1UL ) ) )
319 :( IsStrictlyLower_v<MT1> ? i : i+1UL ) )
320 :( ( IsUpper_v<MT2> )
321 ?( IsStrictlyUpper_v<MT2> ? j : j+1UL )
322 :(
lhs_.columns() ) ) );
346 if( i >=
lhs_.rows() ) {
349 if( j >=
rhs_.columns() ) {
361 inline size_t rows() const noexcept {
372 return rhs_.columns();
402 template<
typename T >
403 inline bool canAlias(
const T* alias )
const noexcept {
404 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
414 template<
typename T >
415 inline bool isAliased(
const T* alias )
const noexcept {
416 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
426 return rhs_.isAligned();
436 return (
rows() *
columns() >= SMP_TSMATDMATMULT_THRESHOLD ) && !IsDiagonal_v<MT2>;
459 template<
typename MT
479 TSMatDMatMultExpr::selectAssignKernel( ~lhs, A, B );
495 template<
typename MT3
498 static inline void selectAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
500 const size_t size( C.rows() * C.columns() );
502 if( ( IsRowMajorMatrix_v<MT3> &&
size < TSMATDMATMULT_THRESHOLD ) ||
503 ( IsColumnMajorMatrix_v<MT3> &&
size < 625UL ) )
504 selectSmallAssignKernel( C, A, B );
506 selectLargeAssignKernel( C, A, B );
526 template<
typename MT3
529 static inline void selectDefaultAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
533 if( IsDiagonal_v<MT5> )
535 for(
size_t i=0UL; i<A.columns(); ++i )
537 const auto end( A.end(i) );
538 auto element( A.begin(i) );
540 for( ; element!=
end; ++element ) {
541 C(element->index(),i) = element->value() * B(i,i);
547 const size_t block( IsRowMajorMatrix_v<MT3> ? 256UL : 8UL );
549 for(
size_t jj=0UL; jj<B.columns(); jj+=block )
551 const size_t jpos( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
553 for(
size_t i=0UL; i<A.columns(); ++i )
555 const auto end( A.end(i) );
556 auto element( A.begin(i) );
558 for( ; element!=
end; ++element )
560 const size_t i1( element->index() );
562 const size_t jbegin( ( IsUpper_v<MT5> )
564 ?(
max( i1, IsStrictlyUpper_v<MT5> ? i+1UL : i, jj ) )
565 :(
max( IsStrictlyUpper_v<MT5> ? i+1UL : i, jj ) ) )
567 const size_t jend( ( IsLower_v<MT5> )
569 ?(
min( i1+1UL, IsStrictlyLower_v<MT5> ? i : i+1UL, jpos ) )
570 :(
min( IsStrictlyLower_v<MT5> ? i : i+1UL, jpos ) ) )
571 :(
LOW ?
min(i1+1UL,jpos) : jpos ) );
576 for(
size_t j=jbegin; j<jend; ++j ) {
578 C(i1,j) = element->value() * B(i,j);
580 C(i1,j) += element->value() * B(i,j);
588 for(
size_t j=0UL; j<B.columns(); ++j ) {
589 for(
size_t i=j+1UL; i<A.rows(); ++i ) {
590 C(i,j) =
HERM ?
conj( C(j,i) ) : C(j,i);
612 template<
typename MT3
615 static inline auto selectSmallAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
616 -> EnableIf_t< UseDefaultKernel_v<MT3,MT4,MT5> >
618 selectDefaultAssignKernel( C, A, B );
638 template<
typename MT3
641 static inline auto selectSmallAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
642 -> EnableIf_t< UseOptimizedKernel_v<MT3,MT4,MT5> >
644 const size_t block( ( IsRowMajorMatrix_v<MT3> )?( 256UL ):( 8UL ) );
648 for(
size_t jj=0UL; jj<B.columns(); jj+=block )
650 const size_t jpos( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
652 for(
size_t i=0UL; i<A.columns(); ++i )
654 const auto end( A.end(i) );
655 auto element( A.begin(i) );
657 const size_t nonzeros( A.nonZeros(i) );
658 const size_t kpos( nonzeros &
size_t(-4) );
661 for(
size_t k=0UL; k<kpos; k+=4UL )
663 const size_t i1( element->index() );
664 const ET1 v1( element->value() );
666 const size_t i2( element->index() );
667 const ET1 v2( element->value() );
669 const size_t i3( element->index() );
670 const ET1 v3( element->value() );
672 const size_t i4( element->index() );
673 const ET1 v4( element->value() );
678 const size_t jbegin( ( IsUpper_v<MT5> )
680 ?(
max( i1, IsStrictlyUpper_v<MT5> ? i+1UL : i, jj ) )
681 :(
max( IsStrictlyUpper_v<MT5> ? i+1UL : i, jj ) ) )
683 const size_t jend( ( IsLower_v<MT5> )
685 ?(
min( i4+1UL, IsStrictlyLower_v<MT5> ? i : i+1UL, jpos ) )
686 :(
min( IsStrictlyLower_v<MT5> ? i : i+1UL, jpos ) ) )
687 :(
LOW ?
min(i4+1UL,jpos) : jpos ) );
692 for(
size_t j=jbegin; j<jend; ++j ) {
693 C(i1,j) += v1 * B(i,j);
694 C(i2,j) += v2 * B(i,j);
695 C(i3,j) += v3 * B(i,j);
696 C(i4,j) += v4 * B(i,j);
700 for( ; element!=
end; ++element )
702 const size_t i1( element->index() );
704 const size_t jbegin( ( IsUpper_v<MT5> )
706 ?(
max( i1, IsStrictlyUpper_v<MT5> ? i+1UL : i, jj ) )
707 :(
max( IsStrictlyUpper_v<MT5> ? i+1UL : i, jj ) ) )
709 const size_t jend( ( IsLower_v<MT5> )
711 ?(
min( i1+1UL, IsStrictlyLower_v<MT5> ? i : i+1UL, jpos ) )
712 :(
min( IsStrictlyLower_v<MT5> ? i : i+1UL, jpos ) ) )
713 :(
LOW ?
min(i1+1UL,jpos) : jpos ) );
718 for(
size_t j=jbegin; j<jend; ++j ) {
719 C(i1,j) += element->value() * B(i,j);
726 for(
size_t j=0UL; j<B.columns(); ++j ) {
727 for(
size_t i=j+1UL; i<A.rows(); ++i ) {
728 C(i,j) =
HERM ?
conj( C(j,i) ) : C(j,i);
750 template<
typename MT3
753 static inline auto selectLargeAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
754 -> EnableIf_t< UseDefaultKernel_v<MT3,MT4,MT5> >
756 selectDefaultAssignKernel( C, A, B );
776 template<
typename MT3
779 static inline auto selectLargeAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
780 -> EnableIf_t< UseOptimizedKernel_v<MT3,MT4,MT5> >
784 const ForwardFunctor fwd;
786 const OppositeType_t<MT4> tmp(
serial( A ) );
787 assign( C, fwd( tmp * B ) );
805 template<
typename MT
807 friend inline auto assign( SparseMatrix<MT,SO>& lhs,
const TSMatDMatMultExpr& rhs )
808 -> DisableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
812 using TmpType = If_t< SO, OppositeType, ResultType >;
824 const ForwardFunctor fwd;
826 const TmpType tmp(
serial( rhs ) );
827 assign( ~lhs, fwd( tmp ) );
847 template<
typename MT
850 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
859 const ForwardFunctor fwd;
861 assign( ~lhs, fwd(
trans( rhs.lhs_ ) * rhs.rhs_ ) );
879 template<
typename MT
881 friend inline auto addAssign( DenseMatrix<MT,SO>& lhs,
const TSMatDMatMultExpr& rhs )
882 -> DisableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
899 TSMatDMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
915 template<
typename MT3
918 static inline void selectAddAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
920 const size_t size( C.rows() * C.columns() );
922 if( ( IsRowMajorMatrix_v<MT3> &&
size < TSMATDMATMULT_THRESHOLD ) ||
923 ( IsColumnMajorMatrix_v<MT3> &&
size < 625UL ) )
924 selectSmallAddAssignKernel( C, A, B );
926 selectLargeAddAssignKernel( C, A, B );
946 template<
typename MT3
949 static inline void selectDefaultAddAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
951 if( IsDiagonal_v<MT5> )
953 for(
size_t i=0UL; i<A.columns(); ++i )
955 const auto end( A.end(i) );
956 auto element( A.begin(i) );
958 for( ; element!=
end; ++element ) {
959 C(element->index(),i) += element->value() * B(i,i);
965 const size_t block( IsRowMajorMatrix_v<MT3> ? 256UL : 8UL );
967 for(
size_t jj=0UL; jj<B.columns(); jj+=block )
969 const size_t jpos( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
971 for(
size_t i=0UL; i<A.columns(); ++i )
973 const auto end( A.end(i) );
974 auto element( A.begin(i) );
976 for( ; element!=
end; ++element )
978 const size_t i1( element->index() );
980 const size_t jbegin( ( IsUpper_v<MT5> )
982 ?(
max( i1, IsStrictlyUpper_v<MT5> ? i+1UL : i, jj ) )
983 :(
max( IsStrictlyUpper_v<MT5> ? i+1UL : i, jj ) ) )
984 :(
UPP ?
max(i1,jj) : jj ) );
985 const size_t jend( ( IsLower_v<MT5> )
987 ?(
min( i1+1UL, IsStrictlyLower_v<MT5> ? i : i+1UL, jpos ) )
988 :(
min( IsStrictlyLower_v<MT5> ? i : i+1UL, jpos ) ) )
989 :(
LOW ?
min(i1+1UL,jpos) : jpos ) );
994 for(
size_t j=jbegin; j<jend; ++j ) {
995 C(i1,j) += element->value() * B(i,j);
1019 template<
typename MT3
1022 static inline auto selectSmallAddAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
1023 -> EnableIf_t< UseDefaultKernel_v<MT3,MT4,MT5> >
1025 selectDefaultAddAssignKernel( C, A, B );
1045 template<
typename MT3
1048 static inline auto selectSmallAddAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
1049 -> EnableIf_t< UseOptimizedKernel_v<MT3,MT4,MT5> >
1051 const size_t block( ( IsRowMajorMatrix_v<MT3> )?( 256UL ):( 8UL ) );
1053 for(
size_t jj=0UL; jj<B.columns(); jj+=block )
1055 const size_t jpos( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
1057 for(
size_t i=0UL; i<A.columns(); ++i )
1059 const auto end( A.end(i) );
1060 auto element( A.begin(i) );
1062 const size_t nonzeros( A.nonZeros(i) );
1063 const size_t kpos( nonzeros &
size_t(-4) );
1066 for(
size_t k=0UL; k<kpos; k+=4UL )
1068 const size_t i1( element->index() );
1069 const ET1 v1( element->value() );
1071 const size_t i2( element->index() );
1072 const ET1 v2( element->value() );
1074 const size_t i3( element->index() );
1075 const ET1 v3( element->value() );
1077 const size_t i4( element->index() );
1078 const ET1 v4( element->value() );
1083 const size_t jbegin( ( IsUpper_v<MT5> )
1085 ?(
max( i1, IsStrictlyUpper_v<MT5> ? i+1UL : i, jj ) )
1086 :(
max( IsStrictlyUpper_v<MT5> ? i+1UL : i, jj ) ) )
1087 :(
UPP ?
max(i1,jj) : jj ) );
1088 const size_t jend( ( IsLower_v<MT5> )
1090 ?(
min( i4+1UL, IsStrictlyLower_v<MT5> ? i : i+1UL, jpos ) )
1091 :(
min( IsStrictlyLower_v<MT5> ? i : i+1UL, jpos ) ) )
1092 :(
LOW ?
min(i4+1UL,jpos) : jpos ) );
1094 if( jbegin >= jend )
1097 for(
size_t j=jbegin; j<jend; ++j ) {
1098 C(i1,j) += v1 * B(i,j);
1099 C(i2,j) += v2 * B(i,j);
1100 C(i3,j) += v3 * B(i,j);
1101 C(i4,j) += v4 * B(i,j);
1105 for( ; element!=
end; ++element )
1107 const size_t i1( element->index() );
1109 const size_t jbegin( ( IsUpper_v<MT5> )
1111 ?(
max( i1, IsStrictlyUpper_v<MT5> ? i+1UL : i, jj ) )
1112 :(
max( IsStrictlyUpper_v<MT5> ? i+1UL : i, jj ) ) )
1113 :(
UPP ?
max(i1,jj) : jj ) );
1114 const size_t jend( ( IsLower_v<MT5> )
1116 ?(
min( i1+1UL, IsStrictlyLower_v<MT5> ? i : i+1UL, jpos ) )
1117 :(
min( IsStrictlyLower_v<MT5> ? i : i+1UL, jpos ) ) )
1118 :(
LOW ?
min(i1+1UL,jpos) : jpos ) );
1120 if( jbegin >= jend )
1123 for(
size_t j=jbegin; j<jend; ++j ) {
1124 C(i1,j) += element->value() * B(i,j);
1147 template<
typename MT3
1150 static inline auto selectLargeAddAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
1151 -> EnableIf_t< UseDefaultKernel_v<MT3,MT4,MT5> >
1153 selectDefaultAddAssignKernel( C, A, B );
1173 template<
typename MT3
1176 static inline auto selectLargeAddAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
1177 -> EnableIf_t< UseOptimizedKernel_v<MT3,MT4,MT5> >
1181 const ForwardFunctor fwd;
1183 const OppositeType_t<MT4> tmp(
serial( A ) );
1184 addAssign( C, fwd( tmp * B ) );
1204 template<
typename MT
1206 friend inline auto addAssign( Matrix<MT,SO>& lhs,
const TSMatDMatMultExpr& rhs )
1207 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
1216 const ForwardFunctor fwd;
1218 addAssign( ~lhs, fwd(
trans( rhs.lhs_ ) * rhs.rhs_ ) );
1240 template<
typename MT
1242 friend inline auto subAssign( DenseMatrix<MT,SO>& lhs,
const TSMatDMatMultExpr& rhs )
1243 -> DisableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
1260 TSMatDMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
1276 template<
typename MT3
1279 static inline void selectSubAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
1281 const size_t size( C.rows() * C.columns() );
1283 if( ( IsRowMajorMatrix_v<MT3> &&
size < TSMATDMATMULT_THRESHOLD ) ||
1284 ( IsColumnMajorMatrix_v<MT3> &&
size < 625UL ) )
1285 selectSmallSubAssignKernel( C, A, B );
1287 selectLargeSubAssignKernel( C, A, B );
1307 template<
typename MT3
1310 static inline void selectDefaultSubAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
1312 if( IsDiagonal_v<MT5> )
1314 for(
size_t i=0UL; i<A.columns(); ++i )
1316 const auto end( A.end(i) );
1317 auto element( A.begin(i) );
1319 for( ; element!=
end; ++element ) {
1320 C(element->index(),i) -= element->value() * B(i,i);
1326 const size_t block( IsRowMajorMatrix_v<MT3> ? 256UL : 8UL );
1328 for(
size_t jj=0UL; jj<B.columns(); jj+=block )
1330 const size_t jpos( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
1332 for(
size_t i=0UL; i<A.columns(); ++i )
1334 const auto end( A.end(i) );
1335 auto element( A.begin(i) );
1337 for( ; element!=
end; ++element )
1339 const size_t i1( element->index() );
1341 const size_t jbegin( ( IsUpper_v<MT5> )
1343 ?(
max( i1, IsStrictlyUpper_v<MT5> ? i+1UL : i, jj ) )
1344 :(
max( IsStrictlyUpper_v<MT5> ? i+1UL : i, jj ) ) )
1345 :(
UPP ?
max(i1,jj) : jj ) );
1346 const size_t jend( ( IsLower_v<MT5> )
1348 ?(
min( i1+1UL, IsStrictlyLower_v<MT5> ? i : i+1UL, jpos ) )
1349 :(
min( IsStrictlyLower_v<MT5> ? i : i+1UL, jpos ) ) )
1350 :(
LOW ?
min(i1+1UL,jpos) : jpos ) );
1352 if( jbegin >= jend )
1355 for(
size_t j=jbegin; j<jend; ++j ) {
1356 C(i1,j) -= element->value() * B(i,j);
1380 template<
typename MT3
1383 static inline auto selectSmallSubAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
1384 -> EnableIf_t< UseDefaultKernel_v<MT3,MT4,MT5> >
1386 selectDefaultSubAssignKernel( C, A, B );
1406 template<
typename MT3
1409 static inline auto selectSmallSubAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
1410 -> EnableIf_t< UseOptimizedKernel_v<MT3,MT4,MT5> >
1412 const size_t block( ( IsRowMajorMatrix_v<MT3> )?( 256UL ):( 8UL ) );
1414 for(
size_t jj=0UL; jj<B.columns(); jj+=block )
1416 const size_t jpos( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
1418 for(
size_t i=0UL; i<A.columns(); ++i )
1420 const auto end( A.end(i) );
1421 auto element( A.begin(i) );
1423 const size_t nonzeros( A.nonZeros(i) );
1424 const size_t kpos( nonzeros &
size_t(-4) );
1427 for(
size_t k=0UL; k<kpos; k+=4UL )
1429 const size_t i1( element->index() );
1430 const ET1 v1( element->value() );
1432 const size_t i2( element->index() );
1433 const ET1 v2( element->value() );
1435 const size_t i3( element->index() );
1436 const ET1 v3( element->value() );
1438 const size_t i4( element->index() );
1439 const ET1 v4( element->value() );
1444 const size_t jbegin( ( IsUpper_v<MT5> )
1446 ?(
max( i1, IsStrictlyUpper_v<MT5> ? i+1UL : i, jj ) )
1447 :(
max( IsStrictlyUpper_v<MT5> ? i+1UL : i, jj ) ) )
1448 :(
UPP ?
max(i1,jj) : jj ) );
1449 const size_t jend( ( IsLower_v<MT5> )
1451 ?(
min( i4+1UL, IsStrictlyLower_v<MT5> ? i : i+1UL, jpos ) )
1452 :(
min( IsStrictlyLower_v<MT5> ? i : i+1UL, jpos ) ) )
1453 :(
LOW ?
min(i4+1UL,jpos) : jpos ) );
1455 if( jbegin >= jend )
1458 for(
size_t j=jbegin; j<jend; ++j ) {
1459 C(i1,j) -= v1 * B(i,j);
1460 C(i2,j) -= v2 * B(i,j);
1461 C(i3,j) -= v3 * B(i,j);
1462 C(i4,j) -= v4 * B(i,j);
1466 for( ; element!=
end; ++element )
1468 const size_t i1( element->index() );
1470 const size_t jbegin( ( IsUpper_v<MT5> )
1472 ?(
max( i1, IsStrictlyUpper_v<MT5> ? i+1UL : i, jj ) )
1473 :(
max( IsStrictlyUpper_v<MT5> ? i+1UL : i, jj ) ) )
1474 :(
UPP ?
max(i1,jj) : jj ) );
1475 const size_t jend( ( IsLower_v<MT5> )
1477 ?(
min( i1+1UL, IsStrictlyLower_v<MT5> ? i : i+1UL, jpos ) )
1478 :(
min( IsStrictlyLower_v<MT5> ? i : i+1UL, jpos ) ) )
1479 :(
LOW ?
min(i1+1UL,jpos) : jpos ) );
1481 if( jbegin >= jend )
1484 for(
size_t j=jbegin; j<jend; ++j ) {
1485 C(i1,j) -= element->value() * B(i,j);
1508 template<
typename MT3
1511 static inline auto selectLargeSubAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
1512 -> EnableIf_t< UseDefaultKernel_v<MT3,MT4,MT5> >
1514 selectDefaultSubAssignKernel( C, A, B );
1534 template<
typename MT3
1537 static inline auto selectLargeSubAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
1538 -> EnableIf_t< UseOptimizedKernel_v<MT3,MT4,MT5> >
1542 const ForwardFunctor fwd;
1544 const OppositeType_t<MT4> tmp(
serial( A ) );
1545 subAssign( C, fwd( tmp * B ) );
1565 template<
typename MT
1567 friend inline auto subAssign( Matrix<MT,SO>& lhs,
const TSMatDMatMultExpr& rhs )
1568 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
1577 const ForwardFunctor fwd;
1579 subAssign( ~lhs, fwd(
trans( rhs.lhs_ ) * rhs.rhs_ ) );
1601 template<
typename MT
1603 friend inline void schurAssign( DenseMatrix<MT,SO>& lhs,
const TSMatDMatMultExpr& rhs )
1615 schurAssign( ~lhs, tmp );
1648 template<
typename MT
1651 -> EnableIf_t< IsEvaluationRequired_v<MT,MT1,MT2> >
1689 template<
typename MT
1692 -> EnableIf_t< IsEvaluationRequired_v<MT,MT1,MT2> >
1696 using TmpType = If_t< SO, OppositeType, ResultType >;
1708 const ForwardFunctor fwd;
1710 const TmpType tmp( rhs );
1731 template<
typename MT
1734 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
1741 const ForwardFunctor fwd;
1764 template<
typename MT
1767 -> EnableIf_t< IsEvaluationRequired_v<MT,MT1,MT2> >
1804 template<
typename MT
1807 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
1814 const ForwardFunctor fwd;
1841 template<
typename MT
1844 -> EnableIf_t< IsEvaluationRequired_v<MT,MT1,MT2> >
1881 template<
typename MT
1884 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
1891 const ForwardFunctor fwd;
1915 template<
typename MT
1981 template<
typename MT1
1984 IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > ) ||
1985 IsZero_v<MT1> >* =
nullptr >
1986 inline const TSMatDMatMultExpr<MT1,MT2,false,false,false,false>
1987 tsmatdmatmult(
const SparseMatrix<MT1,true>& lhs,
const DenseMatrix<MT2,false>& rhs )
1993 return TSMatDMatMultExpr<MT1,MT2,false,false,false,false>( ~lhs, ~rhs );
2013 template<
typename MT1
2015 , EnableIf_t< IsIdentity_v<MT1> &&
2016 IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > >* =
nullptr >
2018 tsmatdmatmult(
const SparseMatrix<MT1,true>& lhs,
const DenseMatrix<MT2,false>& rhs )
2045 template<
typename MT1
2047 , EnableIf_t< IsZero_v<MT1> >* =
nullptr >
2048 inline decltype(
auto)
2049 tsmatdmatmult( const SparseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs )
2055 using ReturnType =
const MultTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
2060 return ReturnType( (~lhs).
rows(), (~rhs).
columns() );
2097 template<
typename MT1
2099 inline decltype(
auto)
2108 return tsmatdmatmult( ~lhs, ~rhs );
2147 template<
typename MT1
2153 inline decltype(
auto)
declsym( const TSMatDMatMultExpr<MT1,MT2,SF,HF,LF,UF>& dm )
2161 using ReturnType =
const TSMatDMatMultExpr<MT1,MT2,true,HF,LF,UF>;
2162 return ReturnType( dm.leftOperand(), dm.rightOperand() );
2194 template<
typename MT1
2200 inline decltype(
auto)
declherm( const TSMatDMatMultExpr<MT1,MT2,SF,HF,LF,UF>& dm )
2208 using ReturnType =
const TSMatDMatMultExpr<MT1,MT2,SF,true,LF,UF>;
2209 return ReturnType( dm.leftOperand(), dm.rightOperand() );
2241 template<
typename MT1
2247 inline decltype(
auto)
decllow( const TSMatDMatMultExpr<MT1,MT2,SF,HF,LF,UF>& dm )
2255 using ReturnType =
const TSMatDMatMultExpr<MT1,MT2,SF,HF,true,UF>;
2256 return ReturnType( dm.leftOperand(), dm.rightOperand() );
2288 template<
typename MT1
2294 inline decltype(
auto)
declupp( const TSMatDMatMultExpr<MT1,MT2,SF,HF,LF,UF>& dm )
2302 using ReturnType =
const TSMatDMatMultExpr<MT1,MT2,SF,HF,LF,true>;
2303 return ReturnType( dm.leftOperand(), dm.rightOperand() );
2335 template<
typename MT1
2341 inline decltype(
auto)
decldiag( const TSMatDMatMultExpr<MT1,MT2,SF,HF,LF,UF>& dm )
2349 using ReturnType =
const TSMatDMatMultExpr<MT1,MT2,SF,HF,true,true>;
2350 return ReturnType( dm.leftOperand(), dm.rightOperand() );
2366 template<
typename MT1,
typename MT2,
bool SF,
bool HF,
bool LF,
bool UF >
2367 struct Size< TSMatDMatMultExpr<MT1,MT2,SF,HF,LF,UF>, 0UL >
2368 :
public Size<MT1,0UL>
2371 template<
typename MT1,
typename MT2,
bool SF,
bool HF,
bool LF,
bool UF >
2372 struct Size< TSMatDMatMultExpr<MT1,MT2,SF,HF,LF,UF>, 1UL >
2373 :
public Size<MT2,1UL>
2389 template<
typename MT1,
typename MT2,
bool SF,
bool HF,
bool LF,
bool UF >
2390 struct IsAligned< TSMatDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2391 :
public IsAligned<MT2>
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatDMatMultExpr.h:247
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Header file for auxiliary alias declarations.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:133
Headerfile for the generic min algorithm.
Header file for the blaze::checked and blaze::unchecked instances.
Header file for the decldiag trait.
decltype(auto) decldiag(const DenseMatrix< MT, SO > &dm)
Declares the given dense matrix expression dm as diagonal.
Definition: DMatDeclDiagExpr.h:975
If_t< IsExpression_v< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: TSMatDMatMultExpr.h:257
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: TSMatDMatMultExpr.h:425
Header file for basic type definitions.
typename If< Condition, T1, T2 >::Type If_t
Auxiliary alias template for the If class template.The If_t alias template provides a convenient shor...
Definition: If.h:109
Header file for the declherm trait.
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.The ResultType_t alias declaration provides ...
Definition: Aliases.h:390
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatDMatMultExpr.h:296
Header file for the serial shim.
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: TSMatDMatMultExpr.h:371
Header file for the IsDiagonal type trait.
Base template for the DeclUppTrait class.
Definition: DeclUppTrait.h:134
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type,...
Definition: DenseMatrix.h:61
Header file for the DeclUpp functor.
ResultType_t< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatDMatMultExpr.h:134
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: TSMatDMatMultExpr.h:442
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
Header file for the IsColumnMajorMatrix type trait.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:595
constexpr Unchecked unchecked
Global Unchecked instance.The blaze::unchecked instance is an optional token for the creation of view...
Definition: Check.h:138
Constraint on the data type.
decltype(auto) subvector(Vector< VT, TF > &, RSAs...)
Creating a view on a specific subvector of the given vector.
Definition: Subvector.h:154
Header file for the MAYBE_UNUSED function template.
Header file for the IsIdentity type trait.
If_t< evaluateLeft, const RT1, CT1 > LT
Type for the assignment of the left-hand side sparse matrix operand.
Definition: TSMatDMatMultExpr.h:260
static constexpr bool SYM
Flag for symmetric matrices.
Definition: TSMatDMatMultExpr.h:153
decltype(auto) declupp(const DenseMatrix< MT, SO > &dm)
Declares the given dense matrix expression dm as upper.
Definition: DMatDeclUppExpr.h:1001
CompositeType_t< MT2 > CT2
Composite type of the right-hand side dense matrix expression.
Definition: TSMatDMatMultExpr.h:139
static constexpr bool simdEnabled
Compilation switch for the expression template evaluation strategy.
Definition: TSMatDMatMultExpr.h:268
LeftOperand leftOperand() const noexcept
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatDMatMultExpr.h:381
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
Header file for the reset shim.
static constexpr bool evaluateRight
Compilation switch for the composite type of the right-hand side dense matrix expression.
Definition: TSMatDMatMultExpr.h:149
Constraints on the storage order of matrix types.
Header file for the RequiresEvaluation type trait.
System settings for performance optimizations.
If_t< IsExpression_v< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatDMatMultExpr.h:254
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: TSMatDMatMultExpr.h:361
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes....
Definition: DenseMatrix.h:81
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatDMatMultExpr.h:251
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes....
Definition: Forward.h:145
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
static constexpr bool UPP
Flag for upper matrices.
Definition: TSMatDMatMultExpr.h:156
static constexpr bool LOW
Flag for lower matrices.
Definition: TSMatDMatMultExpr.h:155
RightOperand rhs_
Right-hand side dense matrix of the multiplication expression.
Definition: TSMatDMatMultExpr.h:443
Constraint on the data type.
Constraint on the data type.
typename If_t< HERM, DeclHermTrait< MultTrait_t< RT1, RT2 > >, If_t< SYM, DeclSymTrait< MultTrait_t< RT1, RT2 > >, If_t< LOW, If_t< UPP, DeclDiagTrait< MultTrait_t< RT1, RT2 > >, DeclLowTrait< MultTrait_t< RT1, RT2 > > >, If_t< UPP, DeclUppTrait< MultTrait_t< RT1, RT2 > >, MultTrait< RT1, RT2 > > > > >::Type ResultType
Result type for expression template evaluations.
Definition: TSMatDMatMultExpr.h:245
Headerfile for the generic max algorithm.
Header file for the DisableIf class template.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the DeclLow functor.
Header file for the If class template.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: TSMatDMatMultExpr.h:271
#define BLAZE_CONSTRAINT_MUST_BE_ZERO_TYPE(T)
Constraint on the data type.In case the given data type T is not a zero vector or matrix type,...
Definition: Zero.h:61
ElementType_t< RT2 > ET2
Element type of the right-hand side sparse matrix expression.
Definition: TSMatDMatMultExpr.h:137
Generic wrapper for the decllow() function.
Definition: DeclLow.h:59
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:1162
Header file for the decllow trait.
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the DenseMatrix base class.
decltype(auto) decllow(const DenseMatrix< MT, SO > &dm)
Declares the given dense matrix expression dm as lower.
Definition: DMatDeclLowExpr.h:1001
Header file for the IsLower type trait.
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
Header file for the IsAligned type trait.
If_t< evaluateRight, const RT2, CT2 > RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: TSMatDMatMultExpr.h:263
Generic wrapper for the null function.
Definition: Noop.h:60
Header file for the IsTriangular type trait.
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: TSMatDMatMultExpr.h:345
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: TSMatDMatMultExpr.h:435
Base template for the DeclSymTrait class.
Definition: DeclSymTrait.h:134
Constraints on the storage order of matrix types.
Header file for the exception macros of the math module.
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:1198
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:438
Header file for the DeclDiag functor.
Constraint on the data type.
CompositeType_t< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatDMatMultExpr.h:138
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATMULTEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid matrix/matrix ...
Definition: MatMatMultExpr.h:103
RightOperand rightOperand() const noexcept
Returns the right-hand side dense matrix operand.
Definition: TSMatDMatMultExpr.h:391
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: TSMatDMatMultExpr.h:249
typename T::OppositeType OppositeType_t
Alias declaration for nested OppositeType type definitions.The OppositeType_t alias declaration provi...
Definition: Aliases.h:270
Header file for the conjugate shim.
Header file for the declupp trait.
ResultType_t< MT2 > RT2
Result type of the right-hand side dense matrix expression.
Definition: TSMatDMatMultExpr.h:135
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type,...
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
typename T::TransposeType TransposeType_t
Alias declaration for nested TransposeType type definitions.The TransposeType_t alias declaration pro...
Definition: Aliases.h:470
Header file for run time assertion macros.
Base template for the DeclHermTrait class.
Definition: DeclHermTrait.h:134
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.The CompositeType_t alias declaration pro...
Definition: Aliases.h:90
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: TSMatDMatMultExpr.h:248
Base template for the MultTrait class.
Definition: MultTrait.h:146
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) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:133
TSMatDMatMultExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the TSMatDMatMultExpr class.
Definition: TSMatDMatMultExpr.h:281
Header file for the IsZero type trait.
ElementType_t< RT1 > ET1
Element type of the left-hand side dense matrix expression.
Definition: TSMatDMatMultExpr.h:136
Header file for the declsym trait.
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:94
Header file for all forward declarations for expression class templates.
decltype(auto) declsym(const DenseMatrix< MT, SO > &dm)
Declares the given dense matrix expression dm as symmetric.
Definition: DMatDeclSymExpr.h:1002
Header file for the isDefault shim.
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
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
Constraint on the data type.
Constraints on the storage order of matrix types.
Generic wrapper for the declherm() function.
Definition: DeclHerm.h:59
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:808
Header file for the Noop functor.
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
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
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
#define BLAZE_CONSTRAINT_MATRICES_MUST_HAVE_SAME_STORAGE_ORDER(T1, T2)
Constraint on the data type.In case either of the two given data types T1 or T2 is not a matrix type ...
Definition: StorageOrder.h:84
Generic wrapper for the declupp() function.
Definition: DeclUpp.h:59
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSMatDMatMultExpr.h:250
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: TSMatDMatMultExpr.h:415
Base template for the DeclLowTrait class.
Definition: DeclLowTrait.h:134
decltype(auto) declherm(const DenseMatrix< MT, SO > &dm)
Declares the given dense matrix expression dm as Hermitian.
Definition: DMatDeclHermExpr.h:1002
Header file for the IsRowMajorMatrix type trait.
Header file for the IsComputation type trait class.
Header file for the IsBuiltin type trait.
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
Expression object for transpose sparse matrix-dense matrix multiplications.The TSMatDMatMultExpr clas...
Definition: Forward.h:179
static constexpr bool evaluateLeft
Compilation switch for the composite type of the left-hand side sparse matrix expression.
Definition: TSMatDMatMultExpr.h:144
Header file for the IntegralConstant class template.
Generic wrapper for the decldiag() function.
Definition: DeclDiag.h:59
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: TSMatDMatMultExpr.h:403
Header file for the DeclHerm functor.
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:635
Header file for the IsUpper type trait.
typename DisableIf< Condition, T >::Type DisableIf_t
Auxiliary type for the DisableIf class template.The DisableIf_t alias declaration provides a convenie...
Definition: DisableIf.h:138
decltype(auto) conj(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the complex conjugate of each single element of dm.
Definition: DMatMapExpr.h:1324
Constraint on the data type.
Generic wrapper for the declsym() function.
Definition: DeclSym.h:59
Base template for the DeclDiagTrait class.
Definition: DeclDiagTrait.h:134
bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:951
static constexpr bool HERM
Flag for Hermitian matrices.
Definition: TSMatDMatMultExpr.h:154
Header file for the IsResizable type trait.
Header file for the Size type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_ZERO_TYPE(T)
Constraint on the data type.In case the given data type T is a zero vector or matrix type,...
Definition: Zero.h:81
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression,...
Definition: Assert.h:101
Header file for the DeclSym functor.
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type,...
Definition: SparseMatrix.h:61
Header file for the IsExpression type trait class.
Header file for the function trace functionality.