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
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> >;
1989 return ReturnType( (~lhs).
rows(), (~rhs).
columns() );
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>
#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 template for the If class template.The If_t alias template provides a convenient shor...
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:595
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.
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.
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:1001
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.
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:81
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: 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:59
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: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.
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:1001
Header file for the IsLower type trait.
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
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:136
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatTDMatMultExpr.h:237
Generic wrapper for the null function.
Definition: Noop.h:60
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: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.
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
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
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:59
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:59
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:59
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: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
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.
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatTDMatMultExpr.h:331