35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATDMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATDMATMULTEXPR_H_
119 template<
typename MT1
121 class SMatDMatMultExpr :
public DenseMatrix< SMatDMatMultExpr<MT1,MT2>, false >
122 ,
private MatMatMultExpr
123 ,
private Computation
153 template<
typename T1,
typename T2,
typename T3 >
154 struct CanExploitSymmetry {
155 enum { value = IsColumnMajorMatrix<T1>::value &&
156 ( IsSymmetric<T2>::value || IsSymmetric<T3>::value ) };
167 template<
typename T1,
typename T2,
typename T3 >
168 struct IsEvaluationRequired {
169 enum { value = ( evaluateLeft || evaluateRight ) &&
170 !CanExploitSymmetry<T1,T2,T3>::value };
180 template<
typename T1,
typename T2,
typename T3 >
181 struct UseVectorizedKernel {
182 enum { value = !IsDiagonal<T3>::value &&
183 T1::vectorizable && T3::vectorizable &&
184 IsRowMajorMatrix<T1>::value &&
185 IsSame<typename T1::ElementType,typename T2::ElementType>::value &&
186 IsSame<typename T1::ElementType,typename T3::ElementType>::value &&
187 IntrinsicTrait<typename T1::ElementType>::addition &&
188 IntrinsicTrait<typename T1::ElementType>::subtraction &&
189 IntrinsicTrait<typename T1::ElementType>::multiplication };
200 template<
typename T1,
typename T2,
typename T3 >
201 struct UseOptimizedKernel {
202 enum { value = !UseVectorizedKernel<T1,T2,T3>::value &&
203 !IsDiagonal<T3>::value &&
204 !IsResizable<typename T1::ElementType>::value &&
205 !IsResizable<ET1>::value };
215 template<
typename T1,
typename T2,
typename T3 >
216 struct UseDefaultKernel {
217 enum { value = !UseVectorizedKernel<T1,T2,T3>::value &&
218 !UseOptimizedKernel<T1,T2,T3>::value };
256 enum { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
257 !evaluateRight && MT2::smpAssignable };
290 if(
lhs_.columns() == 0UL )
305 if( element != end ) {
306 tmp = element->value() *
rhs_(element->index(),j);
308 for( ; element!=
end; ++element ) {
309 tmp += element->value() *
rhs_(element->index(),j);
332 :(
lhs_.columns() ) ) );
335 tmp =
lhs_(i,kbegin) *
rhs_(kbegin,j);
336 for(
size_t k=kbegin+1UL; k<kend; ++k ) {
362 return rhs_.columns();
392 template<
typename T >
394 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
404 template<
typename T >
406 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
416 return rhs_.isAligned();
449 template<
typename MT
459 LT A(
serial( rhs.lhs_ ) );
460 RT B(
serial( rhs.rhs_ ) );
469 SMatDMatMultExpr::selectAssignKernel( ~lhs, A, B );
488 template<
typename MT3
496 for(
size_t i=0UL; i<A.rows(); ++i )
498 for(
size_t j=0UL; j<(~C).
columns(); ++j ) {
502 ConstIterator element( A.begin(i) );
503 const ConstIterator
end( A.end(i) );
505 for( ; element!=
end; ++element )
507 const size_t index( element->index() );
509 if( IsDiagonal<MT5>::value )
511 (~C)(i,index) = element->value() * B(index,index);
515 const size_t jbegin( ( IsUpper<MT5>::value )
516 ?( IsStrictlyUpper<MT5>::value ? index+1UL : index )
518 const size_t jend( ( IsLower<MT5>::value )
519 ?( IsStrictlyLower<MT5>::value ? index : index+1UL )
523 for(
size_t j=jbegin; j<jend; ++j ) {
525 (~C)(i,j) = element->value() * B(index,j);
527 (~C)(i,j) += element->value() * B(index,j);
550 template<
typename MT3
553 static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
554 selectAssignKernel( DenseMatrix<MT3,false>& C,
const MT4& A,
const MT5& B )
560 for(
size_t i=0UL; i<A.rows(); ++i )
562 const ConstIterator
end( A.end(i) );
563 ConstIterator element( A.begin(i) );
565 const size_t nonzeros( A.nonZeros(i) );
566 const size_t kpos( nonzeros &
size_t(-4) );
569 for(
size_t k=0UL; k<kpos; k+=4UL )
571 const size_t i1( element->index() );
572 const ET1 v1( element->value() );
574 const size_t i2( element->index() );
575 const ET1 v2( element->value() );
577 const size_t i3( element->index() );
578 const ET1 v3( element->value() );
580 const size_t i4( element->index() );
581 const ET1 v4( element->value() );
586 const size_t jbegin( ( IsUpper<MT5>::value )
587 ?( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 )
589 const size_t jend( ( IsLower<MT5>::value )
590 ?( IsStrictlyLower<MT5>::value ? i4 : i4+1UL )
594 const size_t jnum( jend - jbegin );
595 const size_t jpos( jbegin + ( jnum &
size_t(-4) ) );
598 for(
size_t j=jbegin; j<jpos; j+=4UL ) {
599 (~C)(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
600 (~C)(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
601 (~C)(i,j+2UL) += v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
602 (~C)(i,j+3UL) += v1 * B(i1,j+3UL) + v2 * B(i2,j+3UL) + v3 * B(i3,j+3UL) + v4 * B(i4,j+3UL);
604 for(
size_t j=jpos; j<jend; ++j ) {
605 (~C)(i,j) += v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
609 for( ; element!=
end; ++element )
611 const size_t i1( element->index() );
612 const ET1 v1( element->value() );
614 const size_t jbegin( ( IsUpper<MT5>::value )
615 ?( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 )
617 const size_t jend( ( IsLower<MT5>::value )
618 ?( IsStrictlyLower<MT5>::value ? i1 : i1+1UL )
622 const size_t jnum( jend - jbegin );
623 const size_t jpos( jbegin + ( jnum &
size_t(-4) ) );
626 for(
size_t j=jbegin; j<jpos; j+=4UL ) {
627 (~C)(i,j ) += v1 * B(i1,j );
628 (~C)(i,j+1UL) += v1 * B(i1,j+1UL);
629 (~C)(i,j+2UL) += v1 * B(i1,j+2UL);
630 (~C)(i,j+3UL) += v1 * B(i1,j+3UL);
632 for(
size_t j=jpos; j<jend; ++j ) {
633 (~C)(i,j) += v1 * B(i1,j);
655 template<
typename MT3
658 static inline typename EnableIf< UseVectorizedKernel<MT3,MT4,MT5> >::Type
659 selectAssignKernel( DenseMatrix<MT3,false>& C,
const MT4& A,
const MT5& B )
661 typedef IntrinsicTrait<ElementType> IT;
666 for(
size_t i=0UL; i<A.rows(); ++i )
668 const ConstIterator
end( A.end(i) );
669 ConstIterator element( A.begin(i) );
671 const size_t nonzeros( A.nonZeros(i) );
672 const size_t kpos( nonzeros &
size_t(-4) );
675 for(
size_t k=0UL; k<kpos; k+=4UL )
677 const size_t i1( element->index() );
678 const IntrinsicType v1(
set( element->value() ) );
680 const size_t i2( element->index() );
681 const IntrinsicType v2(
set( element->value() ) );
683 const size_t i3( element->index() );
684 const IntrinsicType v3(
set( element->value() ) );
686 const size_t i4( element->index() );
687 const IntrinsicType v4(
set( element->value() ) );
692 const size_t jbegin( ( IsUpper<MT5>::value )
693 ?( ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) &
size_t(-
IT::size) )
695 const size_t jend( ( IsLower<MT5>::value )
696 ?( IsStrictlyLower<MT5>::value ? i4 : i4+1UL )
700 for(
size_t j=jbegin; j<jend; j+=
IT::size ) {
701 (~C).
store( i, j, (~C).load(i,j) + v1 * B.load(i1,j) + v2 * B.load(i2,j) + v3 * B.load(i3,j) + v4 * B.load(i4,j) );
705 for( ; element!=
end; ++element )
707 const size_t i1( element->index() );
708 const IntrinsicType v1(
set( element->value() ) );
710 const size_t jbegin( ( IsUpper<MT5>::value )
711 ?( ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) &
size_t(-
IT::size) )
713 const size_t jend( ( IsLower<MT5>::value )
714 ?( IsStrictlyLower<MT5>::value ? i1 : i1+1UL )
718 for(
size_t j=jbegin; j<jend; j+=
IT::size ) {
719 (~C).
store( i, j, (~C).load(i,j) + v1 * B.load(i1,j) );
741 template<
typename MT3
744 static inline void selectAssignKernel( DenseMatrix<MT3,true>& C,
const MT4& A,
const MT5& B )
748 const size_t jpos( B.columns() & size_t(-4) );
751 for(
size_t j=0UL; j<jpos; j+=4UL ) {
752 for(
size_t i=0UL; i<A.rows(); ++i )
754 ConstIterator element( ( IsLower<MT5>::value )
755 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
757 const ConstIterator
end( ( IsUpper<MT5>::value )
758 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
761 if( element ==
end ) {
763 reset( (~C)(i,j+1UL) );
764 reset( (~C)(i,j+2UL) );
765 reset( (~C)(i,j+3UL) );
769 (~C)(i,j ) = element->value() * B(element->index(),j );
770 (~C)(i,j+1UL) = element->value() * B(element->index(),j+1UL);
771 (~C)(i,j+2UL) = element->value() * B(element->index(),j+2UL);
772 (~C)(i,j+3UL) = element->value() * B(element->index(),j+3UL);
774 for( ; element!=
end; ++element ) {
775 (~C)(i,j ) += element->value() * B(element->index(),j );
776 (~C)(i,j+1UL) += element->value() * B(element->index(),j+1UL);
777 (~C)(i,j+2UL) += element->value() * B(element->index(),j+2UL);
778 (~C)(i,j+3UL) += element->value() * B(element->index(),j+3UL);
783 for(
size_t j=jpos; j<B.columns(); ++j ) {
784 for(
size_t i=0UL; i<A.rows(); ++i )
786 ConstIterator element( ( IsLower<MT5>::value )
787 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
789 const ConstIterator
end( ( IsUpper<MT5>::value )
790 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j) : A.upperBound(i,j) )
793 if( element ==
end ) {
798 (~C)(i,j) = element->value() * B(element->index(),j);
800 for( ; element!=
end; ++element )
801 (~C)(i,j) += element->value() * B(element->index(),j);
821 template<
typename MT
827 typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
839 const TmpType tmp(
serial( rhs ) );
860 template<
typename MT >
861 friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
871 if( IsSymmetric<MT1>::value )
892 template<
typename MT
901 LT A(
serial( rhs.lhs_ ) );
902 RT B(
serial( rhs.rhs_ ) );
911 SMatDMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
930 template<
typename MT3
933 static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
934 selectAddAssignKernel( DenseMatrix<MT3,false>& C,
const MT4& A,
const MT5& B )
938 for(
size_t i=0UL; i<A.rows(); ++i )
940 const ConstIterator
end( A.end(i) );
941 ConstIterator element( A.begin(i) );
943 for( ; element!=
end; ++element )
945 const size_t i1( element->index() );
947 if( IsDiagonal<MT5>::value )
949 (~C)(i,i1) += element->value() * B(i1,i1);
953 const size_t jbegin( ( IsUpper<MT5>::value )
954 ?( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ):( 0UL ) );
955 const size_t jend( ( IsLower<MT5>::value )
956 ?( IsStrictlyLower<MT5>::value ? i1 : i1+1UL )
960 const size_t jnum( jend - jbegin );
961 const size_t jpos( jbegin + ( jnum &
size_t(-4) ) );
964 for(
size_t j=jbegin; j<jpos; j+=4UL ) {
965 (~C)(i,j ) += element->value() * B(i1,j );
966 (~C)(i,j+1UL) += element->value() * B(i1,j+1UL);
967 (~C)(i,j+2UL) += element->value() * B(i1,j+2UL);
968 (~C)(i,j+3UL) += element->value() * B(i1,j+3UL);
970 for(
size_t j=jpos; j<jend; ++j ) {
971 (~C)(i,j) += element->value() * B(i1,j);
994 template<
typename MT3
997 static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
998 selectAddAssignKernel( DenseMatrix<MT3,false>& C,
const MT4& A,
const MT5& B )
1002 for(
size_t i=0UL; i<A.rows(); ++i )
1004 const ConstIterator
end( A.end(i) );
1005 ConstIterator element( A.begin(i) );
1007 const size_t nonzeros( A.nonZeros(i) );
1008 const size_t kpos( nonzeros &
size_t(-4) );
1011 for(
size_t k=0UL; k<kpos; k+=4UL )
1013 const size_t i1( element->index() );
1014 const ET1 v1( element->value() );
1016 const size_t i2( element->index() );
1017 const ET1 v2( element->value() );
1019 const size_t i3( element->index() );
1020 const ET1 v3( element->value() );
1022 const size_t i4( element->index() );
1023 const ET1 v4( element->value() );
1028 const size_t jbegin( ( IsUpper<MT5>::value )
1029 ?( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 )
1031 const size_t jend( ( IsLower<MT5>::value )
1032 ?( IsStrictlyLower<MT5>::value ? i4 : i4+1UL )
1036 const size_t jnum( jend - jbegin );
1037 const size_t jpos( jbegin + ( jnum &
size_t(-4) ) );
1040 for(
size_t j=jbegin; j<jpos; j+=4UL ) {
1041 (~C)(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
1042 (~C)(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
1043 (~C)(i,j+2UL) += v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
1044 (~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(
size_t j=jpos; j<jend; ++j ) {
1047 (~C)(i,j) += v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
1051 for( ; element!=
end; ++element )
1053 const size_t i1( element->index() );
1054 const ET1 v1( element->value() );
1056 const size_t jbegin( ( IsUpper<MT5>::value )
1057 ?( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 )
1059 const size_t jend( ( IsLower<MT5>::value )
1060 ?( IsStrictlyLower<MT5>::value ? i1 : i1+1UL )
1064 const size_t jnum( jend - jbegin );
1065 const size_t jpos( jbegin + ( jnum &
size_t(-4) ) );
1068 for(
size_t j=jbegin; j<jpos; j+=4UL ) {
1069 (~C)(i,j ) += v1 * B(i1,j );
1070 (~C)(i,j+1UL) += v1 * B(i1,j+1UL);
1071 (~C)(i,j+2UL) += v1 * B(i1,j+2UL);
1072 (~C)(i,j+3UL) += v1 * B(i1,j+3UL);
1074 for(
size_t j=jpos; j<jend; ++j ) {
1075 (~C)(i,j) += v1 * B(i1,j);
1097 template<
typename MT3
1100 static inline typename EnableIf< UseVectorizedKernel<MT3,MT4,MT5> >::Type
1101 selectAddAssignKernel( DenseMatrix<MT3,false>& C,
const MT4& A,
const MT5& B )
1103 typedef IntrinsicTrait<ElementType> IT;
1106 for(
size_t i=0UL; i<A.rows(); ++i )
1108 const ConstIterator
end( A.end(i) );
1109 ConstIterator element( A.begin(i) );
1111 const size_t nonzeros( A.nonZeros(i) );
1112 const size_t kpos( nonzeros &
size_t(-4) );
1115 for(
size_t k=0UL; k<kpos; k+=4UL )
1117 const size_t i1( element->index() );
1118 const IntrinsicType v1(
set( element->value() ) );
1120 const size_t i2( element->index() );
1121 const IntrinsicType v2(
set( element->value() ) );
1123 const size_t i3( element->index() );
1124 const IntrinsicType v3(
set( element->value() ) );
1126 const size_t i4( element->index() );
1127 const IntrinsicType v4(
set( element->value() ) );
1132 const size_t jbegin( ( IsUpper<MT5>::value )
1133 ?( ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) &
size_t(-
IT::size) )
1135 const size_t jend( ( IsLower<MT5>::value )
1136 ?( IsStrictlyLower<MT5>::value ? i4 : i4+1UL )
1140 for(
size_t j=jbegin; j<jend; j+=
IT::size ) {
1141 (~C).
store( i, j, (~C).load(i,j) + v1 * B.load(i1,j) + v2 * B.load(i2,j) + v3 * B.load(i3,j) + v4 * B.load(i4,j) );
1145 for( ; element!=
end; ++element )
1147 const size_t i1( element->index() );
1148 const IntrinsicType v1(
set( element->value() ) );
1150 const size_t jbegin( ( IsUpper<MT5>::value )
1151 ?( ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) &
size_t(-
IT::size) )
1153 const size_t jend( ( IsLower<MT5>::value )
1154 ?( IsStrictlyLower<MT5>::value ? i1 : i1+1UL )
1158 for(
size_t j=jbegin; j<jend; j+=
IT::size ) {
1159 (~C).
store( i, j, (~C).load(i,j) + v1 * B.load(i1,j) );
1181 template<
typename MT3
1184 static inline void selectAddAssignKernel( DenseMatrix<MT3,true>& C,
const MT4& A,
const MT5& B )
1188 const size_t jpos( B.columns() & size_t(-4) );
1189 BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == jpos,
"Invalid end calculation" );
1191 for(
size_t j=0UL; j<jpos; j+=4UL ) {
1192 for(
size_t i=0UL; i<A.rows(); ++i )
1194 ConstIterator element( ( IsLower<MT5>::value )
1195 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1197 const ConstIterator
end( ( IsUpper<MT5>::value )
1198 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
1201 for( ; element!=
end; ++element ) {
1202 (~C)(i,j ) += element->value() * B(element->index(),j );
1203 (~C)(i,j+1UL) += element->value() * B(element->index(),j+1UL);
1204 (~C)(i,j+2UL) += element->value() * B(element->index(),j+2UL);
1205 (~C)(i,j+3UL) += element->value() * B(element->index(),j+3UL);
1210 for(
size_t j=jpos; j<B.columns(); ++j ) {
1211 for(
size_t i=0UL; i<A.rows(); ++i )
1213 ConstIterator element( ( IsLower<MT5>::value )
1214 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1216 const ConstIterator
end( ( IsUpper<MT5>::value )
1217 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j) : A.upperBound(i,j) )
1220 for( ; element!=
end; ++element )
1221 (~C)(i,j) += element->value() * B(element->index(),j);
1243 template<
typename MT >
1244 friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1254 if( IsSymmetric<MT1>::value )
1279 template<
typename MT
1288 LT A(
serial( rhs.lhs_ ) );
1289 RT B(
serial( rhs.rhs_ ) );
1298 SMatDMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
1317 template<
typename MT3
1320 static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
1321 selectSubAssignKernel( DenseMatrix<MT3,false>& C,
const MT4& A,
const MT5& B )
1325 for(
size_t i=0UL; i<A.rows(); ++i )
1327 const ConstIterator
end( A.end(i) );
1328 ConstIterator element( A.begin(i) );
1330 for( ; element!=
end; ++element )
1332 const size_t i1( element->index() );
1334 if( IsDiagonal<MT5>::value )
1336 (~C)(i,i1) -= element->value() * B(i1,i1);
1340 const size_t jbegin( ( IsUpper<MT5>::value )
1341 ?( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ):( 0UL ) );
1342 const size_t jend( ( IsLower<MT5>::value )
1343 ?( IsStrictlyLower<MT5>::value ? i1 : i1+1UL )
1347 const size_t jnum( jend - jbegin );
1348 const size_t jpos( jbegin + ( jnum &
size_t(-4) ) );
1351 for(
size_t j=jbegin; j<jpos; j+=4UL ) {
1352 (~C)(i,j ) -= element->value() * B(i1,j );
1353 (~C)(i,j+1UL) -= element->value() * B(i1,j+1UL);
1354 (~C)(i,j+2UL) -= element->value() * B(i1,j+2UL);
1355 (~C)(i,j+3UL) -= element->value() * B(i1,j+3UL);
1357 for(
size_t j=jpos; j<jend; ++j ) {
1358 (~C)(i,j) -= element->value() * B(i1,j);
1381 template<
typename MT3
1384 static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
1385 selectSubAssignKernel( DenseMatrix<MT3,false>& C,
const MT4& A,
const MT5& B )
1389 for(
size_t i=0UL; i<A.rows(); ++i )
1391 const ConstIterator
end( A.end(i) );
1392 ConstIterator element( A.begin(i) );
1394 const size_t nonzeros( A.nonZeros(i) );
1395 const size_t kpos( nonzeros &
size_t(-4) );
1398 for(
size_t k=0UL; k<kpos; k+=4UL )
1400 const size_t i1( element->index() );
1401 const ET1 v1( element->value() );
1403 const size_t i2( element->index() );
1404 const ET1 v2( element->value() );
1406 const size_t i3( element->index() );
1407 const ET1 v3( element->value() );
1409 const size_t i4( element->index() );
1410 const ET1 v4( element->value() );
1415 const size_t jbegin( ( IsUpper<MT5>::value )
1416 ?( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 )
1418 const size_t jend( ( IsLower<MT5>::value )
1419 ?( IsStrictlyLower<MT5>::value ? i4 : i4+1UL )
1423 const size_t jnum( jend - jbegin );
1424 const size_t jpos( jbegin + ( jnum &
size_t(-4) ) );
1427 for(
size_t j=jbegin; j<jpos; j+=4UL ) {
1428 (~C)(i,j ) -= v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
1429 (~C)(i,j+1UL) -= v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
1430 (~C)(i,j+2UL) -= v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
1431 (~C)(i,j+3UL) -= v1 * B(i1,j+3UL) + v2 * B(i2,j+3UL) + v3 * B(i3,j+3UL) + v4 * B(i4,j+3UL);
1433 for(
size_t j=jpos; j<jend; ++j ) {
1434 (~C)(i,j) -= v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
1438 for( ; element!=
end; ++element )
1440 const size_t i1( element->index() );
1441 const ET1 v1( element->value() );
1443 const size_t jbegin( ( IsUpper<MT5>::value )
1444 ?( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 )
1446 const size_t jend( ( IsLower<MT5>::value )
1447 ?( IsStrictlyLower<MT5>::value ? i1 : i1+1UL )
1451 const size_t jnum( jend - jbegin );
1452 const size_t jpos( jbegin + ( jnum &
size_t(-4) ) );
1455 for(
size_t j=jbegin; j<jpos; j+=4UL ) {
1456 (~C)(i,j ) -= v1 * B(i1,j );
1457 (~C)(i,j+1UL) -= v1 * B(i1,j+1UL);
1458 (~C)(i,j+2UL) -= v1 * B(i1,j+2UL);
1459 (~C)(i,j+3UL) -= v1 * B(i1,j+3UL);
1461 for(
size_t j=jpos; j<jend; ++j ) {
1462 (~C)(i,j) -= v1 * B(i1,j);
1484 template<
typename MT3
1487 static inline typename EnableIf< UseVectorizedKernel<MT3,MT4,MT5> >::Type
1488 selectSubAssignKernel( DenseMatrix<MT3,false>& C,
const MT4& A,
const MT5& B )
1490 typedef IntrinsicTrait<ElementType> IT;
1493 for(
size_t i=0UL; i<A.rows(); ++i )
1495 const ConstIterator
end( A.end(i) );
1496 ConstIterator element( A.begin(i) );
1498 const size_t nonzeros( A.nonZeros(i) );
1499 const size_t kpos( nonzeros &
size_t(-4) );
1502 for(
size_t k=0UL; k<kpos; k+=4UL )
1504 const size_t i1( element->index() );
1505 const IntrinsicType v1(
set( element->value() ) );
1507 const size_t i2( element->index() );
1508 const IntrinsicType v2(
set( element->value() ) );
1510 const size_t i3( element->index() );
1511 const IntrinsicType v3(
set( element->value() ) );
1513 const size_t i4( element->index() );
1514 const IntrinsicType v4(
set( element->value() ) );
1519 const size_t jbegin( ( IsUpper<MT5>::value )
1520 ?( ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) &
size_t(-
IT::size) )
1522 const size_t jend( ( IsLower<MT5>::value )
1523 ?( IsStrictlyLower<MT5>::value ? i4 : i4+1UL )
1527 for(
size_t j=jbegin; j<jend; j+=
IT::size ) {
1528 (~C).
store( i, j, (~C).load(i,j) - v1 * B.load(i1,j) - v2 * B.load(i2,j) - v3 * B.load(i3,j) - v4 * B.load(i4,j) );
1532 for( ; element!=
end; ++element )
1534 const size_t i1( element->index() );
1535 const IntrinsicType v1(
set( element->value() ) );
1537 const size_t jbegin( ( IsUpper<MT5>::value )
1538 ?( ( IsStrictlyUpper<MT5>::value ? i1+1UL : i1 ) &
size_t(-
IT::size) )
1540 const size_t jend( ( IsLower<MT5>::value )
1541 ?( IsStrictlyLower<MT5>::value ? i1 : i1+1UL )
1545 for(
size_t j=jbegin; j<jend; j+=
IT::size ) {
1546 (~C).
store( i, j, (~C).load(i,j) - v1 * B.load(i1,j) );
1568 template<
typename MT3
1571 static inline void selectSubAssignKernel( DenseMatrix<MT3,true>& C,
const MT4& A,
const MT5& B )
1575 const size_t jpos( B.columns() & size_t(-4) );
1576 BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == jpos,
"Invalid end calculation" );
1578 for(
size_t j=0UL; j<jpos; j+=4UL ) {
1579 for(
size_t i=0UL; i<A.rows(); ++i )
1581 ConstIterator element( ( IsLower<MT5>::value )
1582 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1584 const ConstIterator
end( ( IsUpper<MT5>::value )
1585 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
1588 for( ; element!=
end; ++element ) {
1589 (~C)(i,j ) -= element->value() * B(element->index(),j );
1590 (~C)(i,j+1UL) -= element->value() * B(element->index(),j+1UL);
1591 (~C)(i,j+2UL) -= element->value() * B(element->index(),j+2UL);
1592 (~C)(i,j+3UL) -= element->value() * B(element->index(),j+3UL);
1597 for(
size_t j=jpos; j<B.columns(); ++j ) {
1598 for(
size_t i=0UL; i<A.rows(); ++i )
1600 ConstIterator element( ( IsLower<MT5>::value )
1601 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1603 const ConstIterator
end( ( IsUpper<MT5>::value )
1604 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j) : A.upperBound(i,j) )
1607 for( ; element!=
end; ++element )
1608 (~C)(i,j) -= element->value() * B(element->index(),j);
1630 template<
typename MT >
1631 friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1641 if( IsSymmetric<MT1>::value )
1676 template<
typename MT
1678 friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1716 template<
typename MT
1718 friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1723 typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
1735 const TmpType tmp( rhs );
1756 template<
typename MT >
1757 friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1767 if( IsSymmetric<MT1>::value )
1791 template<
typename MT
1793 friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1831 template<
typename MT >
1832 friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1842 if( IsSymmetric<MT1>::value )
1870 template<
typename MT
1872 friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1910 template<
typename MT >
1911 friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1921 if( IsSymmetric<MT1>::value )
1991 template<
typename T1
1993 inline const SMatDMatMultExpr<T1,T2>
1999 throw std::invalid_argument(
"Matrix sizes do not match" );
2016 template<
typename MT1,
typename MT2 >
2034 template<
typename MT1,
typename MT2 >
2036 :
public Columns<MT2>
2052 template<
typename MT1,
typename MT2 >
2054 :
public IsTrue< And< IsLower<MT1>, IsLower<MT2> >::value >
2070 template<
typename MT1,
typename MT2 >
2072 :
public IsTrue< And< IsUniLower<MT1>, IsUniLower<MT2> >::value >
2088 template<
typename MT1,
typename MT2 >
2090 :
public IsTrue< Or< And< IsStrictlyLower<MT1>, IsLower<MT2> >
2091 , And< IsStrictlyLower<MT2>, IsLower<MT1> > >::value >
2107 template<
typename MT1,
typename MT2 >
2109 :
public IsTrue< And< IsUpper<MT1>, IsUpper<MT2> >::value >
2125 template<
typename MT1,
typename MT2 >
2127 :
public IsTrue< And< IsUniUpper<MT1>, IsUniUpper<MT2> >::value >
2143 template<
typename MT1,
typename MT2 >
2145 :
public IsTrue< Or< And< IsStrictlyUpper<MT1>, IsUpper<MT2> >
2146 , And< IsStrictlyUpper<MT2>, IsUpper<MT1> > >::value >
2162 template<
typename MT1,
typename MT2,
typename VT >
2167 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
2168 IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
2169 IsDenseVector<VT>::value && IsColumnVector<VT>::value
2170 ,
typename SMatDVecMultExprTrait< MT1, typename DMatDVecMultExprTrait<MT2,VT>::Type >::Type
2171 , INVALID_TYPE >::Type Type;
2180 template<
typename MT1,
typename MT2,
typename VT >
2185 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
2186 IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
2187 IsSparseVector<VT>::value && IsColumnVector<VT>::value
2188 ,
typename SMatDVecMultExprTrait< MT1, typename DMatSVecMultExprTrait<MT2,VT>::Type >::Type
2189 , INVALID_TYPE >::Type Type;
2198 template<
typename VT,
typename MT1,
typename MT2 >
2203 typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
2204 IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
2205 IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
2206 ,
typename TDVecDMatMultExprTrait< typename TDVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
2207 , INVALID_TYPE >::Type Type;
2216 template<
typename VT,
typename MT1,
typename MT2 >
2221 typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
2222 IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
2223 IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
2224 ,
typename TSVecDMatMultExprTrait< typename TSVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
2225 , INVALID_TYPE >::Type Type;
2234 template<
typename MT1,
typename MT2,
bool AF >
2239 typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
2240 ,
typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
2249 template<
typename MT1,
typename MT2 >
2254 typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
2263 template<
typename MT1,
typename MT2 >
2268 typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1649
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: SMatDMatMultExpr.h:432
Header file for the SMatDVecMultExprTrait class template.
Header file for the Rows type trait.
Header file for the IsUniUpper type trait.
const DMatDMatMultExpr< T1, T2 > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:8247
IntrinsicTrait< ElementType >::Type IntrinsicType
Resulting intrinsic element type.
Definition: SMatDMatMultExpr.h:230
Compile time check for triangular matrix types.This type trait tests whether or not the given templat...
Definition: IsTriangular.h:105
Header file for basic type definitions.
SelectType< evaluateRight, const RT2, CT2 >::Type RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: SMatDMatMultExpr.h:244
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:264
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: SMatDMatMultExpr.h:415
BLAZE_ALWAYS_INLINE 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:258
Header file for the IsSparseMatrix type trait.
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:209
Header file for the IsDiagonal type trait.
#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:79
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatDMatMultExpr.h:235
Header file for the ColumnExprTrait class template.
Header file for the IsSame and IsStrictlySame type traits.
SMatDMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the SMatDMatMultExpr class.
Definition: SMatDMatMultExpr.h:266
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:821
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2507
Header file for the IsRowVector type trait.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:261
Header file for the And class template.
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:90
Header file for the TDVecSMatMultExprTrait class template.
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:699
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
Expression object for sparse matrix-dense matrix multiplications.The SMatDMatMultExpr class represent...
Definition: Forward.h:89
Type relationship analysis.This class tests if the two data types A and B are equal. For this type comparison, the cv-qualifiers of both data types are ignored. If A and B are the same data type (ignoring the cv-qualifiers), then the value member enumeration is set to 1, the nested type definition Type is TrueType, and the class derives from TrueType. Otherwise value is set to 0, Type is FalseType, and the class derives from FalseType.
Definition: IsSame.h:158
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SMatDMatMultExpr.h:228
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:90
Header file for the RequiresEvaluation type trait.
Header file for the TSVecSMatMultExprTrait class template.
SelectType< evaluateLeft, const RT1, CT1 >::Type LT
Type for the assignment of the left-hand side sparse matrix operand.
Definition: SMatDMatMultExpr.h:241
Header file for the IsUniLower type trait.
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:107
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:861
Constraint on the data type.
Constraint on the data type.
Header file for the MultExprTrait class template.
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
RT1::ElementType ET1
Element type of the left-hand side sparse matrix expression.
Definition: SMatDMatMultExpr.h:129
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
Header file for the DisableIf class template.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#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: StorageOrder.h:161
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatDMatMultExpr.h:281
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2511
Header file for the Or class template.
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > > >::Type store(T *address, const sse_int16_t &value)
Aligned store of a vector of 2-byte integral values.
Definition: Store.h:80
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1602
Header file for the DenseMatrix base class.
BLAZE_ALWAYS_INLINE void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:635
Header file for the Columns type trait.
Header file for the DMatDVecMultExprTrait class template.
Header file for the IsLower type trait.
Compile time check for diagonal matrices.This type trait tests whether or not the given template para...
Definition: IsDiagonal.h:92
ResultType::ElementType ElementType
Resulting element type.
Definition: SMatDMatMultExpr.h:229
#define BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:78
Header file for the IsTriangular type trait.
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: SMatDMatMultExpr.h:405
Constraints on the storage order of matrix types.
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: SMatDMatMultExpr.h:238
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2505
Header file for the SelectType class template.
Header file for the RowExprTrait class template.
Header file for all forward declarations for expression class templates.
Header file for the IsDenseMatrix type trait.
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: SMatDMatMultExpr.h:226
MT1::CompositeType CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatDMatMultExpr.h:131
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
const size_t SMP_SMATDMATMULT_THRESHOLD
SMP row-major sparse matrix/row-major dense matrix multiplication threshold.This threshold specifies ...
Definition: Thresholds.h:1018
Header file for the serial shim.
#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:165
LeftOperand leftOperand() const
Returns the left-hand side sparse matrix operand.
Definition: SMatDMatMultExpr.h:371
EnableIf< IsDenseMatrix< MT1 > >::Type smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:160
Header file for the IsSparseVector type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:116
Header file for the SubmatrixExprTrait class template.
#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: StorageOrder.h:81
const ElementType ReturnType
Return type for expression template evaluations.
Definition: SMatDMatMultExpr.h:231
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
Intrinsic characteristics of data types.The IntrinsicTrait class template provides the intrinsic char...
Definition: IntrinsicTrait.h:749
MT2::CompositeType CT2
Composite type of the right-hand side dense matrix expression.
Definition: SMatDMatMultExpr.h:132
Header file for run time assertion macros.
EnableIf< IsDenseMatrix< MT1 > >::Type smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:98
Utility type for generic codes.
Base template for the MultTrait class.
Definition: MultTrait.h:150
size_t rows() const
Returns the current number of rows of the matrix.
Definition: SMatDMatMultExpr.h:351
BLAZE_ALWAYS_INLINE void addAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a matrix to a matrix.
Definition: Matrix.h:742
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
Header file for the reset shim.
SMatDMatMultExpr< MT1, MT2 > This
Type of this SMatDMatMultExpr instance.
Definition: SMatDMatMultExpr.h:225
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: SMatDMatMultExpr.h:425
MT2::ResultType RT2
Result type of the right-hand side dense matrix expression.
Definition: SMatDMatMultExpr.h:128
RightOperand rhs_
Right-hand side dense matrix of the multiplication expression.
Definition: SMatDMatMultExpr.h:433
Header file for the RemoveReference type trait.
Substitution Failure Is Not An Error (SFINAE) class.The DisableIf class template is an auxiliary tool...
Definition: DisableIf.h:184
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, sse_int16_t >::Type set(T value)
Sets all values in the vector to the given 2-byte integral value.
Definition: Set.h:73
#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:283
Header file for the IsDenseVector type trait.
Header file for all intrinsic functionality.
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatDMatMultExpr.h:127
Header file for the IsRowMajorMatrix type trait.
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:937
Header file for the IsComputation type trait class.
Header file for the TDVecDMatMultExprTrait class template.
EnableIf< IsDenseMatrix< MT1 > >::Type smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:129
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2502
Header file for the IsTrue value trait.
Header file for the TSVecDMatMultExprTrait class template.
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: SMatDMatMultExpr.h:393
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatDMatMultExpr.h:232
Header file for the IsUpper type trait.
Header file for the DMatSVecMultExprTrait class template.
Header file for the IsColumnVector type trait.
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatDMatMultExpr.h:227
RightOperand rightOperand() const
Returns the right-hand side dense matrix operand.
Definition: SMatDMatMultExpr.h:381
Constraint on the data type.
RT2::ElementType ET2
Element type of the right-hand side dense matrix expression.
Definition: SMatDMatMultExpr.h:130
Header file for the IsResizable type trait.
size_t columns() const
Returns the current number of columns of the matrix.
Definition: SMatDMatMultExpr.h:361
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
#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:79
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.
BLAZE_ALWAYS_INLINE void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:849