35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATTDMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATTDMATMULTEXPR_H_
125 template<
typename MT1
127 class SMatTDMatMultExpr :
public DenseMatrix< SMatTDMatMultExpr<MT1,MT2>, false >
128 ,
private MatMatMultExpr
129 ,
private Computation
158 template<
typename T1,
typename T2,
typename T3 >
159 struct CanExploitSymmetry {
160 enum { value = IsSymmetric<T3>::value };
171 template<
typename T1,
typename T2,
typename T3 >
172 struct IsEvaluationRequired {
173 enum { value = ( evaluateLeft || evaluateRight ) &&
174 CanExploitSymmetry<T1,T2,T3>::value };
184 template<
typename T1,
typename T2,
typename T3 >
185 struct UseOptimizedKernel {
187 !IsDiagonal<T3>::value &&
188 !IsResizable<typename T1::ElementType>::value &&
189 !IsResizable<ET1>::value };
219 enum { vectorizable = 0 };
222 enum { smpAssignable = !evaluateLeft && MT1::smpAssignable &&
223 !evaluateRight && MT2::smpAssignable };
256 if(
lhs_.columns() == 0UL )
271 if( element != end ) {
272 tmp = element->value() *
rhs_(element->index(),j);
274 for( ; element!=
end; ++element ) {
275 tmp += element->value() *
rhs_(element->index(),j);
298 :(
lhs_.columns() ) ) );
301 tmp =
lhs_(i,kbegin) *
rhs_(kbegin,j);
302 for(
size_t k=kbegin+1UL; k<kend; ++k ) {
320 inline ReturnType
at(
size_t i,
size_t j )
const {
321 if( i >=
lhs_.rows() ) {
324 if( j >=
rhs_.columns() ) {
347 return rhs_.columns();
377 template<
typename T >
379 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
389 template<
typename T >
391 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
401 return rhs_.isAligned();
411 return (
rows() > SMP_SMATTDMATMULT_THRESHOLD );
434 template<
typename MT
444 LT A(
serial( rhs.lhs_ ) );
445 RT B(
serial( rhs.rhs_ ) );
454 SMatTDMatMultExpr::selectAssignKernel( ~lhs, A, B );
473 template<
typename MT3
477 selectAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
483 for(
size_t ii=0UL; ii<A.rows(); ii+=block )
485 const size_t iend(
min( ii+block, A.rows() ) );
489 for( ; (j+4UL) <= B.columns(); j+=4UL ) {
490 for(
size_t i=ii; i<iend; ++i )
499 if( element ==
end ) {
507 C(i,j ) = element->value() * B(element->index(),j );
508 C(i,j+1UL) = element->value() * B(element->index(),j+1UL);
509 C(i,j+2UL) = element->value() * B(element->index(),j+2UL);
510 C(i,j+3UL) = element->value() * B(element->index(),j+3UL);
512 for( ; element!=
end; ++element ) {
513 C(i,j ) += element->value() * B(element->index(),j );
514 C(i,j+1UL) += element->value() * B(element->index(),j+1UL);
515 C(i,j+2UL) += element->value() * B(element->index(),j+2UL);
516 C(i,j+3UL) += element->value() * B(element->index(),j+3UL);
521 for( ; (j+2UL) <= B.columns(); j+=2UL ) {
522 for(
size_t i=ii; i<iend; ++i )
524 const ConstIterator
end( ( IsUpper<MT5>::value )
525 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+2UL) : A.upperBound(i,j+2UL) )
527 ConstIterator element( ( IsLower<MT5>::value )
528 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
531 if( element ==
end ) {
537 C(i,j ) = element->value() * B(element->index(),j );
538 C(i,j+1UL) = element->value() * B(element->index(),j+1UL);
540 for( ; element!=
end; ++element ) {
541 C(i,j ) += element->value() * B(element->index(),j );
542 C(i,j+1UL) += element->value() * B(element->index(),j+1UL);
547 for( ; j<B.columns(); ++j ) {
548 for(
size_t i=ii; i<iend; ++i )
550 const ConstIterator
end( ( IsUpper<MT5>::value )
551 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j) : A.upperBound(i,j) )
553 ConstIterator element( ( IsLower<MT5>::value )
554 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
557 if( element ==
end ) {
562 C(i,j) = element->value() * B(element->index(),j);
564 for( ; element!=
end; ++element ) {
565 C(i,j) += element->value() * B(element->index(),j);
588 template<
typename MT3
591 static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
592 selectAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
596 const size_t block( IsColumnMajorMatrix<MT3>::value ? A.rows() : 256UL );
600 for(
size_t ii=0UL; ii<A.rows(); ii+=block )
602 const size_t iend(
min( ii+block, A.rows() ) );
606 for( ; (j+4UL) <= B.columns(); j+=4UL ) {
607 for(
size_t i=ii; i<iend; ++i )
609 const ConstIterator
end( ( IsUpper<MT5>::value )
610 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
612 ConstIterator element( ( IsLower<MT5>::value )
613 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
616 const size_t nonzeros(
end - element );
617 const size_t kpos( nonzeros &
size_t(-4) );
620 for(
size_t k=0UL; k<kpos; k+=4UL )
622 const size_t i1( element->index() );
623 const ET1 v1( element->value() );
625 const size_t i2( element->index() );
626 const ET1 v2( element->value() );
628 const size_t i3( element->index() );
629 const ET1 v3( element->value() );
631 const size_t i4( element->index() );
632 const ET1 v4( element->value() );
637 C(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
638 C(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
639 C(i,j+2UL) += v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
640 C(i,j+3UL) += v1 * B(i1,j+3UL) + v2 * B(i2,j+3UL) + v3 * B(i3,j+3UL) + v4 * B(i4,j+3UL);
643 for( ; element!=
end; ++element )
645 const size_t i1( element->index() );
646 const ET1 v1( element->value() );
648 C(i,j ) += v1 * B(i1,j );
649 C(i,j+1UL) += v1 * B(i1,j+1UL);
650 C(i,j+2UL) += v1 * B(i1,j+2UL);
651 C(i,j+3UL) += v1 * B(i1,j+3UL);
656 for( ; (j+2UL) <= B.columns(); j+=2UL ) {
657 for(
size_t i=ii; i<iend; ++i )
659 const ConstIterator
end( ( IsUpper<MT5>::value )
660 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+2UL) : A.upperBound(i,j+2UL) )
662 ConstIterator element( ( IsLower<MT5>::value )
663 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
666 const size_t nonzeros(
end - element );
667 const size_t kpos( nonzeros &
size_t(-4) );
670 for(
size_t k=0UL; k<kpos; k+=4UL )
672 const size_t i1( element->index() );
673 const ET1 v1( element->value() );
675 const size_t i2( element->index() );
676 const ET1 v2( element->value() );
678 const size_t i3( element->index() );
679 const ET1 v3( element->value() );
681 const size_t i4( element->index() );
682 const ET1 v4( element->value() );
687 C(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
688 C(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
691 for( ; element!=
end; ++element )
693 const size_t i1( element->index() );
694 const ET1 v1( element->value() );
696 C(i,j ) += v1 * B(i1,j );
697 C(i,j+1UL) += v1 * B(i1,j+1UL);
702 for( ; j<B.columns(); ++j ) {
703 for(
size_t i=ii; i<iend; ++i )
705 const ConstIterator
end( ( IsUpper<MT5>::value )
706 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j) : A.upperBound(i,j) )
708 ConstIterator element( ( IsLower<MT5>::value )
709 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
712 const size_t nonzeros(
end - element );
713 const size_t kpos( nonzeros &
size_t(-4) );
716 for(
size_t k=0UL; k<kpos; k+=4UL )
718 const size_t i1( element->index() );
719 const ET1 v1( element->value() );
721 const size_t i2( element->index() );
722 const ET1 v2( element->value() );
724 const size_t i3( element->index() );
725 const ET1 v3( element->value() );
727 const size_t i4( element->index() );
728 const ET1 v4( element->value() );
733 C(i,j) += v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
736 for( ; element!=
end; ++element )
738 const size_t i1( element->index() );
739 const ET1 v1( element->value() );
741 C(i,j) += v1 * B(i1,j);
763 template<
typename MT
765 friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
770 typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
782 const TmpType tmp(
serial( rhs ) );
803 template<
typename MT
805 friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
813 assign( ~lhs, rhs.lhs_ *
trans( rhs.rhs_ ) );
831 template<
typename MT
833 friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
841 LT A(
serial( rhs.lhs_ ) );
842 RT B(
serial( rhs.rhs_ ) );
851 SMatTDMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
870 template<
typename MT3
873 static inline typename DisableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
874 selectAddAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
878 const size_t block( IsColumnMajorMatrix<MT3>::value ? A.rows() : 256UL );
880 for(
size_t ii=0UL; ii<A.rows(); ii+=block )
882 const size_t iend(
min( ii+block, A.rows() ) );
886 for( ; (j+4UL) <= B.columns(); j+=4UL ) {
887 for(
size_t i=ii; i<iend; ++i )
889 const ConstIterator
end( ( IsUpper<MT5>::value )
890 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
892 ConstIterator element( ( IsLower<MT5>::value )
893 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
896 for( ; element!=
end; ++element ) {
897 C(i,j ) += element->value() * B(element->index(),j );
898 C(i,j+1UL) += element->value() * B(element->index(),j+1UL);
899 C(i,j+2UL) += element->value() * B(element->index(),j+2UL);
900 C(i,j+3UL) += element->value() * B(element->index(),j+3UL);
905 for( ; (j+2UL) <= B.columns(); j+=2UL ) {
906 for(
size_t i=ii; i<iend; ++i )
908 const ConstIterator
end( ( IsUpper<MT5>::value )
909 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+2UL) : A.upperBound(i,j+2UL) )
911 ConstIterator element( ( IsLower<MT5>::value )
912 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
915 for( ; element!=
end; ++element ) {
916 C(i,j ) += element->value() * B(element->index(),j );
917 C(i,j+1UL) += element->value() * B(element->index(),j+1UL);
922 for( ; j<B.columns(); ++j ) {
923 for(
size_t i=ii; i<iend; ++i )
925 const ConstIterator
end( ( IsUpper<MT5>::value )
926 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j) : A.upperBound(i,j) )
928 ConstIterator element( ( IsLower<MT5>::value )
929 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
932 for( ; element!=
end; ++element ) {
933 C(i,j) += element->value() * B(element->index(),j);
956 template<
typename MT3
959 static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
960 selectAddAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
964 const size_t block( IsColumnMajorMatrix<MT3>::value ? A.rows() : 256UL );
966 for(
size_t ii=0UL; ii<A.rows(); ii+=block )
968 const size_t iend(
min( ii+block, A.rows() ) );
972 for( ; (j+4UL) <= B.columns(); j+=4UL ) {
973 for(
size_t i=ii; i<iend; ++i )
975 const ConstIterator
end( ( IsUpper<MT5>::value )
976 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
978 ConstIterator element( ( IsLower<MT5>::value )
979 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
982 const size_t nonzeros(
end - element );
983 const size_t kpos( nonzeros &
size_t(-4) );
986 for(
size_t k=0UL; k<kpos; k+=4UL )
988 const size_t i1( element->index() );
989 const ET1 v1( element->value() );
991 const size_t i2( element->index() );
992 const ET1 v2( element->value() );
994 const size_t i3( element->index() );
995 const ET1 v3( element->value() );
997 const size_t i4( element->index() );
998 const ET1 v4( element->value() );
1003 C(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
1004 C(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
1005 C(i,j+2UL) += v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
1006 C(i,j+3UL) += v1 * B(i1,j+3UL) + v2 * B(i2,j+3UL) + v3 * B(i3,j+3UL) + v4 * B(i4,j+3UL);
1009 for( ; element!=
end; ++element )
1011 const size_t i1( element->index() );
1012 const ET1 v1( element->value() );
1014 C(i,j ) += v1 * B(i1,j );
1015 C(i,j+1UL) += v1 * B(i1,j+1UL);
1016 C(i,j+2UL) += v1 * B(i1,j+2UL);
1017 C(i,j+3UL) += v1 * B(i1,j+3UL);
1022 for( ; (j+2UL) <= B.columns(); j+=2UL ) {
1023 for(
size_t i=ii; i<iend; ++i )
1025 const ConstIterator
end( ( IsUpper<MT5>::value )
1026 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+2UL) : A.upperBound(i,j+2UL) )
1028 ConstIterator element( ( IsLower<MT5>::value )
1029 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1032 const size_t nonzeros(
end - element );
1033 const size_t kpos( nonzeros &
size_t(-4) );
1036 for(
size_t k=0UL; k<kpos; k+=4UL )
1038 const size_t i1( element->index() );
1039 const ET1 v1( element->value() );
1041 const size_t i2( element->index() );
1042 const ET1 v2( element->value() );
1044 const size_t i3( element->index() );
1045 const ET1 v3( element->value() );
1047 const size_t i4( element->index() );
1048 const ET1 v4( element->value() );
1053 C(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
1054 C(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
1057 for( ; element!=
end; ++element )
1059 const size_t i1( element->index() );
1060 const ET1 v1( element->value() );
1062 C(i,j ) += v1 * B(i1,j );
1063 C(i,j+1UL) += v1 * B(i1,j+1UL);
1068 for( ; j<B.columns(); ++j ) {
1069 for(
size_t i=ii; i<iend; ++i )
1071 const ConstIterator
end( ( IsUpper<MT5>::value )
1072 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j) : A.upperBound(i,j) )
1074 ConstIterator element( ( IsLower<MT5>::value )
1075 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1078 const size_t nonzeros(
end - element );
1079 const size_t kpos( nonzeros &
size_t(-4) );
1082 for(
size_t k=0UL; k<kpos; k+=4UL )
1084 const size_t i1( element->index() );
1085 const ET1 v1( element->value() );
1087 const size_t i2( element->index() );
1088 const ET1 v2( element->value() );
1090 const size_t i3( element->index() );
1091 const ET1 v3( element->value() );
1093 const size_t i4( element->index() );
1094 const ET1 v4( element->value() );
1099 C(i,j) += v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
1102 for( ; element!=
end; ++element )
1104 const size_t i1( element->index() );
1105 const ET1 v1( element->value() );
1107 C(i,j) += v1 * B(i1,j);
1131 template<
typename MT
1133 friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1141 addAssign( ~lhs, rhs.lhs_ *
trans( rhs.rhs_ ) );
1163 template<
typename MT
1165 friend inline typename DisableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1173 LT A(
serial( rhs.lhs_ ) );
1174 RT B(
serial( rhs.rhs_ ) );
1183 SMatTDMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
1202 template<
typename MT3
1205 static inline typename DisableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
1206 selectSubAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
1210 const size_t block( IsColumnMajorMatrix<MT3>::value ? A.rows() : 256UL );
1212 for(
size_t ii=0UL; ii<A.rows(); ii+=block )
1214 const size_t iend(
min( ii+block, A.rows() ) );
1218 for( ; (j+4UL) <= B.columns(); j+=4UL ) {
1219 for(
size_t i=ii; i<iend; ++i )
1221 const ConstIterator
end( ( IsUpper<MT5>::value )
1222 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
1224 ConstIterator element( ( IsLower<MT5>::value )
1225 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1228 for( ; element!=
end; ++element ) {
1229 C(i,j ) -= element->value() * B(element->index(),j );
1230 C(i,j+1UL) -= element->value() * B(element->index(),j+1UL);
1231 C(i,j+2UL) -= element->value() * B(element->index(),j+2UL);
1232 C(i,j+3UL) -= element->value() * B(element->index(),j+3UL);
1237 for( ; (j+2UL) <= B.columns(); j+=2UL ) {
1238 for(
size_t i=ii; i<iend; ++i )
1240 const ConstIterator
end( ( IsUpper<MT5>::value )
1241 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+2UL) : A.upperBound(i,j+2UL) )
1243 ConstIterator element( ( IsLower<MT5>::value )
1244 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1247 for( ; element!=
end; ++element ) {
1248 C(i,j ) -= element->value() * B(element->index(),j );
1249 C(i,j+1UL) -= element->value() * B(element->index(),j+1UL);
1254 for( ; j<B.columns(); ++j ) {
1255 for(
size_t i=ii; i<iend; ++i )
1257 const ConstIterator
end( ( IsUpper<MT5>::value )
1258 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j) : A.upperBound(i,j) )
1260 ConstIterator element( ( IsLower<MT5>::value )
1261 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1264 for( ; element!=
end; ++element ) {
1265 C(i,j) -= element->value() * B(element->index(),j);
1288 template<
typename MT3
1291 static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
1292 selectSubAssignKernel( MT3& C,
const MT4& A,
const MT5& B )
1296 const size_t block( IsColumnMajorMatrix<MT3>::value ? A.rows() : 256UL );
1298 for(
size_t ii=0UL; ii<A.rows(); ii+=block )
1300 const size_t iend(
min( ii+block, A.rows() ) );
1304 for( ; (j+4UL) <= B.columns(); j+=4UL ) {
1305 for(
size_t i=ii; i<iend; ++i )
1307 const ConstIterator
end( ( IsUpper<MT5>::value )
1308 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+4UL) : A.upperBound(i,j+4UL) )
1310 ConstIterator element( ( IsLower<MT5>::value )
1311 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1314 const size_t nonzeros(
end - element );
1315 const size_t kpos( nonzeros &
size_t(-4) );
1318 for(
size_t k=0UL; k<kpos; k+=4UL )
1320 const size_t i1( element->index() );
1321 const ET1 v1( element->value() );
1323 const size_t i2( element->index() );
1324 const ET1 v2( element->value() );
1326 const size_t i3( element->index() );
1327 const ET1 v3( element->value() );
1329 const size_t i4( element->index() );
1330 const ET1 v4( element->value() );
1335 C(i,j ) -= v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
1336 C(i,j+1UL) -= v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
1337 C(i,j+2UL) -= v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
1338 C(i,j+3UL) -= v1 * B(i1,j+3UL) + v2 * B(i2,j+3UL) + v3 * B(i3,j+3UL) + v4 * B(i4,j+3UL);
1341 for( ; element!=
end; ++element )
1343 const size_t i1( element->index() );
1344 const ET1 v1( element->value() );
1346 C(i,j ) -= v1 * B(i1,j );
1347 C(i,j+1UL) -= v1 * B(i1,j+1UL);
1348 C(i,j+2UL) -= v1 * B(i1,j+2UL);
1349 C(i,j+3UL) -= v1 * B(i1,j+3UL);
1354 for( ; (j+2UL) <= B.columns(); j+=2UL ) {
1355 for(
size_t i=ii; i<iend; ++i )
1357 const ConstIterator
end( ( IsUpper<MT5>::value )
1358 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j+2UL) : A.upperBound(i,j+2UL) )
1360 ConstIterator element( ( IsLower<MT5>::value )
1361 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1364 const size_t nonzeros(
end - element );
1365 const size_t kpos( nonzeros &
size_t(-4) );
1368 for(
size_t k=0UL; k<kpos; k+=4UL )
1370 const size_t i1( element->index() );
1371 const ET1 v1( element->value() );
1373 const size_t i2( element->index() );
1374 const ET1 v2( element->value() );
1376 const size_t i3( element->index() );
1377 const ET1 v3( element->value() );
1379 const size_t i4( element->index() );
1380 const ET1 v4( element->value() );
1385 C(i,j ) -= v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
1386 C(i,j+1UL) -= v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
1389 for( ; element!=
end; ++element )
1391 const size_t i1( element->index() );
1392 const ET1 v1( element->value() );
1394 C(i,j ) -= v1 * B(i1,j );
1395 C(i,j+1UL) -= v1 * B(i1,j+1UL);
1400 for( ; j<B.columns(); ++j ) {
1401 for(
size_t i=ii; i<iend; ++i )
1403 const ConstIterator
end( ( IsUpper<MT5>::value )
1404 ?( IsStrictlyUpper<MT5>::value ? A.lowerBound(i,j) : A.upperBound(i,j) )
1406 ConstIterator element( ( IsLower<MT5>::value )
1407 ?( IsStrictlyLower<MT5>::value ? A.upperBound(i,j) : A.lowerBound(i,j) )
1410 const size_t nonzeros(
end - element );
1411 const size_t kpos( nonzeros &
size_t(-4) );
1414 for(
size_t k=0UL; k<kpos; k+=4UL )
1416 const size_t i1( element->index() );
1417 const ET1 v1( element->value() );
1419 const size_t i2( element->index() );
1420 const ET1 v2( element->value() );
1422 const size_t i3( element->index() );
1423 const ET1 v3( element->value() );
1425 const size_t i4( element->index() );
1426 const ET1 v4( element->value() );
1431 C(i,j) -= v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
1434 for( ; element!=
end; ++element )
1436 const size_t i1( element->index() );
1437 const ET1 v1( element->value() );
1439 C(i,j) -= v1 * B(i1,j);
1463 template<
typename MT
1465 friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1473 subAssign( ~lhs, rhs.lhs_ *
trans( rhs.rhs_ ) );
1505 template<
typename MT
1507 friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1545 template<
typename MT
1547 friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1552 typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
1564 const TmpType tmp( rhs );
1585 template<
typename MT
1587 friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1616 template<
typename MT
1618 friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1656 template<
typename MT
1658 friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1691 template<
typename MT
1693 friend inline typename EnableIf< IsEvaluationRequired<MT,MT1,MT2> >::Type
1731 template<
typename MT
1733 friend inline typename EnableIf< CanExploitSymmetry<MT,MT1,MT2> >::Type
1810 template<
typename T1
1812 inline const SMatTDMatMultExpr<T1,T2>
1836 template<
typename MT1,
typename MT2 >
1853 template<
typename MT1,
typename MT2 >
1870 template<
typename MT1,
typename MT2 >
1871 struct IsAligned<
SMatTDMatMultExpr<MT1,MT2> > :
public IsTrue< IsAligned<MT2>::value >
1887 template<
typename MT1,
typename MT2 >
1889 :
public IsTrue< And< IsLower<MT1>, IsLower<MT2> >::value >
1905 template<
typename MT1,
typename MT2 >
1907 :
public IsTrue< And< IsUniLower<MT1>, IsUniLower<MT2> >::value >
1923 template<
typename MT1,
typename MT2 >
1925 :
public IsTrue< Or< And< IsStrictlyLower<MT1>, IsLower<MT2> >
1926 , And< IsStrictlyLower<MT2>, IsLower<MT1> > >::value >
1942 template<
typename MT1,
typename MT2 >
1944 :
public IsTrue< And< IsUpper<MT1>, IsUpper<MT2> >::value >
1960 template<
typename MT1,
typename MT2 >
1962 :
public IsTrue< And< IsUniUpper<MT1>, IsUniUpper<MT2> >::value >
1978 template<
typename MT1,
typename MT2 >
1980 :
public IsTrue< Or< And< IsStrictlyUpper<MT1>, IsUpper<MT2> >
1981 , And< IsStrictlyUpper<MT2>, IsUpper<MT1> > >::value >
1997 template<
typename MT1,
typename MT2,
typename VT >
2002 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
2003 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
2004 IsDenseVector<VT>::value && IsColumnVector<VT>::value
2005 ,
typename SMatDVecMultExprTrait< MT1, typename TDMatDVecMultExprTrait<MT2,VT>::Type >::Type
2006 , INVALID_TYPE >::Type Type;
2015 template<
typename MT1,
typename MT2,
typename VT >
2020 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
2021 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
2022 IsSparseVector<VT>::value && IsColumnVector<VT>::value
2023 ,
typename SMatDVecMultExprTrait< MT1, typename TDMatSVecMultExprTrait<MT2,VT>::Type >::Type
2024 , INVALID_TYPE >::Type Type;
2033 template<
typename VT,
typename MT1,
typename MT2 >
2038 typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
2039 IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
2040 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
2041 ,
typename TDVecTDMatMultExprTrait< typename TDVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
2042 , INVALID_TYPE >::Type Type;
2051 template<
typename VT,
typename MT1,
typename MT2 >
2056 typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
2057 IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
2058 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
2059 ,
typename TSVecTDMatMultExprTrait< typename TSVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
2060 , INVALID_TYPE >::Type Type;
2069 template<
typename MT1,
typename MT2,
bool AF >
2074 typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
2075 ,
typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
2084 template<
typename MT1,
typename MT2 >
2089 typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
2098 template<
typename MT1,
typename MT2 >
2103 typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatTDMatMultExpr.h:198
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exceptionThis macro encapsulates the default way of...
Definition: Exception.h:187
const ElementType ReturnType
Return type for expression template evaluations.
Definition: SMatTDMatMultExpr.h:201
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1729
ResultType::ElementType ElementType
Resulting element type.
Definition: SMatTDMatMultExpr.h:200
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
Header file for mathematical functions.
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:7820
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.
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:250
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatTDMatMultExpr.h:320
Header file for the IsSparseMatrix type trait.
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:207
#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
Header file for the ColumnExprTrait class template.
Header file for the IsColumnMajorMatrix type trait.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:507
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2588
Header file for the IsRowVector type trait.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:259
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
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatTDMatMultExpr.h:247
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:721
LeftOperand leftOperand() const
Returns the left-hand side sparse matrix operand.
Definition: SMatTDMatMultExpr.h:356
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:90
MT2::CompositeType CT2
Composite type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:138
Constraints on the storage order of matrix types.
Header file for the RequiresEvaluation type trait.
System settings for performance optimizations.
Header file for the TSVecSMatMultExprTrait class template.
RT2::ElementType ET2
Element type of the right-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:136
SMatTDMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the SMatTDMatMultExpr class.
Definition: SMatTDMatMultExpr.h:232
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
MT1::CompositeType CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:137
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:117
LeftOperand lhs_
Left-hand side sparse matrix of the multiplication expression.
Definition: SMatTDMatMultExpr.h:417
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
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.
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:133
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: ColumnMajorMatrix.h:79
Header file for the TSVecTDMatMultExprTrait class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2592
Header file for the Or class template.
Header file for the TDMatSVecMultExprTrait class template.
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exceptionThis macro encapsulates the default way of Bla...
Definition: Exception.h:331
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1682
Header file for the DenseMatrix base class.
Header file for the Columns type trait.
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: SMatTDMatMultExpr.h:197
Header file for the DMatDVecMultExprTrait class template.
Header file for the IsLower type trait.
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTDMatMultExpr.h:205
Header file for the IsAligned type trait.
Expression object for sparse matrix-transpose dense matrix multiplications.The SMatTDMatMultExpr clas...
Definition: Forward.h:110
#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.
Constraints on the storage order of matrix types.
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: SMatTDMatMultExpr.h:378
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2586
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.
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: SMatTDMatMultExpr.h:400
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
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
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
RT1::ElementType ET1
Element type of the left-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:135
Header file for the IsSparseVector type trait.
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: RowMajorMatrix.h:79
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
Header file for run time assertion macros.
Compile time check for column-major matrix types.This type trait tests whether or not the given templ...
Definition: IsColumnMajorMatrix.h:110
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:138
SelectType< evaluateRight, const RT2, CT2 >::Type RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: SMatTDMatMultExpr.h:214
RightOperand rhs_
Right-hand side dense matrix of the multiplication expression.
Definition: SMatTDMatMultExpr.h:418
const bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: SMatTDMatMultExpr.h:390
Header file for the reset shim.
size_t columns() const
Returns the current number of columns of the matrix.
Definition: SMatTDMatMultExpr.h:346
Constraints on the storage order of matrix types.
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
#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:122
Header file for the IsDenseVector type trait.
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
SelectType< evaluateLeft, const RT1, CT1 >::Type LT
Type for the assignment of the left-hand side sparse matrix operand.
Definition: SMatTDMatMultExpr.h:211
size_t rows() const
Returns the current number of rows of the matrix.
Definition: SMatTDMatMultExpr.h:336
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:944
Header file for the IsComputation type trait class.
Header file for the TDVecDMatMultExprTrait class template.
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: SMatTDMatMultExpr.h:410
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
Header file for the TDMatDVecMultExprTrait class template.
#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
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SMatTDMatMultExpr.h:199
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2583
Header file for the IsTrue value trait.
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatTDMatMultExpr.h:202
Header file for the TSVecDMatMultExprTrait class template.
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:208
SMatTDMatMultExpr< MT1, MT2 > This
Type of this SMatTDMatMultExpr instance.
Definition: SMatTDMatMultExpr.h:196
RightOperand rightOperand() const
Returns the right-hand side transpose dense matrix operand.
Definition: SMatTDMatMultExpr.h:366
Header file for the IsUpper type trait.
Header file for exception macros.
MT2::ResultType RT2
Result type of the right-hand side dense matrix expression.
Definition: SMatTDMatMultExpr.h:134
Header file for the DMatSVecMultExprTrait class template.
Header file for the IsColumnVector type trait.
Constraint on the data type.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the TDVecTDMatMultExprTrait class template.
#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.