35#ifndef _BLAZE_MATH_EXPRESSIONS_TSMATDMATMULTEXPR_H_
36#define _BLAZE_MATH_EXPRESSIONS_TSMATDMATMULTEXPR_H_
122template<
typename MT1
129 :
public MatMatMultExpr< DenseMatrix< TSMatDMatMultExpr<MT1,MT2,SF,HF,LF,UF>, false > >
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) );
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) );
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) );
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
1981template<
typename MT1
1984 IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > ) ||
1985 IsZero_v<MT1> >* =
nullptr >
1986inline 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 );
2013template<
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 )
2045template<
typename MT1
2047 , EnableIf_t< IsZero_v<MT1> >* =
nullptr >
2048inline 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() );
2097template<
typename MT1
2099inline decltype(
auto)
2104 if( (*lhs).columns() != (*rhs).rows() ) {
2108 return tsmatdmatmult( *lhs, *rhs );
2147template<
typename MT1
2153inline 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() );
2194template<
typename MT1
2200inline 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() );
2241template<
typename MT1
2247inline 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() );
2288template<
typename MT1
2293inline decltype(
auto)
declunilow(
const TSMatDMatMultExpr<MT1,MT2,SF,HF,false,UF>& dm )
2333template<
typename MT1
2338inline decltype(
auto)
declstrlow(
const TSMatDMatMultExpr<MT1,MT2,SF,HF,false,UF>& dm )
2378template<
typename MT1
2384inline decltype(
auto)
declupp(
const TSMatDMatMultExpr<MT1,MT2,SF,HF,LF,UF>& dm )
2392 using ReturnType =
const TSMatDMatMultExpr<MT1,MT2,SF,HF,LF,true>;
2393 return ReturnType( dm.leftOperand(), dm.rightOperand() );
2425template<
typename MT1
2430inline decltype(
auto)
decluniupp(
const TSMatDMatMultExpr<MT1,MT2,SF,HF,LF,false>& dm )
2470template<
typename MT1
2475inline decltype(
auto)
declstrupp(
const TSMatDMatMultExpr<MT1,MT2,SF,HF,LF,false>& dm )
2515template<
typename MT1
2521inline decltype(
auto)
decldiag(
const TSMatDMatMultExpr<MT1,MT2,SF,HF,LF,UF>& dm )
2529 using ReturnType =
const TSMatDMatMultExpr<MT1,MT2,SF,HF,true,true>;
2530 return ReturnType( dm.leftOperand(), dm.rightOperand() );
2546template<
typename MT1,
typename MT2,
bool SF,
bool HF,
bool LF,
bool UF >
2547struct Size< TSMatDMatMultExpr<MT1,MT2,SF,HF,LF,UF>, 0UL >
2548 :
public Size<MT1,0UL>
2551template<
typename MT1,
typename MT2,
bool SF,
bool HF,
bool LF,
bool UF >
2552struct Size< TSMatDMatMultExpr<MT1,MT2,SF,HF,LF,UF>, 1UL >
2553 :
public Size<MT2,1UL>
2569template<
typename MT1,
typename MT2,
bool SF,
bool HF,
bool LF,
bool UF >
2570struct IsAligned< TSMatDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2571 :
public IsAligned<MT2>
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 conjugate shim.
Header file for the decldiag trait.
Header file for the DeclDiag functor.
Header file for the declherm trait.
Header file for the DeclHerm functor.
Header file for the decllow trait.
Header file for the DeclLow functor.
Header file for the declsym trait.
Header file for the DeclSym functor.
Header file for the declupp trait.
Header file for the DeclUpp functor.
Header file for the EnableIf class template.
Header file for the function trace functionality.
Header file for the If class template.
Header file for the IntegralConstant class template.
Header file for the IsAligned type trait.
Header file for the IsBuiltin type trait.
Header file for the IsColumnMajorMatrix type trait.
Header file for the IsComputation type trait class.
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 Noop functor.
Header file for the prevMultiple shim.
Constraints on the storage order of matrix types.
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-dense matrix multiplications.
Definition: TSMatDMatMultExpr.h:131
CompositeType_t< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatDMatMultExpr.h:138
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: TSMatDMatMultExpr.h:425
TSMatDMatMultExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the TSMatDMatMultExpr class.
Definition: TSMatDMatMultExpr.h:281
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatDMatMultExpr.h:251
static constexpr bool HERM
Flag for Hermitian matrices.
Definition: TSMatDMatMultExpr.h:154
static constexpr bool UPP
Flag for upper matrices.
Definition: TSMatDMatMultExpr.h:156
ResultType_t< MT2 > RT2
Result type of the right-hand side dense matrix expression.
Definition: TSMatDMatMultExpr.h:135
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: TSMatDMatMultExpr.h:415
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: TSMatDMatMultExpr.h:345
ResultType_t< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatDMatMultExpr.h:134
RightOperand rightOperand() const noexcept
Returns the right-hand side dense matrix operand.
Definition: TSMatDMatMultExpr.h:391
CompositeType_t< MT2 > CT2
Composite type of the right-hand side dense matrix expression.
Definition: TSMatDMatMultExpr.h:139
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: TSMatDMatMultExpr.h:249
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: TSMatDMatMultExpr.h:248
static constexpr bool simdEnabled
Compilation switch for the expression template evaluation strategy.
Definition: TSMatDMatMultExpr.h:268
static constexpr bool evaluateLeft
Compilation switch for the composite type of the left-hand side sparse matrix expression.
Definition: TSMatDMatMultExpr.h:144
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: TSMatDMatMultExpr.h:403
ElementType_t< RT1 > ET1
Element type of the left-hand side dense matrix expression.
Definition: TSMatDMatMultExpr.h:136
RightOperand rhs_
Right-hand side dense matrix of the multiplication expression.
Definition: TSMatDMatMultExpr.h:443
If_t< IsExpression_v< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: TSMatDMatMultExpr.h:257
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
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: TSMatDMatMultExpr.h:361
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 smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: TSMatDMatMultExpr.h:271
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatDMatMultExpr.h:296
static constexpr bool evaluateRight
Compilation switch for the composite type of the right-hand side dense matrix expression.
Definition: TSMatDMatMultExpr.h:149
static constexpr bool SYM
Flag for symmetric matrices.
Definition: TSMatDMatMultExpr.h:153
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: TSMatDMatMultExpr.h:371
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatDMatMultExpr.h:247
If_t< evaluateRight, const RT2, CT2 > RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: TSMatDMatMultExpr.h:263
LeftOperand leftOperand() const noexcept
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatDMatMultExpr.h:381
static constexpr bool LOW
Flag for lower matrices.
Definition: TSMatDMatMultExpr.h:155
ElementType_t< RT2 > ET2
Element type of the right-hand side sparse matrix expression.
Definition: TSMatDMatMultExpr.h:137
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: TSMatDMatMultExpr.h:435
If_t< IsExpression_v< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatDMatMultExpr.h:254
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: TSMatDMatMultExpr.h:442
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSMatDMatMultExpr.h:250
Constraint on the data type.
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 DenseMatrix base class.
Header file for the MatMatMultExpr 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) declstrupp(const DenseMatrix< MT, SO > &dm)
Declares the given dense matrix expression dm as strictly upper.
Definition: DMatDeclStrUppExpr.h:1003
decltype(auto) conj(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the complex conjugate of each single element of dm.
Definition: DMatMapExpr.h:1464
decltype(auto) decldiag(const DenseMatrix< MT, SO > &dm)
Declares the given dense matrix expression dm as diagonal.
Definition: DMatDeclDiagExpr.h:978
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:766
decltype(auto) declstrlow(const DenseMatrix< MT, SO > &dm)
Declares the given dense matrix expression dm as strictly lower.
Definition: DMatDeclStrLowExpr.h:1003
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:812
decltype(auto) declupp(const DenseMatrix< MT, SO > &dm)
Declares the given dense matrix expression dm as upper.
Definition: DMatDeclUppExpr.h:1004
decltype(auto) decllow(const DenseMatrix< MT, SO > &dm)
Declares the given dense matrix expression dm as lower.
Definition: DMatDeclLowExpr.h:1004
decltype(auto) decluniupp(const DenseMatrix< MT, SO > &dm)
Declares the given dense matrix expression dm as uniupper.
Definition: DMatDeclUniUppExpr.h:1005
decltype(auto) declherm(const DenseMatrix< MT, SO > &dm)
Declares the given dense matrix expression dm as Hermitian.
Definition: DMatDeclHermExpr.h:1005
decltype(auto) declsym(const DenseMatrix< MT, SO > &dm)
Declares the given dense matrix expression dm as symmetric.
Definition: DMatDeclSymExpr.h:1005
decltype(auto) declunilow(const DenseMatrix< MT, SO > &dm)
Declares the given dense matrix expression dm as unilower.
Definition: DMatDeclUniLowExpr.h:1004
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_MATRICES_MUST_HAVE_SAME_STORAGE_ORDER(T1, T2)
Constraint on the data type.
Definition: StorageOrder.h:84
#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_DENSE_MATRIX_TYPE(T)
Constraint on the data type.
Definition: DenseMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.
Definition: SparseMatrix.h:61
#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
BLAZE_ALWAYS_INLINE constexpr auto prevMultiple(T1 value, T2 factor) noexcept
Rounds down an integral value to the previous multiple of a given factor.
Definition: PrevMultiple.h:68
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
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:676
bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:1383
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 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.
Constraints on the storage order of matrix types.
Header file for all forward declarations for expression class templates.
Header file for the Size type trait.
Header file for the reset shim.
Header file for the serial shim.
Base class for all compute expression templates.
Definition: Computation.h:68
Base template for the DeclDiagTrait class.
Definition: DeclDiagTrait.h:127
Generic wrapper for the decldiag() function.
Definition: DeclDiag.h:61
Base template for the DeclHermTrait class.
Definition: DeclHermTrait.h:126
Generic wrapper for the declherm() function.
Definition: DeclHerm.h:61
Base template for the DeclLowTrait class.
Definition: DeclLowTrait.h:126
Generic wrapper for the decllow() function.
Definition: DeclLow.h:61
Base template for the DeclSymTrait class.
Definition: DeclSymTrait.h:126
Generic wrapper for the declsym() function.
Definition: DeclSym.h:61
Base template for the DeclUppTrait class.
Definition: DeclUppTrait.h:126
Generic wrapper for the declupp() function.
Definition: DeclUpp.h:61
Base class for all matrix/matrix multiplication expression templates.
Definition: MatMatMultExpr.h:71
Base template for the MultTrait class.
Definition: MultTrait.h:130
Generic wrapper for the null function.
Definition: Noop.h:62
System settings for performance optimizations.
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.