22 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATTDMATMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_SMATTDMATMULTEXPR_H_
31 #include <boost/type_traits/remove_reference.hpp>
87 template<
typename MT1
89 class SMatTDMatMultExpr :
public DenseMatrix< SMatTDMatMultExpr<MT1,MT2>, false >
95 typedef typename MT1::ResultType
RT1;
96 typedef typename MT2::ResultType
RT2;
97 typedef typename MT1::CompositeType
CT1;
98 typedef typename MT2::CompositeType
CT2;
126 enum { vectorizable = 0 };
154 typedef typename boost::remove_reference<CT1>::type::ConstIterator ConstIterator;
159 if(
lhs_.columns() == 0UL )
168 const ConstIterator end( A.end(i) );
169 ConstIterator element( A.begin(i) );
176 tmp = element->value() *
rhs_(element->index(),j);
178 for( ; element!=end; ++element )
179 tmp += element->value() *
rhs_(element->index(),j);
185 for(
size_t k=1UL; k<
lhs_.columns(); ++k ) {
210 return rhs_.columns();
240 template<
typename T >
242 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
252 template<
typename T >
254 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
276 template<
typename MT
285 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
297 const size_t block( 256UL );
300 const size_t jend( B.columns() &
size_t(-4) );
302 for(
size_t ii=0UL; ii<A.rows(); ii+=block ) {
303 const size_t iend( ( ii+block > A.rows() )?( A.rows() ):( ii+block ) );
304 for(
size_t j=0UL; j<jend; j+=4UL ) {
305 for(
size_t i=ii; i<iend; ++i ) {
306 const ConstIterator end( A.end(i) );
307 ConstIterator element( A.begin(i) );
309 (~lhs)(i,j ) = element->value() * B(element->index(),j );
310 (~lhs)(i,j+1UL) = element->value() * B(element->index(),j+1UL);
311 (~lhs)(i,j+2UL) = element->value() * B(element->index(),j+2UL);
312 (~lhs)(i,j+3UL) = element->value() * B(element->index(),j+3UL);
314 for( ; element!=end; ++element ) {
315 (~lhs)(i,j ) += element->value() * B(element->index(),j );
316 (~lhs)(i,j+1UL) += element->value() * B(element->index(),j+1UL);
317 (~lhs)(i,j+2UL) += element->value() * B(element->index(),j+2UL);
318 (~lhs)(i,j+3UL) += element->value() * B(element->index(),j+3UL);
322 reset( (~lhs)(i,j ) );
323 reset( (~lhs)(i,j+1UL) );
324 reset( (~lhs)(i,j+2UL) );
325 reset( (~lhs)(i,j+3UL) );
329 for(
size_t j=jend; j<B.columns(); ++j ) {
330 for(
size_t i=ii; i<iend; ++i ) {
331 const ConstIterator end( A.end(i) );
332 ConstIterator element( A.begin(i) );
334 (~lhs)(i,j) = element->value() * B(element->index(),j);
336 for( ; element!=end; ++element ) {
337 (~lhs)(i,j) += element->value() * B(element->index(),j);
341 reset( (~lhs)(i,j) );
362 template<
typename MT
380 const TmpType tmp( rhs );
399 template<
typename MT
408 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
420 const size_t block( 256UL );
421 BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == ( B.columns() & size_t(-4) ),
"Invalid end calculation" );
422 const size_t jend( B.columns() & size_t(-4) );
424 for(
size_t ii=0UL; ii<A.rows(); ii+=block ) {
425 const size_t iend( ( ii+block > A.rows() )?( A.rows() ):( ii+block ) );
426 for(
size_t j=0UL; j<jend; j+=4UL ) {
427 for(
size_t i=ii; i<iend; ++i ) {
428 const ConstIterator end( A.end(i) );
429 ConstIterator element( A.begin(i) );
430 for( ; element!=end; ++element ) {
431 (~lhs)(i,j ) += element->value() * B(element->index(),j );
432 (~lhs)(i,j+1UL) += element->value() * B(element->index(),j+1UL);
433 (~lhs)(i,j+2UL) += element->value() * B(element->index(),j+2UL);
434 (~lhs)(i,j+3UL) += element->value() * B(element->index(),j+3UL);
438 for(
size_t j=jend; j<B.columns(); ++j ) {
439 for(
size_t i=ii; i<iend; ++i ) {
440 const ConstIterator end( A.end(i) );
441 ConstIterator element( A.begin(i) );
442 for( ; element!=end; ++element ) {
443 (~lhs)(i,j) += element->value() * B(element->index(),j);
469 template<
typename MT
478 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
490 const size_t block( 256UL );
491 BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == ( B.columns() & size_t(-4) ),
"Invalid end calculation" );
492 const size_t jend( B.columns() & size_t(-4) );
494 for(
size_t ii=0UL; ii<A.rows(); ii+=block ) {
495 const size_t iend( ( ii+block > A.rows() )?( A.rows() ):( ii+block ) );
496 for(
size_t j=0UL; j<jend; j+=4UL ) {
497 for(
size_t i=ii; i<iend; ++i ) {
498 const ConstIterator end( A.end(i) );
499 ConstIterator element( A.begin(i) );
500 for( ; element!=end; ++element ) {
501 (~lhs)(i,j ) -= element->value() * B(element->index(),j );
502 (~lhs)(i,j+1UL) -= element->value() * B(element->index(),j+1UL);
503 (~lhs)(i,j+2UL) -= element->value() * B(element->index(),j+2UL);
504 (~lhs)(i,j+3UL) -= element->value() * B(element->index(),j+3UL);
508 for(
size_t j=jend; j<B.columns(); ++j ) {
509 for(
size_t i=ii; i<iend; ++i ) {
510 const ConstIterator end( A.end(i) );
511 ConstIterator element( A.begin(i) );
512 for( ; element!=end; ++element ) {
513 (~lhs)(i,j) -= element->value() * B(element->index(),j);
585 template<
typename T1
587 inline const SMatTDMatMultExpr<T1,T2>
593 throw std::invalid_argument(
"Matrix sizes do not match" );
621 template<
typename MT1
623 inline typename RowExprTrait< SMatTDMatMultExpr<MT1,MT2> >::Type
624 row(
const SMatTDMatMultExpr<MT1,MT2>& dm,
size_t index )
628 return row( dm.leftOperand(), index ) * dm.rightOperand();
647 template<
typename MT1
649 inline typename ColumnExprTrait< SMatTDMatMultExpr<MT1,MT2> >::Type
650 column(
const SMatTDMatMultExpr<MT1,MT2>& dm,
size_t index )
654 return dm.leftOperand() *
column( dm.rightOperand(), index );
670 template<
typename MT1,
typename MT2,
typename VT >
671 struct DMatDVecMultExprTrait< SMatTDMatMultExpr<MT1,MT2>, VT >
675 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
676 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
677 IsDenseVector<VT>::value && !IsTransposeVector<VT>::value
678 ,
typename SMatDVecMultExprTrait< MT1, typename TDMatDVecMultExprTrait<MT2,VT>::Type >::Type
679 , INVALID_TYPE >::Type Type;
688 template<
typename MT1,
typename MT2,
typename VT >
689 struct DMatSVecMultExprTrait< SMatTDMatMultExpr<MT1,MT2>, VT >
693 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
694 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
695 IsSparseVector<VT>::value && !IsTransposeVector<VT>::value
696 ,
typename SMatDVecMultExprTrait< MT1, typename TDMatSVecMultExprTrait<MT2,VT>::Type >::Type
697 , INVALID_TYPE >::Type Type;
706 template<
typename VT,
typename MT1,
typename MT2 >
707 struct TDVecDMatMultExprTrait< VT, SMatTDMatMultExpr<MT1,MT2> >
711 typedef typename SelectType< IsDenseVector<VT>::value && IsTransposeVector<VT>::value &&
712 IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
713 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
714 ,
typename TDVecTDMatMultExprTrait< typename TDVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
715 , INVALID_TYPE >::Type Type;
724 template<
typename VT,
typename MT1,
typename MT2 >
725 struct TSVecDMatMultExprTrait< VT, SMatTDMatMultExpr<MT1,MT2> >
729 typedef typename SelectType< IsSparseVector<VT>::value && IsTransposeVector<VT>::value &&
730 IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
731 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
732 ,
typename TSVecTDMatMultExprTrait< typename TSVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
733 , INVALID_TYPE >::Type Type;
742 template<
typename MT1,
typename MT2 >
743 struct RowExprTrait< SMatTDMatMultExpr<MT1,MT2> >
747 typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
756 template<
typename MT1,
typename MT2 >
757 struct ColumnExprTrait< SMatTDMatMultExpr<MT1,MT2> >
761 typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;