22 #ifndef _BLAZE_MATH_EXPRESSIONS_TDMATSMATMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_TDMATSMATMULTEXPR_H_
31 #include <boost/type_traits/remove_reference.hpp>
87 template<
typename MT1
89 class TDMatSMatMultExpr :
public DenseMatrix< TDMatSMatMultExpr<MT1,MT2>, true >
95 typedef typename MT1::ResultType
RT1;
96 typedef typename MT2::ResultType
RT2;
97 typedef typename MT1::ElementType
ET1;
98 typedef typename MT2::ElementType
ET2;
99 typedef typename MT1::CompositeType
CT1;
100 typedef typename MT2::CompositeType
CT2;
128 enum { vectorizable = 0 };
158 if(
lhs_.columns() != 0 ) {
160 for(
size_t k=1; k<
lhs_.columns(); ++k ) {
188 return rhs_.columns();
218 template<
typename T >
220 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
230 template<
typename T >
232 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
256 template<
typename MT >
265 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
277 for(
size_t i=0; i<A.rows(); ++i ) {
278 for(
size_t j=0; j<(~lhs).
columns(); ++j ) {
279 reset( (~lhs)(i,j) );
281 for(
size_t j=0; j<B.rows(); ++j ) {
282 ConstIterator element( B.begin(j) );
283 const ConstIterator end( B.end(j) );
284 for( ; element!=end; ++element ) {
285 if(
isDefault( (~lhs)(i,element->index()) ) )
286 (~lhs)(i,element->index()) = A(i,j) * element->value();
288 (~lhs)(i,element->index()) += A(i,j) * element->value();
310 template<
typename MT >
319 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
333 for(
size_t i=0; i<B.rows(); ++i ) {
334 ConstIterator element( B.begin(i) );
335 const ConstIterator end( B.end(i) );
336 for( ; element!=end; ++element ) {
337 for(
size_t j=0; j<A.rows(); ++j ) {
338 if(
isDefault( (~lhs)(j,element->index()) ) )
339 (~lhs)(j,element->index()) = A(j,i) * element->value();
341 (~lhs)(j,element->index()) += A(j,i) * element->value();
363 template<
typename MT >
364 friend inline typename DisableIf< IsResizable<typename MT::ElementType> >::Type
372 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
384 const size_t last( A.rows() & size_t(-4) );
386 for(
size_t i=0; i<last; i+=4 ) {
387 for(
size_t j=0; j<(~lhs).
columns(); ++j ) {
388 reset( (~lhs)(i ,j) );
389 reset( (~lhs)(i+1,j) );
390 reset( (~lhs)(i+2,j) );
391 reset( (~lhs)(i+3,j) );
393 for(
size_t j=0; j<B.rows(); ++j ) {
394 ConstIterator element( B.begin(j) );
395 const ConstIterator end( B.end(j) );
396 for( ; element!=end; ++element ) {
397 (~lhs)(i ,element->index()) += A(i ,j) * element->value();
398 (~lhs)(i+1,element->index()) += A(i+1,j) * element->value();
399 (~lhs)(i+2,element->index()) += A(i+2,j) * element->value();
400 (~lhs)(i+3,element->index()) += A(i+3,j) * element->value();
405 for(
size_t i=last; i<A.rows(); ++i ) {
406 for(
size_t j=0; j<(~lhs).
columns(); ++j ) {
407 reset( (~lhs)(i,j) );
409 for(
size_t j=0; j<B.rows(); ++j ) {
410 ConstIterator element( B.begin(j) );
411 const ConstIterator end( B.end(j) );
412 for( ; element!=end; ++element ) {
413 (~lhs)(i,element->index()) += A(i,j) * element->value();
435 template<
typename MT >
436 friend inline typename DisableIf< IsResizable<typename MT::ElementType> >::Type
444 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
458 BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ),
"Invalid end calculation" );
459 const size_t jend( A.rows() & size_t(-4) );
462 for(
size_t i=0UL; i<B.rows(); ++i ) {
463 ConstIterator element( B.begin(i) );
464 const ConstIterator end( B.end(i) );
466 const size_t nonzeros( B.nonZeros(i) );
467 const size_t kend( nonzeros &
size_t(-4) );
469 for(
size_t k=0UL; k<kend; k+=4UL )
471 const size_t i1( element->index() );
472 const ET2 v1( element->value() );
474 const size_t i2( element->index() );
475 const ET2 v2( element->value() );
477 const size_t i3( element->index() );
478 const ET2 v3( element->value() );
480 const size_t i4( element->index() );
481 const ET2 v4( element->value() );
484 for( j=0UL; j<jend; j+=4UL ) {
485 (~lhs)(j ,i1) += A(j ,i) * v1;
486 (~lhs)(j+1UL,i1) += A(j+1UL,i) * v1;
487 (~lhs)(j+2UL,i1) += A(j+2UL,i) * v1;
488 (~lhs)(j+3UL,i1) += A(j+3UL,i) * v1;
489 (~lhs)(j ,i2) += A(j ,i) * v2;
490 (~lhs)(j+1UL,i2) += A(j+1UL,i) * v2;
491 (~lhs)(j+2UL,i2) += A(j+2UL,i) * v2;
492 (~lhs)(j+3UL,i2) += A(j+3UL,i) * v2;
493 (~lhs)(j ,i3) += A(j ,i) * v3;
494 (~lhs)(j+1UL,i3) += A(j+1UL,i) * v3;
495 (~lhs)(j+2UL,i3) += A(j+2UL,i) * v3;
496 (~lhs)(j+3UL,i3) += A(j+3UL,i) * v3;
497 (~lhs)(j ,i4) += A(j ,i) * v4;
498 (~lhs)(j+1UL,i4) += A(j+1UL,i) * v4;
499 (~lhs)(j+2UL,i4) += A(j+2UL,i) * v4;
500 (~lhs)(j+3UL,i4) += A(j+3UL,i) * v4;
502 for( ; j<A.rows(); ++j ) {
503 (~lhs)(j,i1) += A(j,i) * v1;
504 (~lhs)(j,i2) += A(j,i) * v2;
505 (~lhs)(j,i3) += A(j,i) * v3;
506 (~lhs)(j,i4) += A(j,i) * v4;
510 for( ; element!=end; ++element ) {
511 for( j=0UL; j<jend; j+=4UL ) {
512 (~lhs)(j ,element->index()) += A(j ,i) * element->value();
513 (~lhs)(j+1UL,element->index()) += A(j+1UL,i) * element->value();
514 (~lhs)(j+2UL,element->index()) += A(j+2UL,i) * element->value();
515 (~lhs)(j+3UL,element->index()) += A(j+3UL,i) * element->value();
517 for( ; j<A.rows(); ++j ) {
518 (~lhs)(j,element->index()) += A(j,i) * element->value();
538 template<
typename MT
544 typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
556 const TmpType tmp( rhs );
575 template<
typename MT >
583 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
595 BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ),
"Invalid end calculation" );
596 const size_t last( A.rows() & size_t(-4) );
598 for(
size_t i=0UL; i<last; i+=4UL ) {
599 for(
size_t j=0UL; j<B.rows(); ++j ) {
600 ConstIterator element( B.begin(j) );
601 const ConstIterator end( B.end(j) );
602 for( ; element!=end; ++element ) {
603 (~lhs)(i ,element->index()) += A(i ,j) * element->value();
604 (~lhs)(i+1UL,element->index()) += A(i+1UL,j) * element->value();
605 (~lhs)(i+2UL,element->index()) += A(i+2UL,j) * element->value();
606 (~lhs)(i+3UL,element->index()) += A(i+3UL,j) * element->value();
611 for(
size_t i=last; i<A.rows(); ++i ) {
612 for(
size_t j=0UL; j<B.rows(); ++j ) {
613 ConstIterator element( B.begin(j) );
614 const ConstIterator end( B.end(j) );
615 for( ; element!=end; ++element ) {
616 (~lhs)(i,element->index()) += A(i,j) * element->value();
637 template<
typename MT >
645 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
657 BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ),
"Invalid end calculation" );
658 const size_t jend( A.rows() & size_t(-4) );
661 for(
size_t i=0UL; i<B.rows(); ++i ) {
662 ConstIterator element( B.begin(i) );
663 const ConstIterator end( B.end(i) );
665 const size_t nonzeros( B.nonZeros(i) );
666 const size_t kend( nonzeros &
size_t(-4) );
668 for(
size_t k=0UL; k<kend; k+=4UL )
670 const size_t i1( element->index() );
671 const ET2 v1( element->value() );
673 const size_t i2( element->index() );
674 const ET2 v2( element->value() );
676 const size_t i3( element->index() );
677 const ET2 v3( element->value() );
679 const size_t i4( element->index() );
680 const ET2 v4( element->value() );
683 for( j=0UL; j<jend; j+=4UL ) {
684 (~lhs)(j ,i1) += A(j ,i) * v1;
685 (~lhs)(j+1UL,i1) += A(j+1UL,i) * v1;
686 (~lhs)(j+2UL,i1) += A(j+2UL,i) * v1;
687 (~lhs)(j+3UL,i1) += A(j+3UL,i) * v1;
688 (~lhs)(j ,i2) += A(j ,i) * v2;
689 (~lhs)(j+1UL,i2) += A(j+1UL,i) * v2;
690 (~lhs)(j+2UL,i2) += A(j+2UL,i) * v2;
691 (~lhs)(j+3UL,i2) += A(j+3UL,i) * v2;
692 (~lhs)(j ,i3) += A(j ,i) * v3;
693 (~lhs)(j+1UL,i3) += A(j+1UL,i) * v3;
694 (~lhs)(j+2UL,i3) += A(j+2UL,i) * v3;
695 (~lhs)(j+3UL,i3) += A(j+3UL,i) * v3;
696 (~lhs)(j ,i4) += A(j ,i) * v4;
697 (~lhs)(j+1UL,i4) += A(j+1UL,i) * v4;
698 (~lhs)(j+2UL,i4) += A(j+2UL,i) * v4;
699 (~lhs)(j+3UL,i4) += A(j+3UL,i) * v4;
701 for( ; j<A.rows(); ++j ) {
702 (~lhs)(j,i1) += A(j,i) * v1;
703 (~lhs)(j,i2) += A(j,i) * v2;
704 (~lhs)(j,i3) += A(j,i) * v3;
705 (~lhs)(j,i4) += A(j,i) * v4;
709 for( ; element!=end; ++element ) {
710 for( j=0UL; j<jend; j+=4UL ) {
711 (~lhs)(j ,element->index()) += A(j ,i) * element->value();
712 (~lhs)(j+1UL,element->index()) += A(j+1UL,i) * element->value();
713 (~lhs)(j+2UL,element->index()) += A(j+2UL,i) * element->value();
714 (~lhs)(j+3UL,element->index()) += A(j+3UL,i) * element->value();
716 for( ; j<A.rows(); ++j ) {
717 (~lhs)(j,element->index()) += A(j,i) * element->value();
742 template<
typename MT >
750 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
762 BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ),
"Invalid end calculation" );
763 const size_t last( A.rows() & size_t(-4) );
765 for(
size_t i=0UL; i<last; i+=4UL ) {
766 for(
size_t j=0UL; j<B.rows(); ++j ) {
767 ConstIterator element( B.begin(j) );
768 const ConstIterator end( B.end(j) );
769 for( ; element!=end; ++element ) {
770 (~lhs)(i ,element->index()) -= A(i ,j) * element->value();
771 (~lhs)(i+1UL,element->index()) -= A(i+1UL,j) * element->value();
772 (~lhs)(i+2UL,element->index()) -= A(i+2UL,j) * element->value();
773 (~lhs)(i+3UL,element->index()) -= A(i+3UL,j) * element->value();
778 for(
size_t i=last; i<A.rows(); ++i ) {
779 for(
size_t j=0UL; j<B.rows(); ++j ) {
780 ConstIterator element( B.begin(j) );
781 const ConstIterator end( B.end(j) );
782 for( ; element!=end; ++element ) {
783 (~lhs)(i,element->index()) -= A(i,j) * element->value();
804 template<
typename MT >
812 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
824 BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ),
"Invalid end calculation" );
825 const size_t jend( A.rows() & size_t(-4) );
828 for(
size_t i=0UL; i<B.rows(); ++i ) {
829 ConstIterator element( B.begin(i) );
830 const ConstIterator end( B.end(i) );
832 const size_t nonzeros( B.nonZeros(i) );
833 const size_t kend( nonzeros &
size_t(-4) );
835 for(
size_t k=0UL; k<kend; k+=4UL )
837 const size_t i1( element->index() );
838 const ET2 v1( element->value() );
840 const size_t i2( element->index() );
841 const ET2 v2( element->value() );
843 const size_t i3( element->index() );
844 const ET2 v3( element->value() );
846 const size_t i4( element->index() );
847 const ET2 v4( element->value() );
850 for( j=0UL; j<jend; j+=4UL ) {
851 (~lhs)(j ,i1) -= A(j ,i) * v1;
852 (~lhs)(j+1UL,i1) -= A(j+1UL,i) * v1;
853 (~lhs)(j+2UL,i1) -= A(j+2UL,i) * v1;
854 (~lhs)(j+3UL,i1) -= A(j+3UL,i) * v1;
855 (~lhs)(j ,i2) -= A(j ,i) * v2;
856 (~lhs)(j+1UL,i2) -= A(j+1UL,i) * v2;
857 (~lhs)(j+2UL,i2) -= A(j+2UL,i) * v2;
858 (~lhs)(j+3UL,i2) -= A(j+3UL,i) * v2;
859 (~lhs)(j ,i3) -= A(j ,i) * v3;
860 (~lhs)(j+1UL,i3) -= A(j+1UL,i) * v3;
861 (~lhs)(j+2UL,i3) -= A(j+2UL,i) * v3;
862 (~lhs)(j+3UL,i3) -= A(j+3UL,i) * v3;
863 (~lhs)(j ,i4) -= A(j ,i) * v4;
864 (~lhs)(j+1UL,i4) -= A(j+1UL,i) * v4;
865 (~lhs)(j+2UL,i4) -= A(j+2UL,i) * v4;
866 (~lhs)(j+3UL,i4) -= A(j+3UL,i) * v4;
868 for( ; j<A.rows(); ++j ) {
869 (~lhs)(j,i1) -= A(j,i) * v1;
870 (~lhs)(j,i2) -= A(j,i) * v2;
871 (~lhs)(j,i3) -= A(j,i) * v3;
872 (~lhs)(j,i4) -= A(j,i) * v4;
876 for( ; element!=end; ++element ) {
877 for( j=0UL; j<jend; j+=4UL ) {
878 (~lhs)(j ,element->index()) -= A(j ,i) * element->value();
879 (~lhs)(j+1UL,element->index()) -= A(j+1UL,i) * element->value();
880 (~lhs)(j+2UL,element->index()) -= A(j+2UL,i) * element->value();
881 (~lhs)(j+3UL,element->index()) -= A(j+3UL,i) * element->value();
883 for( ; j<A.rows(); ++j ) {
884 (~lhs)(j,element->index()) -= A(j,i) * element->value();
954 template<
typename T1
956 inline const TDMatSMatMultExpr<T1,T2>
962 throw std::invalid_argument(
"Matrix sizes do not match" );
990 template<
typename MT1
992 inline typename RowExprTrait< TDMatSMatMultExpr<MT1,MT2> >::Type
993 row(
const TDMatSMatMultExpr<MT1,MT2>& dm,
size_t index )
997 return row( dm.leftOperand(), index ) * dm.rightOperand();
1016 template<
typename MT1
1018 inline typename ColumnExprTrait< TDMatSMatMultExpr<MT1,MT2> >::Type
1019 column(
const TDMatSMatMultExpr<MT1,MT2>& dm,
size_t index )
1023 return dm.leftOperand() *
column( dm.rightOperand(), index );
1039 template<
typename MT1,
typename MT2,
typename VT >
1040 struct TDMatDVecMultExprTrait< TDMatSMatMultExpr<MT1,MT2>, VT >
1044 typedef typename SelectType< IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1045 IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
1046 IsDenseVector<VT>::value && !IsTransposeVector<VT>::value
1047 ,
typename TDMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
1048 , INVALID_TYPE >::Type Type;
1057 template<
typename MT1,
typename MT2,
typename VT >
1058 struct TDMatSVecMultExprTrait< TDMatSMatMultExpr<MT1,MT2>, VT >
1062 typedef typename SelectType< IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1063 IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
1064 IsSparseVector<VT>::value && !IsTransposeVector<VT>::value
1065 ,
typename TDMatSVecMultExprTrait< MT1, typename SMatSVecMultExprTrait<MT2,VT>::Type >::Type
1066 , INVALID_TYPE >::Type Type;
1075 template<
typename VT,
typename MT1,
typename MT2 >
1076 struct TDVecTDMatMultExprTrait< VT, TDMatSMatMultExpr<MT1,MT2> >
1080 typedef typename SelectType< IsDenseVector<VT>::value && IsTransposeVector<VT>::value &&
1081 IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1082 IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
1083 ,
typename TDMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
1084 , INVALID_TYPE >::Type Type;
1093 template<
typename VT,
typename MT1,
typename MT2 >
1094 struct TSVecTDMatMultExprTrait< VT, TDMatSMatMultExpr<MT1,MT2> >
1098 typedef typename SelectType< IsSparseVector<VT>::value && IsTransposeVector<VT>::value &&
1099 IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1100 IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
1101 ,
typename TDVecSMatMultExprTrait< typename TSVecTDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1102 , INVALID_TYPE >::Type Type;
1111 template<
typename MT1,
typename MT2 >
1112 struct RowExprTrait< TDMatSMatMultExpr<MT1,MT2> >
1116 typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1125 template<
typename MT1,
typename MT2 >
1126 struct ColumnExprTrait< TDMatSMatMultExpr<MT1,MT2> >
1130 typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;