35#ifndef _BLAZE_MATH_EXPRESSIONS_SMATTDMATMULTEXPR_H_
36#define _BLAZE_MATH_EXPRESSIONS_SMATTDMATMULTEXPR_H_
118template<
typename MT1
125 :
public MatMatMultExpr< DenseMatrix< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF>, true > >
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 );
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 );
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 );
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 );
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 );
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 );
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 );
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 );
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 );
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
1910template<
typename MT1
1913 IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > ) ||
1914 IsZero_v<MT1> >* =
nullptr >
1915inline 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 );
1942template<
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 )
1974template<
typename MT1
1976 , EnableIf_t< IsZero_v<MT1> >* =
nullptr >
1977inline 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() );
2026template<
typename MT1
2028inline decltype(
auto)
2033 if( (*lhs).columns() != (*rhs).rows() ) {
2037 return smattdmatmult( *lhs, *rhs );
2076template<
typename MT1
2082inline 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() );
2123template<
typename MT1
2129inline 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() );
2170template<
typename MT1
2176inline 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() );
2217template<
typename MT1
2222inline decltype(
auto)
declunilow(
const SMatTDMatMultExpr<MT1,MT2,SF,HF,false,UF>& dm )
2262template<
typename MT1
2267inline decltype(
auto)
declstrlow(
const SMatTDMatMultExpr<MT1,MT2,SF,HF,false,UF>& dm )
2307template<
typename MT1
2313inline decltype(
auto)
declupp(
const SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF>& dm )
2321 using ReturnType =
const SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,true>;
2322 return ReturnType( dm.leftOperand(), dm.rightOperand() );
2354template<
typename MT1
2359inline decltype(
auto)
decluniupp(
const SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,false>& dm )
2399template<
typename MT1
2404inline decltype(
auto)
declstrupp(
const SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,false>& dm )
2444template<
typename MT1
2450inline decltype(
auto)
decldiag(
const SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF>& dm )
2458 using ReturnType =
const SMatTDMatMultExpr<MT1,MT2,SF,HF,true,true>;
2459 return ReturnType( dm.leftOperand(), dm.rightOperand() );
2475template<
typename MT1,
typename MT2,
bool SF,
bool HF,
bool LF,
bool UF >
2476struct Size< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF>, 0UL >
2477 :
public Size<MT1,0UL>
2480template<
typename MT1,
typename MT2,
bool SF,
bool HF,
bool LF,
bool UF >
2481struct Size< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF>, 1UL >
2482 :
public Size<MT2,1UL>
2498template<
typename MT1,
typename MT2,
bool SF,
bool HF,
bool LF,
bool UF >
2499struct IsAligned< SMatTDMatMultExpr<MT1,MT2,SF,HF,LF,UF> >
2500 :
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 IsComputation type trait class.
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 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.
Base class for dense matrices.
Definition: DenseMatrix.h:82
Expression object for sparse matrix-transpose dense matrix multiplications.
Definition: SMatTDMatMultExpr.h:127
ElementType_t< RT1 > ET1
Element type of the left-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:132
CompositeType_t< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:134
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SMatTDMatMultExpr.h:234
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: SMatTDMatMultExpr.h:411
If_t< evaluateRight, const RT2, CT2 > RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: SMatTDMatMultExpr.h:249
static constexpr bool UPP
Flag for upper matrices.
Definition: SMatTDMatMultExpr.h:152
RightOperand rhs_
Right-hand side dense matrix of the multiplication expression.
Definition: SMatTDMatMultExpr.h:429
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: SMatTDMatMultExpr.h:428
If_t< IsExpression_v< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:243
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SMatTDMatMultExpr.h:389
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: SMatTDMatMultExpr.h:421
static constexpr bool evaluateRight
Compilation switch for the composite type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:145
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SMatTDMatMultExpr.h:401
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatTDMatMultExpr.h:282
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: SMatTDMatMultExpr.h:257
CompositeType_t< MT2 > CT2
Composite type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:135
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatTDMatMultExpr.h:237
static constexpr bool LOW
Flag for lower matrices.
Definition: SMatTDMatMultExpr.h:151
static constexpr bool HERM
Flag for Hermitian matrices.
Definition: SMatTDMatMultExpr.h:150
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatTDMatMultExpr.h:233
ElementType_t< RT2 > ET2
Element type of the right-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:133
static constexpr bool SYM
Flag for symmetric matrices.
Definition: SMatTDMatMultExpr.h:149
static constexpr bool simdEnabled
Compilation switch for the expression template evaluation strategy.
Definition: SMatTDMatMultExpr.h:254
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
If_t< evaluateLeft, const RT1, CT1 > LT
Type for the assignment of the left-hand side sparse matrix operand.
Definition: SMatTDMatMultExpr.h:246
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: SMatTDMatMultExpr.h:235
If_t< IsExpression_v< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:240
static constexpr bool evaluateLeft
Compilation switch for the composite type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:140
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatTDMatMultExpr.h:331
ResultType_t< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:130
ResultType_t< MT2 > RT2
Result type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:131
const ElementType ReturnType
Return type for expression template evaluations.
Definition: SMatTDMatMultExpr.h:236
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: SMatTDMatMultExpr.h:367
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SMatTDMatMultExpr.h:347
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SMatTDMatMultExpr.h:357
SMatTDMatMultExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the SMatTDMatMultExpr class.
Definition: SMatTDMatMultExpr.h:267
RightOperand rightOperand() const noexcept
Returns the right-hand side transpose dense matrix operand.
Definition: SMatTDMatMultExpr.h:377
Base class for sparse matrices.
Definition: SparseMatrix.h:77
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
#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
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.