22 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATTDMATMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_TSMATTDMATMULTEXPR_H_
31 #include <boost/type_traits/remove_reference.hpp>
84 template<
typename MT1
86 class TSMatTDMatMultExpr :
public DenseMatrix< TSMatTDMatMultExpr<MT1,MT2>, true >
92 typedef typename MT1::ResultType
RT1;
93 typedef typename MT2::ResultType
RT2;
94 typedef typename MT1::ElementType
ET1;
95 typedef typename MT2::ElementType
ET2;
96 typedef typename MT1::CompositeType
CT1;
97 typedef typename MT2::CompositeType
CT2;
125 enum { vectorizable = 0 };
155 if(
lhs_.columns() != 0UL ) {
157 for(
size_t k=1UL; k<
lhs_.columns(); ++k ) {
185 return rhs_.columns();
215 template<
typename T >
217 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
227 template<
typename T >
229 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
253 template<
typename MT
263 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
277 const size_t block( 64UL );
279 for(
size_t jj=0UL; jj<B.columns(); jj+=block ) {
280 const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
281 for(
size_t i=0UL; i<A.columns(); ++i ) {
282 const ConstIterator end( A.end(i) );
283 ConstIterator element( A.begin(i) );
284 for( ; element!=end; ++element ) {
285 for(
size_t j=jj; j<jend; ++j ) {
286 if(
isDefault( (~lhs)(element->index(),j) ) )
287 (~lhs)(element->index(),j) = element->value() * B(i,j);
289 (~lhs)(element->index(),j) += element->value() * B(i,j);
312 template<
typename MT
322 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
334 const size_t block( SO ? 64UL : 128UL );
336 for(
size_t jj=0UL; jj<B.columns(); jj+=block ) {
337 const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
338 for(
size_t i=0UL; i<A.rows(); ++i ) {
339 for(
size_t j=jj; j<jend; ++j ) {
340 reset( (~lhs)(i,j) );
343 for(
size_t i=0UL; i<A.columns(); ++i )
345 const ConstIterator end( A.end(i) );
346 ConstIterator element( A.begin(i) );
348 const size_t nonzeros( A.nonZeros(i) );
350 BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == ( nonzeros &
size_t(-4) ),
"Invalid end calculation" );
351 const size_t kend( nonzeros &
size_t(-4) );
353 for(
size_t k=0UL; k<kend; k+=4UL ) {
354 const size_t i1( element->index() );
355 const ET1 v1( element->value() );
357 const size_t i2( element->index() );
358 const ET1 v2( element->value() );
360 const size_t i3( element->index() );
361 const ET1 v3( element->value() );
363 const size_t i4( element->index() );
364 const ET1 v4( element->value() );
367 for(
size_t j=jj; j<jend; ++j ) {
368 (~lhs)(i1,j) += v1 * B(i,j);
369 (~lhs)(i2,j) += v2 * B(i,j);
370 (~lhs)(i3,j) += v3 * B(i,j);
371 (~lhs)(i4,j) += v4 * B(i,j);
375 for( ; element!=end; ++element ) {
376 for(
size_t j=jj; j<jend; ++j ) {
377 (~lhs)(element->index(),j) += element->value() * B(i,j);
399 template<
typename MT
405 typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
417 const TmpType tmp( rhs );
436 template<
typename MT
445 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
457 const size_t block( SO ? 64UL : 128UL );
459 for(
size_t jj=0UL; jj<B.columns(); jj+=block ) {
460 const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
461 for(
size_t i=0UL; i<A.columns(); ++i )
463 const ConstIterator end( A.end(i) );
464 ConstIterator element( A.begin(i) );
466 const size_t nonzeros( A.nonZeros(i) );
468 BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == ( nonzeros &
size_t(-4) ),
"Invalid end calculation" );
469 const size_t kend( nonzeros &
size_t(-4) );
471 for(
size_t k=0UL; k<kend; k+=4UL ) {
472 const size_t i1( element->index() );
473 const ET1 v1( element->value() );
475 const size_t i2( element->index() );
476 const ET1 v2( element->value() );
478 const size_t i3( element->index() );
479 const ET1 v3( element->value() );
481 const size_t i4( element->index() );
482 const ET1 v4( element->value() );
485 for(
size_t j=jj; j<jend; ++j ) {
486 (~lhs)(i1,j) += v1 * B(i,j);
487 (~lhs)(i2,j) += v2 * B(i,j);
488 (~lhs)(i3,j) += v3 * B(i,j);
489 (~lhs)(i4,j) += v4 * B(i,j);
493 for( ; element!=end; ++element ) {
494 for(
size_t j=jj; j<jend; ++j ) {
495 (~lhs)(element->index(),j) += element->value() * B(i,j);
521 template<
typename MT
530 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
542 const size_t block( SO ? 64UL : 128UL );
544 for(
size_t jj=0UL; jj<B.columns(); jj+=block ) {
545 const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
546 for(
size_t i=0UL; i<A.columns(); ++i )
548 const ConstIterator end( A.end(i) );
549 ConstIterator element( A.begin(i) );
551 const size_t nonzeros( A.nonZeros(i) );
553 BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == ( nonzeros &
size_t(-4) ),
"Invalid end calculation" );
554 const size_t kend( nonzeros &
size_t(-4) );
556 for(
size_t k=0UL; k<kend; k+=4UL ) {
557 const size_t i1( element->index() );
558 const ET1 v1( element->value() );
560 const size_t i2( element->index() );
561 const ET1 v2( element->value() );
563 const size_t i3( element->index() );
564 const ET1 v3( element->value() );
566 const size_t i4( element->index() );
567 const ET1 v4( element->value() );
570 for(
size_t j=jj; j<jend; ++j ) {
571 (~lhs)(i1,j) -= v1 * B(i,j);
572 (~lhs)(i2,j) -= v2 * B(i,j);
573 (~lhs)(i3,j) -= v3 * B(i,j);
574 (~lhs)(i4,j) -= v4 * B(i,j);
578 for( ; element!=end; ++element ) {
579 for(
size_t j=jj; j<jend; ++j ) {
580 (~lhs)(element->index(),j) -= element->value() * B(i,j);
650 template<
typename T1
652 inline const TSMatTDMatMultExpr<T1,T2>
658 throw std::invalid_argument(
"Matrix sizes do not match" );
686 template<
typename MT1
688 inline typename RowExprTrait< TSMatTDMatMultExpr<MT1,MT2> >::Type
689 row(
const TSMatTDMatMultExpr<MT1,MT2>& dm,
size_t index )
693 return row( dm.leftOperand(), index ) * dm.rightOperand();
712 template<
typename MT1
714 inline typename ColumnExprTrait< TSMatTDMatMultExpr<MT1,MT2> >::Type
715 column(
const TSMatTDMatMultExpr<MT1,MT2>& dm,
size_t index )
719 return dm.leftOperand() *
column( dm.rightOperand(), index );
735 template<
typename MT1,
typename MT2,
typename VT >
736 struct TDMatDVecMultExprTrait< TSMatTDMatMultExpr<MT1,MT2>, VT >
740 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
741 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
742 IsDenseVector<VT>::value && !IsTransposeVector<VT>::value
743 ,
typename TSMatDVecMultExprTrait< MT1, typename TDMatDVecMultExprTrait<MT2,VT>::Type >::Type
744 , INVALID_TYPE >::Type Type;
753 template<
typename MT1,
typename MT2,
typename VT >
754 struct TDMatSVecMultExprTrait< TSMatTDMatMultExpr<MT1,MT2>, VT >
758 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
759 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
760 IsSparseVector<VT>::value && !IsTransposeVector<VT>::value
761 ,
typename TSMatDVecMultExprTrait< MT1, typename TDMatSVecMultExprTrait<MT2,VT>::Type >::Type
762 , INVALID_TYPE >::Type Type;
771 template<
typename VT,
typename MT1,
typename MT2 >
772 struct TDVecTDMatMultExprTrait< VT, TSMatTDMatMultExpr<MT1,MT2> >
776 typedef typename SelectType< IsDenseVector<VT>::value && !IsTransposeVector<VT>::value &&
777 IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
778 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
779 ,
typename TDVecTDMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
780 , INVALID_TYPE >::Type Type;
789 template<
typename VT,
typename MT1,
typename MT2 >
790 struct TSVecTDMatMultExprTrait< VT, TSMatTDMatMultExpr<MT1,MT2> >
794 typedef typename SelectType< IsSparseVector<VT>::value && !IsTransposeVector<VT>::value &&
795 IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
796 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
797 ,
typename TSVecTDMatMultExprTrait< typename TSVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
798 , INVALID_TYPE >::Type Type;
807 template<
typename MT1,
typename MT2 >
808 struct RowExprTrait< TSMatTDMatMultExpr<MT1,MT2> >
812 typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
821 template<
typename MT1,
typename MT2 >
822 struct ColumnExprTrait< TSMatTDMatMultExpr<MT1,MT2> >
826 typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;