22 #ifndef _BLAZE_MATH_EXPRESSIONS_TDMATSMATMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_TDMATSMATMULTEXPR_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 };
157 if(
lhs_.columns() != 0 ) {
159 for(
size_t k=1; k<
lhs_.columns(); ++k ) {
187 return rhs_.columns();
217 template<
typename T >
243 template<
typename MT >
250 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
262 for(
size_t i=0; i<A.rows(); ++i ) {
263 for(
size_t j=0; j<(~lhs).
columns(); ++j ) {
264 reset( (~lhs)(i,j) );
266 for(
size_t j=0; j<B.rows(); ++j ) {
267 ConstIterator element( B.begin(j) );
268 const ConstIterator end( B.end(j) );
269 for( ; element!=end; ++element ) {
270 if(
isDefault( (~lhs)(i,element->index()) ) )
271 (~lhs)(i,element->index()) = A(i,j) * element->value();
273 (~lhs)(i,element->index()) += A(i,j) * element->value();
295 template<
typename MT >
302 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
316 for(
size_t i=0; i<B.rows(); ++i ) {
317 ConstIterator element( B.begin(i) );
318 const ConstIterator end( B.end(i) );
319 for( ; element!=end; ++element ) {
320 for(
size_t j=0; j<A.rows(); ++j ) {
321 if(
isDefault( (~lhs)(j,element->index()) ) )
322 (~lhs)(j,element->index()) = A(j,i) * element->value();
324 (~lhs)(j,element->index()) += A(j,i) * element->value();
346 template<
typename MT >
347 friend inline typename DisableIf< IsResizable<typename MT::ElementType> >::Type
353 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
365 const size_t last( A.rows() & size_t(-4) );
367 for(
size_t i=0; i<last; i+=4 ) {
368 for(
size_t j=0; j<(~lhs).
columns(); ++j ) {
369 reset( (~lhs)(i ,j) );
370 reset( (~lhs)(i+1,j) );
371 reset( (~lhs)(i+2,j) );
372 reset( (~lhs)(i+3,j) );
374 for(
size_t j=0; j<B.rows(); ++j ) {
375 ConstIterator element( B.begin(j) );
376 const ConstIterator end( B.end(j) );
377 for( ; element!=end; ++element ) {
378 (~lhs)(i ,element->index()) += A(i ,j) * element->value();
379 (~lhs)(i+1,element->index()) += A(i+1,j) * element->value();
380 (~lhs)(i+2,element->index()) += A(i+2,j) * element->value();
381 (~lhs)(i+3,element->index()) += A(i+3,j) * element->value();
386 for(
size_t i=last; i<A.rows(); ++i ) {
387 for(
size_t j=0; j<(~lhs).
columns(); ++j ) {
388 reset( (~lhs)(i,j) );
390 for(
size_t j=0; j<B.rows(); ++j ) {
391 ConstIterator element( B.begin(j) );
392 const ConstIterator end( B.end(j) );
393 for( ; element!=end; ++element ) {
394 (~lhs)(i,element->index()) += A(i,j) * element->value();
416 template<
typename MT >
417 friend inline typename DisableIf< IsResizable<typename MT::ElementType> >::Type
423 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
437 BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ),
"Invalid end calculation" );
438 const size_t jend( A.rows() & size_t(-4) );
441 for(
size_t i=0UL; i<B.rows(); ++i ) {
442 ConstIterator element( B.begin(i) );
443 const ConstIterator end( B.end(i) );
445 const size_t nonzeros( B.nonZeros(i) );
446 const size_t kend( nonzeros &
size_t(-4) );
448 for(
size_t k=0UL; k<kend; k+=4UL )
450 const size_t i1( element->index() );
451 const ET2 v1( element->value() );
453 const size_t i2( element->index() );
454 const ET2 v2( element->value() );
456 const size_t i3( element->index() );
457 const ET2 v3( element->value() );
459 const size_t i4( element->index() );
460 const ET2 v4( element->value() );
463 for( j=0UL; j<jend; j+=4UL ) {
464 (~lhs)(j ,i1) += A(j ,i) * v1;
465 (~lhs)(j+1UL,i1) += A(j+1UL,i) * v1;
466 (~lhs)(j+2UL,i1) += A(j+2UL,i) * v1;
467 (~lhs)(j+3UL,i1) += A(j+3UL,i) * v1;
468 (~lhs)(j ,i2) += A(j ,i) * v2;
469 (~lhs)(j+1UL,i2) += A(j+1UL,i) * v2;
470 (~lhs)(j+2UL,i2) += A(j+2UL,i) * v2;
471 (~lhs)(j+3UL,i2) += A(j+3UL,i) * v2;
472 (~lhs)(j ,i3) += A(j ,i) * v3;
473 (~lhs)(j+1UL,i3) += A(j+1UL,i) * v3;
474 (~lhs)(j+2UL,i3) += A(j+2UL,i) * v3;
475 (~lhs)(j+3UL,i3) += A(j+3UL,i) * v3;
476 (~lhs)(j ,i4) += A(j ,i) * v4;
477 (~lhs)(j+1UL,i4) += A(j+1UL,i) * v4;
478 (~lhs)(j+2UL,i4) += A(j+2UL,i) * v4;
479 (~lhs)(j+3UL,i4) += A(j+3UL,i) * v4;
481 for( ; j<A.rows(); ++j ) {
482 (~lhs)(j,i1) += A(j,i) * v1;
483 (~lhs)(j,i2) += A(j,i) * v2;
484 (~lhs)(j,i3) += A(j,i) * v3;
485 (~lhs)(j,i4) += A(j,i) * v4;
489 for( ; element!=end; ++element ) {
490 for( j=0UL; j<jend; j+=4UL ) {
491 (~lhs)(j ,element->index()) += A(j ,i) * element->value();
492 (~lhs)(j+1UL,element->index()) += A(j+1UL,i) * element->value();
493 (~lhs)(j+2UL,element->index()) += A(j+2UL,i) * element->value();
494 (~lhs)(j+3UL,element->index()) += A(j+3UL,i) * element->value();
496 for( ; j<A.rows(); ++j ) {
497 (~lhs)(j,element->index()) += A(j,i) * element->value();
517 template<
typename MT
521 typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
533 const TmpType tmp( rhs );
552 template<
typename MT >
558 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
570 BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ),
"Invalid end calculation" );
571 const size_t last( A.rows() & size_t(-4) );
573 for(
size_t i=0UL; i<last; i+=4UL ) {
574 for(
size_t j=0UL; j<B.rows(); ++j ) {
575 ConstIterator element( B.begin(j) );
576 const ConstIterator end( B.end(j) );
577 for( ; element!=end; ++element ) {
578 (~lhs)(i ,element->index()) += A(i ,j) * element->value();
579 (~lhs)(i+1UL,element->index()) += A(i+1UL,j) * element->value();
580 (~lhs)(i+2UL,element->index()) += A(i+2UL,j) * element->value();
581 (~lhs)(i+3UL,element->index()) += A(i+3UL,j) * element->value();
586 for(
size_t i=last; i<A.rows(); ++i ) {
587 for(
size_t j=0UL; j<B.rows(); ++j ) {
588 ConstIterator element( B.begin(j) );
589 const ConstIterator end( B.end(j) );
590 for( ; element!=end; ++element ) {
591 (~lhs)(i,element->index()) += A(i,j) * element->value();
612 template<
typename MT >
618 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
630 BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ),
"Invalid end calculation" );
631 const size_t jend( A.rows() & size_t(-4) );
634 for(
size_t i=0UL; i<B.rows(); ++i ) {
635 ConstIterator element( B.begin(i) );
636 const ConstIterator end( B.end(i) );
638 const size_t nonzeros( B.nonZeros(i) );
639 const size_t kend( nonzeros &
size_t(-4) );
641 for(
size_t k=0UL; k<kend; k+=4UL )
643 const size_t i1( element->index() );
644 const ET2 v1( element->value() );
646 const size_t i2( element->index() );
647 const ET2 v2( element->value() );
649 const size_t i3( element->index() );
650 const ET2 v3( element->value() );
652 const size_t i4( element->index() );
653 const ET2 v4( element->value() );
656 for( j=0UL; j<jend; j+=4UL ) {
657 (~lhs)(j ,i1) += A(j ,i) * v1;
658 (~lhs)(j+1UL,i1) += A(j+1UL,i) * v1;
659 (~lhs)(j+2UL,i1) += A(j+2UL,i) * v1;
660 (~lhs)(j+3UL,i1) += A(j+3UL,i) * v1;
661 (~lhs)(j ,i2) += A(j ,i) * v2;
662 (~lhs)(j+1UL,i2) += A(j+1UL,i) * v2;
663 (~lhs)(j+2UL,i2) += A(j+2UL,i) * v2;
664 (~lhs)(j+3UL,i2) += A(j+3UL,i) * v2;
665 (~lhs)(j ,i3) += A(j ,i) * v3;
666 (~lhs)(j+1UL,i3) += A(j+1UL,i) * v3;
667 (~lhs)(j+2UL,i3) += A(j+2UL,i) * v3;
668 (~lhs)(j+3UL,i3) += A(j+3UL,i) * v3;
669 (~lhs)(j ,i4) += A(j ,i) * v4;
670 (~lhs)(j+1UL,i4) += A(j+1UL,i) * v4;
671 (~lhs)(j+2UL,i4) += A(j+2UL,i) * v4;
672 (~lhs)(j+3UL,i4) += A(j+3UL,i) * v4;
674 for( ; j<A.rows(); ++j ) {
675 (~lhs)(j,i1) += A(j,i) * v1;
676 (~lhs)(j,i2) += A(j,i) * v2;
677 (~lhs)(j,i3) += A(j,i) * v3;
678 (~lhs)(j,i4) += A(j,i) * v4;
682 for( ; element!=end; ++element ) {
683 for( j=0UL; j<jend; j+=4UL ) {
684 (~lhs)(j ,element->index()) += A(j ,i) * element->value();
685 (~lhs)(j+1UL,element->index()) += A(j+1UL,i) * element->value();
686 (~lhs)(j+2UL,element->index()) += A(j+2UL,i) * element->value();
687 (~lhs)(j+3UL,element->index()) += A(j+3UL,i) * element->value();
689 for( ; j<A.rows(); ++j ) {
690 (~lhs)(j,element->index()) += A(j,i) * element->value();
715 template<
typename MT >
721 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
733 BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ),
"Invalid end calculation" );
734 const size_t last( A.rows() & size_t(-4) );
736 for(
size_t i=0UL; i<last; i+=4UL ) {
737 for(
size_t j=0UL; j<B.rows(); ++j ) {
738 ConstIterator element( B.begin(j) );
739 const ConstIterator end( B.end(j) );
740 for( ; element!=end; ++element ) {
741 (~lhs)(i ,element->index()) -= A(i ,j) * element->value();
742 (~lhs)(i+1UL,element->index()) -= A(i+1UL,j) * element->value();
743 (~lhs)(i+2UL,element->index()) -= A(i+2UL,j) * element->value();
744 (~lhs)(i+3UL,element->index()) -= A(i+3UL,j) * element->value();
749 for(
size_t i=last; i<A.rows(); ++i ) {
750 for(
size_t j=0UL; j<B.rows(); ++j ) {
751 ConstIterator element( B.begin(j) );
752 const ConstIterator end( B.end(j) );
753 for( ; element!=end; ++element ) {
754 (~lhs)(i,element->index()) -= A(i,j) * element->value();
775 template<
typename MT >
781 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
793 BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ),
"Invalid end calculation" );
794 const size_t jend( A.rows() & size_t(-4) );
797 for(
size_t i=0UL; i<B.rows(); ++i ) {
798 ConstIterator element( B.begin(i) );
799 const ConstIterator end( B.end(i) );
801 const size_t nonzeros( B.nonZeros(i) );
802 const size_t kend( nonzeros &
size_t(-4) );
804 for(
size_t k=0UL; k<kend; k+=4UL )
806 const size_t i1( element->index() );
807 const ET2 v1( element->value() );
809 const size_t i2( element->index() );
810 const ET2 v2( element->value() );
812 const size_t i3( element->index() );
813 const ET2 v3( element->value() );
815 const size_t i4( element->index() );
816 const ET2 v4( element->value() );
819 for( j=0UL; j<jend; j+=4UL ) {
820 (~lhs)(j ,i1) -= A(j ,i) * v1;
821 (~lhs)(j+1UL,i1) -= A(j+1UL,i) * v1;
822 (~lhs)(j+2UL,i1) -= A(j+2UL,i) * v1;
823 (~lhs)(j+3UL,i1) -= A(j+3UL,i) * v1;
824 (~lhs)(j ,i2) -= A(j ,i) * v2;
825 (~lhs)(j+1UL,i2) -= A(j+1UL,i) * v2;
826 (~lhs)(j+2UL,i2) -= A(j+2UL,i) * v2;
827 (~lhs)(j+3UL,i2) -= A(j+3UL,i) * v2;
828 (~lhs)(j ,i3) -= A(j ,i) * v3;
829 (~lhs)(j+1UL,i3) -= A(j+1UL,i) * v3;
830 (~lhs)(j+2UL,i3) -= A(j+2UL,i) * v3;
831 (~lhs)(j+3UL,i3) -= A(j+3UL,i) * v3;
832 (~lhs)(j ,i4) -= A(j ,i) * v4;
833 (~lhs)(j+1UL,i4) -= A(j+1UL,i) * v4;
834 (~lhs)(j+2UL,i4) -= A(j+2UL,i) * v4;
835 (~lhs)(j+3UL,i4) -= A(j+3UL,i) * v4;
837 for( ; j<A.rows(); ++j ) {
838 (~lhs)(j,i1) -= A(j,i) * v1;
839 (~lhs)(j,i2) -= A(j,i) * v2;
840 (~lhs)(j,i3) -= A(j,i) * v3;
841 (~lhs)(j,i4) -= A(j,i) * v4;
845 for( ; element!=end; ++element ) {
846 for( j=0UL; j<jend; j+=4UL ) {
847 (~lhs)(j ,element->index()) -= A(j ,i) * element->value();
848 (~lhs)(j+1UL,element->index()) -= A(j+1UL,i) * element->value();
849 (~lhs)(j+2UL,element->index()) -= A(j+2UL,i) * element->value();
850 (~lhs)(j+3UL,element->index()) -= A(j+3UL,i) * element->value();
852 for( ; j<A.rows(); ++j ) {
853 (~lhs)(j,element->index()) -= A(j,i) * element->value();
923 template<
typename T1
929 throw std::invalid_argument(
"Matrix sizes do not match" );
946 template<
typename MT1,
typename MT2,
typename VT >
951 typedef typename SelectType< IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
952 IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
953 IsDenseVector<VT>::value && !IsTransposeVector<VT>::value
954 ,
typename TDMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
955 , INVALID_TYPE >::Type Type;
964 template<
typename MT1,
typename MT2,
typename VT >
969 typedef typename SelectType< IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
970 IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
971 IsSparseVector<VT>::value && !IsTransposeVector<VT>::value
972 ,
typename TDMatSVecMultExprTrait< MT1, typename SMatSVecMultExprTrait<MT2,VT>::Type >::Type
973 , INVALID_TYPE >::Type Type;
982 template<
typename VT,
typename MT1,
typename MT2 >
987 typedef typename SelectType< IsDenseVector<VT>::value && IsTransposeVector<VT>::value &&
988 IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
989 IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
990 ,
typename TDMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
991 , INVALID_TYPE >::Type Type;
1000 template<
typename VT,
typename MT1,
typename MT2 >
1005 typedef typename SelectType< IsSparseVector<VT>::value && IsTransposeVector<VT>::value &&
1006 IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1007 IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
1008 ,
typename TDVecSMatMultExprTrait< typename TSVecTDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1009 , INVALID_TYPE >::Type Type;