22 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATTDMATMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_TSMATTDMATMULTEXPR_H_
84 template<
typename MT1
86 class TSMatTDMatMultExpr :
public DenseMatrix< TSMatTDMatMultExpr<MT1,MT2>, true >
87 ,
private MatMatMultExpr
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
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
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 RemoveReference<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 RemoveReference<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" );
675 template<
typename MT1,
typename MT2,
typename VT >
676 struct TDMatDVecMultExprTrait< TSMatTDMatMultExpr<MT1,MT2>, VT >
680 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
681 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
682 IsDenseVector<VT>::value && !IsTransposeVector<VT>::value
683 ,
typename TSMatDVecMultExprTrait< MT1, typename TDMatDVecMultExprTrait<MT2,VT>::Type >::Type
684 , INVALID_TYPE >::Type Type;
693 template<
typename MT1,
typename MT2,
typename VT >
694 struct TDMatSVecMultExprTrait< TSMatTDMatMultExpr<MT1,MT2>, VT >
698 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
699 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
700 IsSparseVector<VT>::value && !IsTransposeVector<VT>::value
701 ,
typename TSMatDVecMultExprTrait< MT1, typename TDMatSVecMultExprTrait<MT2,VT>::Type >::Type
702 , INVALID_TYPE >::Type Type;
711 template<
typename VT,
typename MT1,
typename MT2 >
712 struct TDVecTDMatMultExprTrait< VT, TSMatTDMatMultExpr<MT1,MT2> >
716 typedef typename SelectType< IsDenseVector<VT>::value && !IsTransposeVector<VT>::value &&
717 IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
718 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
719 ,
typename TDVecTDMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
720 , INVALID_TYPE >::Type Type;
729 template<
typename VT,
typename MT1,
typename MT2 >
730 struct TSVecTDMatMultExprTrait< VT, TSMatTDMatMultExpr<MT1,MT2> >
734 typedef typename SelectType< IsSparseVector<VT>::value && !IsTransposeVector<VT>::value &&
735 IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
736 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
737 ,
typename TSVecTDMatMultExprTrait< typename TSVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
738 , INVALID_TYPE >::Type Type;
747 template<
typename MT1,
typename MT2 >
748 struct RowExprTrait< TSMatTDMatMultExpr<MT1,MT2> >
752 typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
761 template<
typename MT1,
typename MT2 >
762 struct ColumnExprTrait< TSMatTDMatMultExpr<MT1,MT2> >
766 typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;