22 #ifndef _BLAZE_MATH_EXPRESSIONS_TDMATTSMATMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_TDMATTSMATMULTEXPR_H_
31 #include <boost/type_traits/remove_reference.hpp>
83 template<
typename MT1
91 typedef typename MT1::ResultType
RT1;
92 typedef typename MT2::ResultType
RT2;
93 typedef typename MT1::ElementType
ET1;
94 typedef typename MT2::ElementType
ET2;
95 typedef typename MT1::CompositeType
CT1;
96 typedef typename MT2::CompositeType
CT2;
124 enum { vectorizable = 0 };
155 typedef typename boost::remove_reference<CT2>::type::ConstIterator ConstIterator;
160 if(
lhs_.columns() == 0UL )
168 const ConstIterator end( B.end(j) );
169 ConstIterator element( B.begin(j) );
176 tmp =
lhs_(i,element->index()) * element->value();
178 for( ; element!=end; ++element )
179 tmp +=
lhs_(i,element->index()) * element->value();
185 for(
size_t k=1UL; k<
lhs_.columns(); ++k ) {
210 return rhs_.columns();
240 template<
typename T >
266 template<
typename MT >
273 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
285 for(
size_t i=0UL; i<A.rows(); ++i ) {
286 for(
size_t j=0UL; j<B.columns(); ++j )
288 ConstIterator element( B.begin(j) );
289 const ConstIterator end( B.end(j) );
291 if( element == end ) {
292 reset( (~lhs)(i,j) );
296 (~lhs)(i,j) = A(i,element->index()) * element->value();
298 for( ; element!=end; ++element )
299 (~lhs)(i,j) += A(i,element->index()) * element->value();
320 template<
typename MT >
327 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
339 for(
size_t j=0UL; j<B.columns(); ++j ) {
340 for(
size_t i=0UL; i<(~lhs).
rows(); ++i ) {
341 reset( (~lhs)(i,j) );
343 ConstIterator element( B.begin(j) );
344 const ConstIterator end( B.end(j) );
345 for( ; element!=end; ++element ) {
346 for(
size_t i=0UL; i<A.rows(); ++i ) {
347 if(
isDefault( (~lhs)(element->index(),j) ) )
348 (~lhs)(i,j) = A(i,element->index()) * element->value();
350 (~lhs)(i,j) += A(i,element->index()) * element->value();
372 template<
typename MT >
373 friend inline typename DisableIf< IsResizable<typename MT::ElementType> >::Type
379 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
391 BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ),
"Invalid end calculation" );
392 const size_t iend( A.rows() & size_t(-4) );
394 for(
size_t i=0UL; i<iend; i+=4UL ) {
395 for(
size_t j=0UL; j<B.columns(); ++j )
397 ConstIterator element( B.begin(j) );
398 const ConstIterator end( B.end(j) );
400 if( element == end ) {
401 reset( (~lhs)(i ,j) );
402 reset( (~lhs)(i+1UL,j) );
403 reset( (~lhs)(i+2UL,j) );
404 reset( (~lhs)(i+3UL,j) );
408 (~lhs)(i ,j) = A(i ,element->index()) * element->value();
409 (~lhs)(i+1UL,j) = A(i+1UL,element->index()) * element->value();
410 (~lhs)(i+2UL,j) = A(i+2UL,element->index()) * element->value();
411 (~lhs)(i+3UL,j) = A(i+3UL,element->index()) * element->value();
413 for( ; element!=end; ++element ) {
414 (~lhs)(i ,j) += A(i ,element->index()) * element->value();
415 (~lhs)(i+1UL,j) += A(i+1UL,element->index()) * element->value();
416 (~lhs)(i+2UL,j) += A(i+2UL,element->index()) * element->value();
417 (~lhs)(i+3UL,j) += A(i+3UL,element->index()) * element->value();
422 for(
size_t i=iend; i<A.rows(); ++i ) {
423 for(
size_t j=0UL; j<B.columns(); ++j )
425 ConstIterator element( B.begin(j) );
426 const ConstIterator end( B.end(j) );
428 if( element == end ) {
429 reset( (~lhs)(i,j) );
433 (~lhs)(i,j) = A(i,element->index()) * element->value();
435 for( ; element!=end; ++element )
436 (~lhs)(i,j) += A(i,element->index()) * element->value();
457 template<
typename MT >
458 friend inline typename DisableIf< IsResizable<typename MT::ElementType> >::Type
464 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
476 BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ),
"Invalid end calculation" );
477 const size_t iend( A.rows() & size_t(-4) );
479 for(
size_t j=0UL; j<B.columns(); ++j ) {
480 for(
size_t i=0UL; i<iend; i+=4UL ) {
481 reset( (~lhs)(i ,j) );
482 reset( (~lhs)(i+1UL,j) );
483 reset( (~lhs)(i+2UL,j) );
484 reset( (~lhs)(i+3UL,j) );
486 for(
size_t i=iend; i<(~lhs).
rows(); ++i ) {
487 reset( (~lhs)(i,j) );
489 ConstIterator element( B.begin(j) );
490 const ConstIterator end( B.end(j) );
492 while( element!=end )
494 const ET2 v1( element->value() );
495 const size_t i1( element->index() );
498 if( element != end ) {
499 const ET2 v2( element->value() );
500 const size_t i2( element->index() );
503 if( element != end ) {
504 const ET2 v3( element->value() );
505 const size_t i3( element->index() );
508 if( element != end ) {
509 const ET2 v4( element->value() );
510 const size_t i4( element->index() );
513 for(
size_t i=0UL; i<iend; i+=4UL ) {
514 (~lhs)(i ,j) += A(i ,i1) * v1 + A(i ,i2) * v2 + A(i ,i3) * v3 + A(i ,i4) * v4;
515 (~lhs)(i+1UL,j) += A(i+1UL,i1) * v1 + A(i+1UL,i2) * v2 + A(i+1UL,i3) * v3 + A(i+1UL,i4) * v4;
516 (~lhs)(i+2UL,j) += A(i+2UL,i1) * v1 + A(i+2UL,i2) * v2 + A(i+2UL,i3) * v3 + A(i+2UL,i4) * v4;
517 (~lhs)(i+3UL,j) += A(i+3UL,i1) * v1 + A(i+3UL,i2) * v2 + A(i+3UL,i3) * v3 + A(i+3UL,i4) * v4;
519 for(
size_t i=iend; i<A.rows(); ++i ) {
520 (~lhs)(i,j) += A(i,i1) * v1 + A(i,i2) * v2 + A(i,i3) * v3 + A(i,i4) * v4;
524 for(
size_t i=0UL; i<iend; i+=4UL ) {
525 (~lhs)(i ,j) += A(i ,i1) * v1 + A(i ,i2) * v2 + A(i ,i3) * v3;
526 (~lhs)(i+1UL,j) += A(i+1UL,i1) * v1 + A(i+1UL,i2) * v2 + A(i+1UL,i3) * v3;
527 (~lhs)(i+2UL,j) += A(i+2UL,i1) * v1 + A(i+2UL,i2) * v2 + A(i+2UL,i3) * v3;
528 (~lhs)(i+3UL,j) += A(i+3UL,i1) * v1 + A(i+3UL,i2) * v2 + A(i+3UL,i3) * v3;
530 for(
size_t i=iend; i<A.rows(); ++i ) {
531 (~lhs)(i,j) += A(i,i1) * v1 + A(i,i2) * v2 + A(i,i3) * v3;
536 for(
size_t i=0UL; i<iend; i+=4UL ) {
537 (~lhs)(i ,j) += A(i ,i1) * v1 + A(i ,i2) * v2;
538 (~lhs)(i+1UL,j) += A(i+1UL,i1) * v1 + A(i+1UL,i2) * v2;
539 (~lhs)(i+2UL,j) += A(i+2UL,i1) * v1 + A(i+2UL,i2) * v2;
540 (~lhs)(i+3UL,j) += A(i+3UL,i1) * v1 + A(i+3UL,i2) * v2;
542 for(
size_t i=iend; i<A.rows(); ++i ) {
543 (~lhs)(i,j) += A(i,i1) * v1 + A(i,i2) * v2;
548 for(
size_t i=0UL; i<iend; i+=4UL ) {
549 (~lhs)(i ,j) += A(i ,i1) * v1;
550 (~lhs)(i+1UL,j) += A(i+1UL,i1) * v1;
551 (~lhs)(i+2UL,j) += A(i+2UL,i1) * v1;
552 (~lhs)(i+3UL,j) += A(i+3UL,i1) * v1;
554 for(
size_t i=iend; i<A.rows(); ++i ) {
555 (~lhs)(i,j) += A(i,i1) * v1;
576 template<
typename MT
580 typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
592 const TmpType tmp( rhs );
611 template<
typename MT >
617 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
629 BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ),
"Invalid end calculation" );
630 const size_t iend( A.rows() & size_t(-4) );
632 for(
size_t i=0UL; i<iend; i+=4UL ) {
633 for(
size_t j=0UL; j<B.columns(); ++j )
635 ConstIterator element( B.begin(j) );
636 const ConstIterator end( B.end(j) );
638 for( ; element!=end; ++element ) {
639 (~lhs)(i ,j) += A(i ,element->index()) * element->value();
640 (~lhs)(i+1UL,j) += A(i+1UL,element->index()) * element->value();
641 (~lhs)(i+2UL,j) += A(i+2UL,element->index()) * element->value();
642 (~lhs)(i+3UL,j) += A(i+3UL,element->index()) * element->value();
647 for(
size_t i=iend; i<A.rows(); ++i ) {
648 for(
size_t j=0UL; j<B.columns(); ++j )
650 ConstIterator element( B.begin(j) );
651 const ConstIterator end( B.end(j) );
653 for( ; element!=end; ++element )
654 (~lhs)(i,j) += A(i,element->index()) * element->value();
674 template<
typename MT >
680 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
692 BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ),
"Invalid end calculation" );
693 const size_t iend( A.rows() & size_t(-4) );
695 for(
size_t j=0UL; j<B.columns(); ++j )
697 ConstIterator element( B.begin(j) );
698 const ConstIterator end( B.end(j) );
700 while( element!=end )
702 const ET2 v1( element->value() );
703 const size_t i1( element->index() );
706 if( element != end ) {
707 const ET2 v2( element->value() );
708 const size_t i2( element->index() );
711 if( element != end ) {
712 const ET2 v3( element->value() );
713 const size_t i3( element->index() );
716 if( element != end ) {
717 const ET2 v4( element->value() );
718 const size_t i4( element->index() );
721 for(
size_t i=0UL; i<iend; i+=4UL ) {
722 (~lhs)(i ,j) += A(i ,i1) * v1 + A(i ,i2) * v2 + A(i ,i3) * v3 + A(i ,i4) * v4;
723 (~lhs)(i+1UL,j) += A(i+1UL,i1) * v1 + A(i+1UL,i2) * v2 + A(i+1UL,i3) * v3 + A(i+1UL,i4) * v4;
724 (~lhs)(i+2UL,j) += A(i+2UL,i1) * v1 + A(i+2UL,i2) * v2 + A(i+2UL,i3) * v3 + A(i+2UL,i4) * v4;
725 (~lhs)(i+3UL,j) += A(i+3UL,i1) * v1 + A(i+3UL,i2) * v2 + A(i+3UL,i3) * v3 + A(i+3UL,i4) * v4;
727 for(
size_t i=iend; i<A.rows(); ++i ) {
728 (~lhs)(i,j) += A(i,i1) * v1 + A(i,i2) * v2 + A(i,i3) * v3 + A(i,i4) * v4;
732 for(
size_t i=0UL; i<iend; i+=4UL ) {
733 (~lhs)(i ,j) += A(i ,i1) * v1 + A(i ,i2) * v2 + A(i ,i3) * v3;
734 (~lhs)(i+1UL,j) += A(i+1UL,i1) * v1 + A(i+1UL,i2) * v2 + A(i+1UL,i3) * v3;
735 (~lhs)(i+2UL,j) += A(i+2UL,i1) * v1 + A(i+2UL,i2) * v2 + A(i+2UL,i3) * v3;
736 (~lhs)(i+3UL,j) += A(i+3UL,i1) * v1 + A(i+3UL,i2) * v2 + A(i+3UL,i3) * v3;
738 for(
size_t i=iend; i<A.rows(); ++i ) {
739 (~lhs)(i,j) += A(i,i1) * v1 + A(i,i2) * v2 + A(i,i3) * v3;
744 for(
size_t i=0UL; i<iend; i+=4UL ) {
745 (~lhs)(i ,j) += A(i ,i1) * v1 + A(i ,i2) * v2;
746 (~lhs)(i+1UL,j) += A(i+1UL,i1) * v1 + A(i+1UL,i2) * v2;
747 (~lhs)(i+2UL,j) += A(i+2UL,i1) * v1 + A(i+2UL,i2) * v2;
748 (~lhs)(i+3UL,j) += A(i+3UL,i1) * v1 + A(i+3UL,i2) * v2;
750 for(
size_t i=iend; i<A.rows(); ++i ) {
751 (~lhs)(i,j) += A(i,i1) * v1 + A(i,i2) * v2;
756 for(
size_t i=0UL; i<iend; i+=4UL ) {
757 (~lhs)(i ,j) += A(i ,i1) * v1;
758 (~lhs)(i+1UL,j) += A(i+1UL,i1) * v1;
759 (~lhs)(i+2UL,j) += A(i+2UL,i1) * v1;
760 (~lhs)(i+3UL,j) += A(i+3UL,i1) * v1;
762 for(
size_t i=iend; i<A.rows(); ++i ) {
763 (~lhs)(i,j) += A(i,i1) * v1;
789 template<
typename MT >
795 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
807 BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ),
"Invalid end calculation" );
808 const size_t iend( A.rows() & size_t(-4) );
810 for(
size_t i=0UL; i<iend; i+=4 ) {
811 for(
size_t j=0UL; j<B.columns(); ++j )
813 ConstIterator element( B.begin(j) );
814 const ConstIterator end( B.end(j) );
816 for( ; element!=end; ++element ) {
817 (~lhs)(i ,j) -= A(i ,element->index()) * element->value();
818 (~lhs)(i+1UL,j) -= A(i+1UL,element->index()) * element->value();
819 (~lhs)(i+2UL,j) -= A(i+2UL,element->index()) * element->value();
820 (~lhs)(i+3UL,j) -= A(i+3UL,element->index()) * element->value();
825 for(
size_t i=iend; i<A.rows(); ++i ) {
826 for(
size_t j=0UL; j<B.columns(); ++j )
828 ConstIterator element( B.begin(j) );
829 const ConstIterator end( B.end(j) );
831 for( ; element!=end; ++element )
832 (~lhs)(i,j) -= A(i,element->index()) * element->value();
852 template<
typename MT >
858 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
870 BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ),
"Invalid end calculation" );
871 const size_t iend( A.rows() & size_t(-4) );
873 for(
size_t j=0UL; j<B.columns(); ++j )
875 ConstIterator element( B.begin(j) );
876 const ConstIterator end( B.end(j) );
878 while( element!=end )
880 const ET2 v1( element->value() );
881 const size_t i1( element->index() );
884 if( element != end ) {
885 const ET2 v2( element->value() );
886 const size_t i2( element->index() );
889 if( element != end ) {
890 const ET2 v3( element->value() );
891 const size_t i3( element->index() );
894 if( element != end ) {
895 const ET2 v4( element->value() );
896 const size_t i4( element->index() );
899 for(
size_t i=0UL; i<iend; i+=4UL ) {
900 (~lhs)(i ,j) -= A(i ,i1) * v1 + A(i ,i2) * v2 + A(i ,i3) * v3 + A(i ,i4) * v4;
901 (~lhs)(i+1UL,j) -= A(i+1UL,i1) * v1 + A(i+1UL,i2) * v2 + A(i+1UL,i3) * v3 + A(i+1UL,i4) * v4;
902 (~lhs)(i+2UL,j) -= A(i+2UL,i1) * v1 + A(i+2UL,i2) * v2 + A(i+2UL,i3) * v3 + A(i+2UL,i4) * v4;
903 (~lhs)(i+3UL,j) -= A(i+3UL,i1) * v1 + A(i+3UL,i2) * v2 + A(i+3UL,i3) * v3 + A(i+3UL,i4) * v4;
905 for(
size_t i=iend; i<A.rows(); ++i ) {
906 (~lhs)(i,j) -= A(i,i1) * v1 + A(i,i2) * v2 + A(i,i3) * v3 + A(i,i4) * v4;
910 for(
size_t i=0UL; i<iend; i+=4UL ) {
911 (~lhs)(i ,j) -= A(i ,i1) * v1 + A(i ,i2) * v2 + A(i ,i3) * v3;
912 (~lhs)(i+1UL,j) -= A(i+1UL,i1) * v1 + A(i+1UL,i2) * v2 + A(i+1UL,i3) * v3;
913 (~lhs)(i+2UL,j) -= A(i+2UL,i1) * v1 + A(i+2UL,i2) * v2 + A(i+2UL,i3) * v3;
914 (~lhs)(i+3UL,j) -= A(i+3UL,i1) * v1 + A(i+3UL,i2) * v2 + A(i+3UL,i3) * v3;
916 for(
size_t i=iend; i<A.rows(); ++i ) {
917 (~lhs)(i,j) -= A(i,i1) * v1 + A(i,i2) * v2 + A(i,i3) * v3;
922 for(
size_t i=0UL; i<iend; i+=4UL ) {
923 (~lhs)(i ,j) -= A(i ,i1) * v1 + A(i ,i2) * v2;
924 (~lhs)(i+1UL,j) -= A(i+1UL,i1) * v1 + A(i+1UL,i2) * v2;
925 (~lhs)(i+2UL,j) -= A(i+2UL,i1) * v1 + A(i+2UL,i2) * v2;
926 (~lhs)(i+3UL,j) -= A(i+3UL,i1) * v1 + A(i+3UL,i2) * v2;
928 for(
size_t i=iend; i<A.rows(); ++i ) {
929 (~lhs)(i,j) -= A(i,i1) * v1 + A(i,i2) * v2;
934 for(
size_t i=0UL; i<iend; i+=4UL ) {
935 (~lhs)(i ,j) -= A(i ,i1) * v1;
936 (~lhs)(i+1UL,j) -= A(i+1UL,i1) * v1;
937 (~lhs)(i+2UL,j) -= A(i+2UL,i1) * v1;
938 (~lhs)(i+3UL,j) -= A(i+3UL,i1) * v1;
940 for(
size_t i=iend; i<A.rows(); ++i ) {
941 (~lhs)(i,j) -= A(i,i1) * v1;
1011 template<
typename T1
1017 throw std::invalid_argument(
"Matrix sizes do not match" );
1034 template<
typename MT1,
typename MT2,
typename VT >
1039 typedef typename SelectType< IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1040 IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1041 IsDenseVector<VT>::value && !IsTransposeVector<VT>::value
1042 ,
typename TDMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
1043 , INVALID_TYPE >::Type Type;
1052 template<
typename MT1,
typename MT2,
typename VT >
1057 typedef typename SelectType< IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1058 IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1059 IsSparseVector<VT>::value && !IsTransposeVector<VT>::value
1060 ,
typename TDMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
1061 , INVALID_TYPE >::Type Type;
1070 template<
typename VT,
typename MT1,
typename MT2 >
1075 typedef typename SelectType< IsDenseVector<VT>::value && IsTransposeVector<VT>::value &&
1076 IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1077 IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1078 ,
typename TDVecTSMatMultExprTrait< typename TDVecTDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1079 , INVALID_TYPE >::Type Type;
1088 template<
typename VT,
typename MT1,
typename MT2 >
1093 typedef typename SelectType< IsSparseVector<VT>::value && IsTransposeVector<VT>::value &&
1094 IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1095 IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1096 ,
typename TDVecTSMatMultExprTrait< typename TSVecTDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1097 , INVALID_TYPE >::Type Type;