22 #ifndef _BLAZE_MATH_EXPRESSIONS_DMATSMATMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_DMATSMATMULTEXPR_H_
31 #include <boost/type_traits/remove_reference.hpp>
82 template<
typename MT1
90 typedef typename MT1::ResultType
RT1;
91 typedef typename MT2::ResultType
RT2;
92 typedef typename MT1::CompositeType
CT1;
93 typedef typename MT2::CompositeType
CT2;
121 enum { vectorizable = 0 };
154 if(
lhs_.columns() != 0UL ) {
156 for(
size_t k=1UL; k<
lhs_.columns(); ++k ) {
184 return rhs_.columns();
214 template<
typename T >
240 template<
typename MT >
247 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
259 for(
size_t i=0UL; i<A.rows(); ++i ) {
260 for(
size_t j=0UL; j<(~lhs).
columns(); ++j ) {
261 reset( (~lhs)(i,j) );
263 for(
size_t j=0UL; j<B.rows(); ++j ) {
264 ConstIterator element( B.begin(j) );
265 const ConstIterator end( B.end(j) );
266 for( ; element!=end; ++element ) {
267 if(
isDefault( (~lhs)(i,element->index()) ) )
268 (~lhs)(i,element->index()) = A(i,j) * element->value();
270 (~lhs)(i,element->index()) += A(i,j) * element->value();
292 template<
typename MT >
299 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
313 for(
size_t i=0UL; i<B.rows(); ++i ) {
314 for(
size_t jj=0UL; jj<A.rows(); jj+=8UL ) {
315 const size_t jend( ( jj+8UL > A.rows() )?( A.rows() ):( jj+8UL ) );
316 ConstIterator element( B.begin(i) );
317 const ConstIterator end( B.end(i) );
318 for( ; element!=end; ++element ) {
319 for(
size_t j=jj; j<jend; ++j ) {
320 if(
isDefault( (~lhs)(j,element->index()) ) )
321 (~lhs)(j,element->index()) = A(j,i) * element->value();
323 (~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 BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ),
"Invalid end calculation" );
366 const size_t last( A.rows() & size_t(-4) );
368 for(
size_t i=0UL; i<last; i+=4UL ) {
369 for(
size_t j=0UL; j<(~lhs).
columns(); ++j ) {
370 reset( (~lhs)(i ,j) );
371 reset( (~lhs)(i+1UL,j) );
372 reset( (~lhs)(i+2UL,j) );
373 reset( (~lhs)(i+3UL,j) );
375 for(
size_t j=0UL; j<B.rows(); ++j ) {
376 ConstIterator element( B.begin(j) );
377 const ConstIterator end( B.end(j) );
378 for( ; element!=end; ++element ) {
379 (~lhs)(i ,element->index()) += A(i ,j) * element->value();
380 (~lhs)(i+1UL,element->index()) += A(i+1UL,j) * element->value();
381 (~lhs)(i+2UL,element->index()) += A(i+2UL,j) * element->value();
382 (~lhs)(i+3UL,element->index()) += A(i+3UL,j) * element->value();
387 for(
size_t i=last; i<A.rows(); ++i ) {
388 for(
size_t j=0UL; j<(~lhs).
columns(); ++j ) {
389 reset( (~lhs)(i,j) );
391 for(
size_t j=0UL; j<B.rows(); ++j ) {
392 ConstIterator element( B.begin(j) );
393 const ConstIterator end( B.end(j) );
394 for( ; element!=end; ++element ) {
395 (~lhs)(i,element->index()) += A(i,j) * element->value();
417 template<
typename MT >
418 friend inline typename DisableIf< IsResizable<typename MT::ElementType> >::Type
424 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
438 for(
size_t i=0UL; i<B.rows(); ++i ) {
439 for(
size_t jj=0UL; jj<A.rows(); jj+=8UL ) {
440 const size_t jend( ( jj+8UL > A.rows() )?( A.rows() ):( jj+8UL ) );
441 ConstIterator element( B.begin(i) );
442 const ConstIterator end( B.end(i) );
443 for( ; element!=end; ++element ) {
444 for(
size_t j=jj; j<jend; ++j ) {
445 (~lhs)(j,element->index()) += A(j,i) * element->value();
466 template<
typename MT
470 typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
482 const TmpType tmp( rhs );
501 template<
typename MT >
507 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
519 const size_t last( A.rows() & size_t(-4) );
521 for(
size_t i=0UL; i<last; i+=4UL ) {
522 for(
size_t j=0UL; j<B.rows(); ++j ) {
523 ConstIterator element( B.begin(j) );
524 const ConstIterator end( B.end(j) );
525 for( ; element!=end; ++element ) {
526 (~lhs)(i ,element->index()) += A(i ,j) * element->value();
527 (~lhs)(i+1UL,element->index()) += A(i+1UL,j) * element->value();
528 (~lhs)(i+2UL,element->index()) += A(i+2UL,j) * element->value();
529 (~lhs)(i+3UL,element->index()) += A(i+3UL,j) * element->value();
534 for(
size_t i=last; i<A.rows(); ++i ) {
535 for(
size_t j=0UL; j<B.rows(); ++j ) {
536 ConstIterator element( B.begin(j) );
537 const ConstIterator end( B.end(j) );
538 for( ; element!=end; ++element ) {
539 (~lhs)(i,element->index()) += A(i,j) * element->value();
560 template<
typename MT >
566 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
578 for(
size_t i=0UL; i<B.rows(); ++i ) {
579 for(
size_t jj=0UL; jj<A.rows(); jj+=8UL ) {
580 const size_t jend( ( jj+8UL > A.rows() )?( A.rows() ):( jj+8UL ) );
581 ConstIterator element( B.begin(i) );
582 const ConstIterator end( B.end(i) );
583 for( ; element!=end; ++element ) {
584 for(
size_t j=jj; j<jend; ++j ) {
585 (~lhs)(j,element->index()) += A(j,i) * element->value();
611 template<
typename MT >
617 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
629 const size_t last( A.rows() & size_t(-4) );
631 for(
size_t i=0UL; i<last; i+=4UL ) {
632 for(
size_t j=0UL; j<B.rows(); ++j ) {
633 ConstIterator element( B.begin(j) );
634 const ConstIterator end( B.end(j) );
635 for( ; element!=end; ++element ) {
636 (~lhs)(i ,element->index()) -= A(i ,j) * element->value();
637 (~lhs)(i+1UL,element->index()) -= A(i+1UL,j) * element->value();
638 (~lhs)(i+2UL,element->index()) -= A(i+2UL,j) * element->value();
639 (~lhs)(i+3UL,element->index()) -= A(i+3UL,j) * element->value();
644 for(
size_t i=last; i<A.rows(); ++i ) {
645 for(
size_t j=0UL; j<B.rows(); ++j ) {
646 ConstIterator element( B.begin(j) );
647 const ConstIterator end( B.end(j) );
648 for( ; element!=end; ++element ) {
649 (~lhs)(i,element->index()) -= A(i,j) * element->value();
670 template<
typename MT >
676 typedef typename boost::remove_reference<RT>::type::ConstIterator ConstIterator;
688 for(
size_t i=0UL; i<B.rows(); ++i ) {
689 for(
size_t jj=0UL; jj<A.rows(); jj+=8UL ) {
690 const size_t jend( ( jj+8UL > A.rows() )?( A.rows() ):( jj+8UL ) );
691 ConstIterator element( B.begin(i) );
692 const ConstIterator end( B.end(i) );
693 for( ; element!=end; ++element ) {
694 for(
size_t j=jj; j<jend; ++j ) {
695 (~lhs)(j,element->index()) -= A(j,i) * element->value();
765 template<
typename T1
767 inline const DMatSMatMultExpr<T1,T2>
771 throw std::invalid_argument(
"Matrix sizes do not match" );
788 template<
typename MT1,
typename MT2,
typename VT >
789 struct DMatDVecMultExprTrait< DMatSMatMultExpr<MT1,MT2>, VT >
793 typedef typename SelectType< IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
794 IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
795 IsDenseVector<VT>::value && !IsTransposeVector<VT>::value
796 ,
typename DMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
797 , INVALID_TYPE >::Type Type;
806 template<
typename MT1,
typename MT2,
typename VT >
807 struct DMatSVecMultExprTrait< DMatSMatMultExpr<MT1,MT2>, VT >
811 typedef typename SelectType< IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
812 IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
813 IsSparseVector<VT>::value && !IsTransposeVector<VT>::value
814 ,
typename DMatSVecMultExprTrait< MT1, typename SMatSVecMultExprTrait<MT2,VT>::Type >::Type
815 , INVALID_TYPE >::Type Type;
824 template<
typename VT,
typename MT1,
typename MT2 >
825 struct TDVecDMatMultExprTrait< VT, DMatSMatMultExpr<MT1,MT2> >
829 typedef typename SelectType< IsDenseVector<VT>::value && IsTransposeVector<VT>::value &&
830 IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
831 IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
832 ,
typename TDVecSMatMultExprTrait< typename TDVecDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
833 , INVALID_TYPE >::Type Type;
842 template<
typename VT,
typename MT1,
typename MT2 >
843 struct TSVecDMatMultExprTrait< VT, DMatSMatMultExpr<MT1,MT2> >
847 typedef typename SelectType< IsSparseVector<VT>::value && IsTransposeVector<VT>::value &&
848 IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
849 IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
850 ,
typename TDVecSMatMultExprTrait< typename TDVecDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
851 , INVALID_TYPE >::Type Type;