35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATTDMATMULTEXPR_H_ 36 #define _BLAZE_MATH_EXPRESSIONS_SMATTDMATMULTEXPR_H_ 118 template<
typename MT1
124 class SMatTDMatMultExpr
125 :
public MatMatMultExpr< DenseMatrix< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF>, true > >
126 ,
private Computation
140 static constexpr
bool evaluateLeft = ( IsComputation_v<MT1> || RequiresEvaluation_v<MT1> );
145 static constexpr
bool evaluateRight = ( IsComputation_v<MT2> || RequiresEvaluation_v<MT2> );
149 static constexpr
bool SYM = ( SF && !( HF || LF || UF ) );
150 static constexpr
bool HERM = ( HF && !( LF || UF ) );
151 static constexpr
bool LOW = ( LF || ( ( SF || HF ) && UF ) );
152 static constexpr
bool UPP = ( UF || ( ( SF || HF ) && LF ) );
162 template<
typename T1,
typename T2,
typename T3 >
163 static constexpr
bool CanExploitSymmetry_v = IsSymmetric_v<T3>;
173 template<
typename T1,
typename T2,
typename T3 >
174 static constexpr
bool IsEvaluationRequired_v =
184 template<
typename T1,
typename T2,
typename T3 >
185 static constexpr
bool UseOptimizedKernel_v =
186 ( useOptimizedKernels &&
188 !IsResizable_v< ElementType_t<T1> > &&
189 !IsResizable_v<ET1> );
286 if( IsDiagonal_v<MT1> ) {
289 else if( IsDiagonal_v<MT2> ) {
292 else if( IsTriangular_v<MT1> || IsTriangular_v<MT2> ) {
293 const size_t begin( ( IsUpper_v<MT1> )
294 ?( ( IsLower_v<MT2> )
295 ?(
max( ( IsStrictlyUpper_v<MT1> ? i+1UL : i )
296 , ( IsStrictlyLower_v<MT2> ? j+1UL : j ) ) )
297 :( IsStrictlyUpper_v<MT1> ? i+1UL : i ) )
298 :( ( IsLower_v<MT2> )
299 ?( IsStrictlyLower_v<MT2> ? j+1UL : j )
301 const size_t end( ( IsLower_v<MT1> )
302 ?( ( IsUpper_v<MT2> )
303 ?(
min( ( IsStrictlyLower_v<MT1> ? i : i+1UL )
304 , ( IsStrictlyUpper_v<MT2> ? j : j+1UL ) ) )
305 :( IsStrictlyLower_v<MT1> ? i : i+1UL ) )
306 :( ( IsUpper_v<MT2> )
307 ?( IsStrictlyUpper_v<MT2> ? j : j+1UL )
308 :(
lhs_.columns() ) ) );
332 if( i >=
lhs_.rows() ) {
335 if( j >=
rhs_.columns() ) {
347 inline size_t rows() const noexcept {
358 return rhs_.columns();
388 template<
typename T >
389 inline bool canAlias(
const T* alias )
const noexcept {
390 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
400 template<
typename T >
401 inline bool isAliased(
const T* alias )
const noexcept {
402 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
412 return rhs_.isAligned();
422 return (
rows() *
columns() >= SMP_SMATTDMATMULT_THRESHOLD ) && !IsDiagonal_v<MT2>;
445 template<
typename MT
465 SMatTDMatMultExpr::selectAssignKernel( ~lhs, A, B );
484 template<
typename MT3
487 static inline auto selectAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
490 const size_t M( A.rows() );
491 const size_t N( B.columns() );
498 for( ; (j+4UL) <= N; j+=4UL ) {
499 for(
size_t i=(
SYM ||
HERM ||
LOW ? j : 0UL ); i<(
UPP ? j+4UL : M ); ++i )
501 const auto end( ( IsUpper_v<MT5> )
502 ?( IsStrictlyUpper_v<MT5> ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
504 auto element( ( IsLower_v<MT5> )
505 ?( IsStrictlyLower_v<MT5> ? A.upperBound(i,j) : A.lowerBound(i,j) )
508 if( element ==
end ) {
516 C(i,j ) = element->value() * B(element->index(),j );
517 C(i,j+1UL) = element->value() * B(element->index(),j+1UL);
518 C(i,j+2UL) = element->value() * B(element->index(),j+2UL);
519 C(i,j+3UL) = element->value() * B(element->index(),j+3UL);
521 for( ; element!=
end; ++element ) {
522 C(i,j ) += element->value() * B(element->index(),j );
523 C(i,j+1UL) += element->value() * B(element->index(),j+1UL);
524 C(i,j+2UL) += element->value() * B(element->index(),j+2UL);
525 C(i,j+3UL) += element->value() * B(element->index(),j+3UL);
530 for( ; (j+2UL) <= N; j+=2UL ) {
531 for(
size_t i=(
SYM ||
HERM ||
LOW ? j : 0UL ); i<(
UPP ? j+2UL : M ); ++i )
533 const auto end( ( IsUpper_v<MT5> )
534 ?( IsStrictlyUpper_v<MT5> ? A.lowerBound(i,j+2UL) : A.upperBound(i,j+2UL) )
536 auto element( ( IsLower_v<MT5> )
537 ?( IsStrictlyLower_v<MT5> ? A.upperBound(i,j) : A.lowerBound(i,j) )
540 if( element ==
end ) {
546 C(i,j ) = element->value() * B(element->index(),j );
547 C(i,j+1UL) = element->value() * B(element->index(),j+1UL);
549 for( ; element!=
end; ++element ) {
550 C(i,j ) += element->value() * B(element->index(),j );
551 C(i,j+1UL) += element->value() * B(element->index(),j+1UL);
557 for(
size_t i=(
SYM ||
HERM ||
LOW ? j : 0UL ); i<(
UPP ? j+1UL : M ); ++i )
559 const auto end( ( IsUpper_v<MT5> )
560 ?( IsStrictlyUpper_v<MT5> ? A.lowerBound(i,j) : A.upperBound(i,j) )
562 auto element( ( IsLower_v<MT5> )
563 ?( IsStrictlyLower_v<MT5> ? A.upperBound(i,j) : A.lowerBound(i,j) )
566 if( element ==
end ) {
571 C(i,j) = element->value() * B(element->index(),j);
573 for( ; element!=
end; ++element ) {
574 C(i,j) += element->value() * B(element->index(),j);
581 for(
size_t j=1UL; j<N; ++j ) {
582 for(
size_t i=0UL; i<j; ++i ) {
583 C(i,j) =
HERM ?
conj( C(j,i) ) : C(j,i);
588 for(
size_t j=1UL; j<N; ++j ) {
589 for(
size_t i=0UL; i<j; ++i ) {
595 for(
size_t i=1UL; i<M; ++i ) {
596 for(
size_t j=0UL; j<i; ++j ) {
619 template<
typename MT3
622 static inline auto selectAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
623 -> EnableIf_t< UseOptimizedKernel_v<MT3,MT4,MT5> >
625 const size_t M( A.rows() );
626 const size_t N( B.columns() );
635 for( ; (j+4UL) <= N; j+=4UL ) {
636 for(
size_t i=(
SYM ||
HERM ||
LOW ? j : 0UL ); i<(
UPP ? j+4UL : M ); ++i )
638 const auto end( ( IsUpper_v<MT5> )
639 ?( IsStrictlyUpper_v<MT5> ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
641 auto element( ( IsLower_v<MT5> )
642 ?( IsStrictlyLower_v<MT5> ? A.upperBound(i,j) : A.lowerBound(i,j) )
645 const size_t nonzeros(
end - element );
646 const size_t kpos( nonzeros &
size_t(-4) );
649 for(
size_t k=0UL; k<kpos; k+=4UL )
651 const size_t i1( element->index() );
652 const ET1 v1( element->value() );
654 const size_t i2( element->index() );
655 const ET1 v2( element->value() );
657 const size_t i3( element->index() );
658 const ET1 v3( element->value() );
660 const size_t i4( element->index() );
661 const ET1 v4( element->value() );
666 C(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
667 C(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
668 C(i,j+2UL) += v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
669 C(i,j+3UL) += v1 * B(i1,j+3UL) + v2 * B(i2,j+3UL) + v3 * B(i3,j+3UL) + v4 * B(i4,j+3UL);
672 for( ; element!=
end; ++element )
674 const size_t i1( element->index() );
675 const ET1 v1( element->value() );
677 C(i,j ) += v1 * B(i1,j );
678 C(i,j+1UL) += v1 * B(i1,j+1UL);
679 C(i,j+2UL) += v1 * B(i1,j+2UL);
680 C(i,j+3UL) += v1 * B(i1,j+3UL);
685 for( ; (j+2UL) <= N; j+=2UL ) {
686 for(
size_t i=(
SYM ||
HERM ||
LOW ? j : 0UL ); i<(
UPP ? j+2UL : M ); ++i )
688 const auto end( ( IsUpper_v<MT5> )
689 ?( IsStrictlyUpper_v<MT5> ? A.lowerBound(i,j+2UL) : A.upperBound(i,j+2UL) )
691 auto element( ( IsLower_v<MT5> )
692 ?( IsStrictlyLower_v<MT5> ? A.upperBound(i,j) : A.lowerBound(i,j) )
695 const size_t nonzeros(
end - element );
696 const size_t kpos( nonzeros &
size_t(-4) );
699 for(
size_t k=0UL; k<kpos; k+=4UL )
701 const size_t i1( element->index() );
702 const ET1 v1( element->value() );
704 const size_t i2( element->index() );
705 const ET1 v2( element->value() );
707 const size_t i3( element->index() );
708 const ET1 v3( element->value() );
710 const size_t i4( element->index() );
711 const ET1 v4( element->value() );
716 C(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
717 C(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
720 for( ; element!=
end; ++element )
722 const size_t i1( element->index() );
723 const ET1 v1( element->value() );
725 C(i,j ) += v1 * B(i1,j );
726 C(i,j+1UL) += v1 * B(i1,j+1UL);
732 for(
size_t i=(
SYM ||
HERM ||
LOW ? j : 0UL ); i<(
UPP ? j+1UL : M ); ++i )
734 const auto end( ( IsUpper_v<MT5> )
735 ?( IsStrictlyUpper_v<MT5> ? A.lowerBound(i,j) : A.upperBound(i,j) )
737 auto element( ( IsLower_v<MT5> )
738 ?( IsStrictlyLower_v<MT5> ? A.upperBound(i,j) : A.lowerBound(i,j) )
741 const size_t nonzeros(
end - element );
742 const size_t kpos( nonzeros &
size_t(-4) );
745 for(
size_t k=0UL; k<kpos; k+=4UL )
747 const size_t i1( element->index() );
748 const ET1 v1( element->value() );
750 const size_t i2( element->index() );
751 const ET1 v2( element->value() );
753 const size_t i3( element->index() );
754 const ET1 v3( element->value() );
756 const size_t i4( element->index() );
757 const ET1 v4( element->value() );
762 C(i,j) += v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
765 for( ; element!=
end; ++element )
767 const size_t i1( element->index() );
768 const ET1 v1( element->value() );
770 C(i,j) += v1 * B(i1,j);
777 for(
size_t j=1UL; j<N; ++j ) {
778 for(
size_t i=0UL; i<j; ++i ) {
779 C(i,j) =
HERM ?
conj( C(j,i) ) : C(j,i);
800 template<
typename MT
802 friend inline auto assign( SparseMatrix<MT,SO>& lhs,
const SMatTDMatMultExpr& rhs )
803 -> DisableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
807 using TmpType = If_t< SO, ResultType, OppositeType >;
819 const ForwardFunctor fwd;
821 const TmpType tmp(
serial( rhs ) );
822 assign( ~lhs, fwd( tmp ) );
842 template<
typename MT
845 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
852 const ForwardFunctor fwd;
854 assign( ~lhs, fwd( rhs.lhs_ *
trans( rhs.rhs_ ) ) );
872 template<
typename MT
874 friend inline auto addAssign( DenseMatrix<MT,SO>& lhs,
const SMatTDMatMultExpr& rhs )
875 -> DisableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
892 SMatTDMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
911 template<
typename MT3
914 static inline auto selectAddAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
915 -> DisableIf_t< UseOptimizedKernel_v<MT3,MT4,MT5> >
917 const size_t M( A.rows() );
918 const size_t N( B.columns() );
925 for( ; (j+4UL) <= N; j+=4UL ) {
926 for(
size_t i=(
LOW ? j : 0UL ); i<(
UPP ? j+4UL : M ); ++i )
928 const auto end( ( IsUpper_v<MT5> )
929 ?( IsStrictlyUpper_v<MT5> ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
931 auto element( ( IsLower_v<MT5> )
932 ?( IsStrictlyLower_v<MT5> ? A.upperBound(i,j) : A.lowerBound(i,j) )
935 for( ; element!=
end; ++element ) {
936 C(i,j ) += element->value() * B(element->index(),j );
937 C(i,j+1UL) += element->value() * B(element->index(),j+1UL);
938 C(i,j+2UL) += element->value() * B(element->index(),j+2UL);
939 C(i,j+3UL) += element->value() * B(element->index(),j+3UL);
944 for( ; (j+2UL) <= N; j+=2UL ) {
945 for(
size_t i=(
LOW ? j : 0UL ); i<(
UPP ? j+2UL : M ); ++i )
947 const auto end( ( IsUpper_v<MT5> )
948 ?( IsStrictlyUpper_v<MT5> ? A.lowerBound(i,j+2UL) : A.upperBound(i,j+2UL) )
950 auto element( ( IsLower_v<MT5> )
951 ?( IsStrictlyLower_v<MT5> ? A.upperBound(i,j) : A.lowerBound(i,j) )
954 for( ; element!=
end; ++element ) {
955 C(i,j ) += element->value() * B(element->index(),j );
956 C(i,j+1UL) += element->value() * B(element->index(),j+1UL);
962 for(
size_t i=(
LOW ? j : 0UL ); i<(
UPP ? j+1UL : M ); ++i )
964 const auto end( ( IsUpper_v<MT5> )
965 ?( IsStrictlyUpper_v<MT5> ? A.lowerBound(i,j) : A.upperBound(i,j) )
967 auto element( ( IsLower_v<MT5> )
968 ?( IsStrictlyLower_v<MT5> ? A.upperBound(i,j) : A.lowerBound(i,j) )
971 for( ; element!=
end; ++element ) {
972 C(i,j) += element->value() * B(element->index(),j);
995 template<
typename MT3
998 static inline auto selectAddAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
999 -> EnableIf_t< UseOptimizedKernel_v<MT3,MT4,MT5> >
1001 const size_t M( A.rows() );
1002 const size_t N( B.columns() );
1009 for( ; (j+4UL) <= N; j+=4UL ) {
1010 for(
size_t i=(
LOW ? j : 0UL ); i<(
UPP ? j+4UL : M ); ++i )
1012 const auto end( ( IsUpper_v<MT5> )
1013 ?( IsStrictlyUpper_v<MT5> ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
1015 auto element( ( IsLower_v<MT5> )
1016 ?( IsStrictlyLower_v<MT5> ? A.upperBound(i,j) : A.lowerBound(i,j) )
1019 const size_t nonzeros(
end - element );
1020 const size_t kpos( nonzeros &
size_t(-4) );
1023 for(
size_t k=0UL; k<kpos; k+=4UL )
1025 const size_t i1( element->index() );
1026 const ET1 v1( element->value() );
1028 const size_t i2( element->index() );
1029 const ET1 v2( element->value() );
1031 const size_t i3( element->index() );
1032 const ET1 v3( element->value() );
1034 const size_t i4( element->index() );
1035 const ET1 v4( element->value() );
1040 C(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
1041 C(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
1042 C(i,j+2UL) += v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
1043 C(i,j+3UL) += v1 * B(i1,j+3UL) + v2 * B(i2,j+3UL) + v3 * B(i3,j+3UL) + v4 * B(i4,j+3UL);
1046 for( ; element!=
end; ++element )
1048 const size_t i1( element->index() );
1049 const ET1 v1( element->value() );
1051 C(i,j ) += v1 * B(i1,j );
1052 C(i,j+1UL) += v1 * B(i1,j+1UL);
1053 C(i,j+2UL) += v1 * B(i1,j+2UL);
1054 C(i,j+3UL) += v1 * B(i1,j+3UL);
1059 for( ; (j+2UL) <= N; j+=2UL ) {
1060 for(
size_t i=(
LOW ? j : 0UL ); i<(
UPP ? j+2UL : M ); ++i )
1062 const auto end( ( IsUpper_v<MT5> )
1063 ?( IsStrictlyUpper_v<MT5> ? A.lowerBound(i,j+2UL) : A.upperBound(i,j+2UL) )
1065 auto element( ( IsLower_v<MT5> )
1066 ?( IsStrictlyLower_v<MT5> ? A.upperBound(i,j) : A.lowerBound(i,j) )
1069 const size_t nonzeros(
end - element );
1070 const size_t kpos( nonzeros &
size_t(-4) );
1073 for(
size_t k=0UL; k<kpos; k+=4UL )
1075 const size_t i1( element->index() );
1076 const ET1 v1( element->value() );
1078 const size_t i2( element->index() );
1079 const ET1 v2( element->value() );
1081 const size_t i3( element->index() );
1082 const ET1 v3( element->value() );
1084 const size_t i4( element->index() );
1085 const ET1 v4( element->value() );
1090 C(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
1091 C(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
1094 for( ; element!=
end; ++element )
1096 const size_t i1( element->index() );
1097 const ET1 v1( element->value() );
1099 C(i,j ) += v1 * B(i1,j );
1100 C(i,j+1UL) += v1 * B(i1,j+1UL);
1106 for(
size_t i=(
LOW ? j : 0UL ); i<(
UPP ? j+1UL : M ); ++i )
1108 const auto end( ( IsUpper_v<MT5> )
1109 ?( IsStrictlyUpper_v<MT5> ? A.lowerBound(i,j) : A.upperBound(i,j) )
1111 auto element( ( IsLower_v<MT5> )
1112 ?( IsStrictlyLower_v<MT5> ? A.upperBound(i,j) : A.lowerBound(i,j) )
1115 const size_t nonzeros(
end - element );
1116 const size_t kpos( nonzeros &
size_t(-4) );
1119 for(
size_t k=0UL; k<kpos; k+=4UL )
1121 const size_t i1( element->index() );
1122 const ET1 v1( element->value() );
1124 const size_t i2( element->index() );
1125 const ET1 v2( element->value() );
1127 const size_t i3( element->index() );
1128 const ET1 v3( element->value() );
1130 const size_t i4( element->index() );
1131 const ET1 v4( element->value() );
1136 C(i,j) += v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
1139 for( ; element!=
end; ++element )
1141 const size_t i1( element->index() );
1142 const ET1 v1( element->value() );
1144 C(i,j) += v1 * B(i1,j);
1168 template<
typename MT
1170 friend inline auto addAssign( Matrix<MT,SO>& lhs,
const SMatTDMatMultExpr& rhs )
1171 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
1178 const ForwardFunctor fwd;
1180 addAssign( ~lhs, fwd( rhs.lhs_ *
trans( rhs.rhs_ ) ) );
1202 template<
typename MT
1204 friend inline auto subAssign( DenseMatrix<MT,SO>& lhs,
const SMatTDMatMultExpr& rhs )
1205 -> DisableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
1222 SMatTDMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
1241 template<
typename MT3
1244 static inline auto selectSubAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
1245 -> DisableIf_t< UseOptimizedKernel_v<MT3,MT4,MT5> >
1247 const size_t M( A.rows() );
1248 const size_t N( B.columns() );
1255 for( ; (j+4UL) <= N; j+=4UL ) {
1256 for(
size_t i=(
LOW ? j : 0UL ); i<(
UPP ? j+4UL : M ); ++i )
1258 const auto end( ( IsUpper_v<MT5> )
1259 ?( IsStrictlyUpper_v<MT5> ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
1261 auto element( ( IsLower_v<MT5> )
1262 ?( IsStrictlyLower_v<MT5> ? A.upperBound(i,j) : A.lowerBound(i,j) )
1265 for( ; element!=
end; ++element ) {
1266 C(i,j ) -= element->value() * B(element->index(),j );
1267 C(i,j+1UL) -= element->value() * B(element->index(),j+1UL);
1268 C(i,j+2UL) -= element->value() * B(element->index(),j+2UL);
1269 C(i,j+3UL) -= element->value() * B(element->index(),j+3UL);
1274 for( ; (j+2UL) <= N; j+=2UL ) {
1275 for(
size_t i=(
LOW ? j : 0UL ); i<(
UPP ? j+2UL : M ); ++i )
1277 const auto end( ( IsUpper_v<MT5> )
1278 ?( IsStrictlyUpper_v<MT5> ? A.lowerBound(i,j+2UL) : A.upperBound(i,j+2UL) )
1280 auto element( ( IsLower_v<MT5> )
1281 ?( IsStrictlyLower_v<MT5> ? A.upperBound(i,j) : A.lowerBound(i,j) )
1284 for( ; element!=
end; ++element ) {
1285 C(i,j ) -= element->value() * B(element->index(),j );
1286 C(i,j+1UL) -= element->value() * B(element->index(),j+1UL);
1292 for(
size_t i=(
LOW ? j : 0UL ); i<(
UPP ? j+1UL : M ); ++i )
1294 const auto end( ( IsUpper_v<MT5> )
1295 ?( IsStrictlyUpper_v<MT5> ? A.lowerBound(i,j) : A.upperBound(i,j) )
1297 auto element( ( IsLower_v<MT5> )
1298 ?( IsStrictlyLower_v<MT5> ? A.upperBound(i,j) : A.lowerBound(i,j) )
1301 for( ; element!=
end; ++element ) {
1302 C(i,j) -= element->value() * B(element->index(),j);
1325 template<
typename MT3
1328 static inline auto selectSubAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
1329 -> EnableIf_t< UseOptimizedKernel_v<MT3,MT4,MT5> >
1331 const size_t M( A.rows() );
1332 const size_t N( B.columns() );
1339 for( ; (j+4UL) <= N; j+=4UL ) {
1340 for(
size_t i=(
LOW ? j : 0UL ); i<(
UPP ? j+4UL : M ); ++i )
1342 const auto end( ( IsUpper_v<MT5> )
1343 ?( IsStrictlyUpper_v<MT5> ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
1345 auto element( ( IsLower_v<MT5> )
1346 ?( IsStrictlyLower_v<MT5> ? A.upperBound(i,j) : A.lowerBound(i,j) )
1349 const size_t nonzeros(
end - element );
1350 const size_t kpos( nonzeros &
size_t(-4) );
1353 for(
size_t k=0UL; k<kpos; k+=4UL )
1355 const size_t i1( element->index() );
1356 const ET1 v1( element->value() );
1358 const size_t i2( element->index() );
1359 const ET1 v2( element->value() );
1361 const size_t i3( element->index() );
1362 const ET1 v3( element->value() );
1364 const size_t i4( element->index() );
1365 const ET1 v4( element->value() );
1370 C(i,j ) -= v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
1371 C(i,j+1UL) -= v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
1372 C(i,j+2UL) -= v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
1373 C(i,j+3UL) -= v1 * B(i1,j+3UL) + v2 * B(i2,j+3UL) + v3 * B(i3,j+3UL) + v4 * B(i4,j+3UL);
1376 for( ; element!=
end; ++element )
1378 const size_t i1( element->index() );
1379 const ET1 v1( element->value() );
1381 C(i,j ) -= v1 * B(i1,j );
1382 C(i,j+1UL) -= v1 * B(i1,j+1UL);
1383 C(i,j+2UL) -= v1 * B(i1,j+2UL);
1384 C(i,j+3UL) -= v1 * B(i1,j+3UL);
1389 for( ; (j+2UL) <= N; j+=2UL ) {
1390 for(
size_t i=(
LOW ? j : 0UL ); i<(
UPP ? j+2UL : M ); ++i )
1392 const auto end( ( IsUpper_v<MT5> )
1393 ?( IsStrictlyUpper_v<MT5> ? A.lowerBound(i,j+2UL) : A.upperBound(i,j+2UL) )
1395 auto element( ( IsLower_v<MT5> )
1396 ?( IsStrictlyLower_v<MT5> ? A.upperBound(i,j) : A.lowerBound(i,j) )
1399 const size_t nonzeros(
end - element );
1400 const size_t kpos( nonzeros &
size_t(-4) );
1403 for(
size_t k=0UL; k<kpos; k+=4UL )
1405 const size_t i1( element->index() );
1406 const ET1 v1( element->value() );
1408 const size_t i2( element->index() );
1409 const ET1 v2( element->value() );
1411 const size_t i3( element->index() );
1412 const ET1 v3( element->value() );
1414 const size_t i4( element->index() );
1415 const ET1 v4( element->value() );
1420 C(i,j ) -= v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
1421 C(i,j+1UL) -= v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
1424 for( ; element!=
end; ++element )
1426 const size_t i1( element->index() );
1427 const ET1 v1( element->value() );
1429 C(i,j ) -= v1 * B(i1,j );
1430 C(i,j+1UL) -= v1 * B(i1,j+1UL);
1436 for(
size_t i=(
LOW ? j : 0UL ); i<(
UPP ? j+1UL : M ); ++i )
1438 const auto end( ( IsUpper_v<MT5> )
1439 ?( IsStrictlyUpper_v<MT5> ? A.lowerBound(i,j) : A.upperBound(i,j) )
1441 auto element( ( IsLower_v<MT5> )
1442 ?( IsStrictlyLower_v<MT5> ? A.upperBound(i,j) : A.lowerBound(i,j) )
1445 const size_t nonzeros(
end - element );
1446 const size_t kpos( nonzeros &
size_t(-4) );
1449 for(
size_t k=0UL; k<kpos; k+=4UL )
1451 const size_t i1( element->index() );
1452 const ET1 v1( element->value() );
1454 const size_t i2( element->index() );
1455 const ET1 v2( element->value() );
1457 const size_t i3( element->index() );
1458 const ET1 v3( element->value() );
1460 const size_t i4( element->index() );
1461 const ET1 v4( element->value() );
1466 C(i,j) -= v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
1469 for( ; element!=
end; ++element )
1471 const size_t i1( element->index() );
1472 const ET1 v1( element->value() );
1474 C(i,j) -= v1 * B(i1,j);
1498 template<
typename MT
1500 friend inline auto subAssign( Matrix<MT,SO>& lhs,
const SMatTDMatMultExpr& rhs )
1501 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
1508 const ForwardFunctor fwd;
1510 subAssign( ~lhs, fwd( rhs.lhs_ *
trans( rhs.rhs_ ) ) );
1532 template<
typename MT
1534 friend inline void schurAssign( DenseMatrix<MT,SO>& lhs,
const SMatTDMatMultExpr& rhs )
1546 schurAssign( ~lhs, tmp );
1578 template<
typename MT
1581 -> EnableIf_t< IsEvaluationRequired_v<MT,MT1,MT2> >
1618 template<
typename MT
1621 -> EnableIf_t< IsEvaluationRequired_v<MT,MT1,MT2> >
1625 using TmpType = If_t< SO, ResultType, OppositeType >;
1637 const ForwardFunctor fwd;
1639 const TmpType tmp( rhs );
1660 template<
typename MT
1663 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
1670 const ForwardFunctor fwd;
1693 template<
typename MT
1696 -> EnableIf_t< IsEvaluationRequired_v<MT,MT1,MT2> >
1733 template<
typename MT
1736 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
1743 const ForwardFunctor fwd;
1770 template<
typename MT
1773 -> EnableIf_t< IsEvaluationRequired_v<MT,MT1,MT2> >
1810 template<
typename MT
1813 -> EnableIf_t< CanExploitSymmetry_v<MT,MT1,MT2> >
1820 const ForwardFunctor fwd;
1844 template<
typename MT
1910 template<
typename MT1
1912 , DisableIf_t< ( IsIdentity_v<MT1> &&
1913 IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > ) ||
1914 IsZero_v<MT1> >* =
nullptr >
1915 inline const SMatTDMatMultExpr<MT1,MT2,false,false,false,false>
1916 smattdmatmult(
const SparseMatrix<MT1,false>& lhs,
const DenseMatrix<MT2,true>& rhs )
1922 return SMatTDMatMultExpr<MT1,MT2,false,false,false,false>( ~lhs, ~rhs );
1942 template<
typename MT1
1944 , EnableIf_t< IsIdentity_v<MT1> &&
1945 IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > >* =
nullptr >
1947 smattdmatmult(
const SparseMatrix<MT1,false>& lhs,
const DenseMatrix<MT2,true>& rhs )
1974 template<
typename MT1
1976 , EnableIf_t< IsZero_v<MT1> >* =
nullptr >
1977 inline decltype(
auto)
1978 smattdmatmult( const SparseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs )
1984 using ReturnType =
const MultTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
2026 template<
typename MT1
2028 inline decltype(
auto)
2037 return smattdmatmult( ~lhs, ~rhs );
2076 template<
typename MT1
2082 inline decltype(
auto)
declsym( const SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF>& dm )
2090 using ReturnType =
const SMatTDMatMultExpr<MT1,MT2,true,HF,LF,UF>;
2091 return ReturnType( dm.leftOperand(), dm.rightOperand() );
2123 template<
typename MT1
2129 inline decltype(
auto)
declherm( const SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF>& dm )
2137 using ReturnType =
const SMatTDMatMultExpr<MT1,MT2,SF,true,LF,UF>;
2138 return ReturnType( dm.leftOperand(), dm.rightOperand() );
2170 template<
typename MT1
2176 inline decltype(
auto)
decllow( const SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF>& dm )
2184 using ReturnType =
const SMatTDMatMultExpr<MT1,MT2,SF,HF,true,UF>;
2185 return ReturnType( dm.leftOperand(), dm.rightOperand() );
2217 template<
typename MT1
2223 inline decltype(
auto)
declupp( const SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF>& dm )
2231 using ReturnType =
const SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,true>;
2232 return ReturnType( dm.leftOperand(), dm.rightOperand() );
2264 template<
typename MT1
2270 inline decltype(
auto)
decldiag( const SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF>& dm )
2278 using ReturnType =
const SMatTDMatMultExpr<MT1,MT2,SF,HF,true,true>;
2279 return ReturnType( dm.leftOperand(), dm.rightOperand() );
2295 template<
typename MT1,
typename MT2,
bool SF,
bool HF,
bool LF,
bool UF >
2296 struct Size< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF>, 0UL >
2297 :
public Size<MT1,0UL>
2300 template<
typename MT1,
typename MT2,
bool SF,
bool HF,
bool LF,
bool UF >
2301 struct Size< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF>, 1UL >
2302 :
public Size<MT2,1UL>
2318 template<
typename MT1,
typename MT2,
bool SF,
bool HF,
bool LF,
bool UF >
2319 struct IsAligned< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2320 :
public IsAligned<MT2>
decltype(auto) subvector(Vector< VT, TF > &, RSAs...)
Creating a view on a specific subvector of the given vector.
Definition: Subvector.h:329
#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
Header file for basic type definitions.
const ElementType ReturnType
Return type for expression template evaluations.
Definition: SMatTDMatMultExpr.h:236
typename If< Condition, T1, T2 >::Type If_t
Auxiliary alias declaration for the If class template.The If_t alias declaration provides a convenien...
Definition: If.h:109
RightOperand rightOperand() const noexcept
Returns the right-hand side transpose dense matrix operand.
Definition: SMatTDMatMultExpr.h:377
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
static constexpr bool simdEnabled
Compilation switch for the expression template evaluation strategy.
Definition: SMatTDMatMultExpr.h:254
Header file for the serial shim.
ElementType_t< RT1 > ET1
Element type of the left-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:132
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.
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
If_t< IsExpression_v< MT1 >, const MT1, const MT1 &> LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:240
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:591
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: CompressedMatrix.h:3113
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SMatTDMatMultExpr.h:357
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.
Header file for the IsIdentity type trait.
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatTDMatMultExpr.h:233
decltype(auto) declupp(const DenseMatrix< MT, SO > &dm)
Declares the given dense matrix expression dm as upper.
Definition: DMatDeclUppExpr.h:1002
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SMatTDMatMultExpr.h:401
static constexpr bool evaluateRight
Compilation switch for the composite type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:145
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
Header file for the reset shim.
Constraints on the storage order of matrix types.
CompositeType_t< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:134
Header file for the RequiresEvaluation type trait.
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: SMatTDMatMultExpr.h:231
System settings for performance optimizations.
constexpr void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
static constexpr bool evaluateLeft
Compilation switch for the composite type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:140
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SMatTDMatMultExpr.h:347
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:137
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: SMatTDMatMultExpr.h:152
Constraint on the data type.
Constraint on the data type.
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SMatTDMatMultExpr.h:389
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: SMatTDMatMultExpr.h:235
Headerfile for the generic max algorithm.
static constexpr bool HERM
Flag for Hermitian matrices.
Definition: SMatTDMatMultExpr.h:150
Header file for the DisableIf class template.
static constexpr bool SYM
Flag for symmetric matrices.
Definition: SMatTDMatMultExpr.h:149
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
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: SMatTDMatMultExpr.h:421
#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
ResultType_t< MT2 > RT2
Result type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:131
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: SMatTDMatMultExpr.h:411
Generic wrapper for the decllow() function.
Definition: DeclLow.h:58
CompositeType_t< MT2 > CT2
Composite type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:135
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:1147
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.
If_t< evaluateLeft, const RT1, CT1 > LT
Type for the assignment of the left-hand side sparse matrix operand.
Definition: SMatTDMatMultExpr.h:246
decltype(auto) decllow(const DenseMatrix< MT, SO > &dm)
Declares the given dense matrix expression dm as lower.
Definition: DMatDeclLowExpr.h:1002
Header file for the IsLower type trait.
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: SMatTDMatMultExpr.h:428
Header file for the IsAligned type trait.
Expression object for sparse matrix-transpose dense matrix multiplications.The SMatTDMatMultExpr clas...
Definition: Forward.h:129
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatTDMatMultExpr.h:237
Generic wrapper for the null function.
Definition: Noop.h:59
Header file for the IsTriangular type trait.
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:1179
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.
Header file for all forward declarations for expression class templates.
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
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.
#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
static constexpr bool LOW
Flag for lower matrices.
Definition: SMatTDMatMultExpr.h:151
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
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
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: SMatTDMatMultExpr.h:257
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:133
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SMatTDMatMultExpr.h:234
Header file for the IsZero type trait.
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
decltype(auto) declsym(const DenseMatrix< MT, SO > &dm)
Declares the given dense matrix expression dm as symmetric.
Definition: DMatDeclSymExpr.h:1002
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
Constraints on the storage order of matrix types.
Generic wrapper for the declherm() function.
Definition: DeclHerm.h:58
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:808
SMatTDMatMultExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the SMatTDMatMultExpr class.
Definition: SMatTDMatMultExpr.h:267
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:58
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3081
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: SMatTDMatMultExpr.h:367
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 IsComputation type trait class.
RightOperand rhs_
Right-hand side dense matrix of the multiplication expression.
Definition: SMatTDMatMultExpr.h:429
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
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatTDMatMultExpr.h:282
ResultType_t< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:130
Header file for the IntegralConstant class template.
Generic wrapper for the decldiag() function.
Definition: DeclDiag.h:58
Header file for the DeclHerm functor.
If_t< evaluateRight, const RT2, CT2 > RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: SMatTDMatMultExpr.h:249
If_t< IsExpression_v< MT2 >, const MT2, const MT2 &> RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:243
ElementType_t< RT2 > ET2
Element type of the right-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:133
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:1326
Constraint on the data type.
Generic wrapper for the declsym() function.
Definition: DeclSym.h:58
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
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, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
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 TrueType type/value trait base class.
Header file for the IsExpression type trait class.
Header file for the function trace functionality.
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatTDMatMultExpr.h:331