22 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATDMATMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_SMATDMATMULTEXPR_H_
31 #include <boost/type_traits/remove_reference.hpp>
85 template<
typename MT1
87 class SMatDMatMultExpr :
public DenseMatrix< SMatDMatMultExpr<MT1,MT2>, false >
93 typedef typename MT1::ResultType
RT1;
94 typedef typename MT2::ResultType
RT2;
95 typedef typename MT1::ElementType
ET1;
96 typedef typename MT2::ElementType
ET2;
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() == 0 )
167 const ConstIterator end( A.end(i) );
168 ConstIterator element( A.begin(i) );
175 tmp = element->value() *
rhs_(element->index(),j);
177 for( ; element!=end; ++element )
178 tmp += element->value() *
rhs_(element->index(),j);
184 for(
size_t k=1; k<
lhs_.columns(); ++k ) {
209 return rhs_.columns();
239 template<
typename T >
241 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
251 template<
typename T >
253 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
276 template<
typename MT
286 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
298 for(
size_t i=0; i<A.rows(); ++i )
300 const ConstIterator end( A.end(i) );
302 for(
size_t j=0; j<B.columns(); ++j )
304 ConstIterator element( A.begin(i) );
306 if( element != end ) {
307 (~lhs)(i,j) = element->value() * B(element->index(),j);
309 for( ; element!=end; ++element ) {
310 (~lhs)(i,j) += element->value() * B(element->index(),j);
314 reset( (~lhs)(i,j) );
335 template<
typename MT
345 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
360 const size_t jend( B.columns() &
size_t(-4) );
362 for(
size_t i=0UL; i<A.rows(); ++i ) {
363 const ConstIterator end( A.end(i) );
364 ConstIterator element( A.begin(i) );
366 const size_t nonzeros( A.nonZeros(i) );
367 const size_t kend( nonzeros &
size_t(-4) );
369 for(
size_t k=0UL; k<kend; k+=4UL ) {
370 const size_t i1( element->index() );
371 const ET1 v1( element->value() );
373 const size_t i2( element->index() );
374 const ET1 v2( element->value() );
376 const size_t i3( element->index() );
377 const ET1 v3( element->value() );
379 const size_t i4( element->index() );
380 const ET1 v4( element->value() );
383 for(
size_t j=0UL; j<jend; j+=4UL ) {
384 (~lhs)(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
385 (~lhs)(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
386 (~lhs)(i,j+2UL) += v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
387 (~lhs)(i,j+3UL) += v1 * B(i1,j+3UL) + v2 * B(i2,j+3UL) + v3 * B(i3,j+3UL) + v4 * B(i4,j+3UL);
389 for(
size_t j=jend; j<B.columns(); ++j ) {
390 (~lhs)(i,j) += v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
394 for( ; element!=end; ++element ) {
395 for(
size_t j=0UL; j<jend; j+=4UL ) {
396 (~lhs)(i,j ) += element->value() * B(element->index(),j );
397 (~lhs)(i,j+1UL) += element->value() * B(element->index(),j+1UL);
398 (~lhs)(i,j+2UL) += element->value() * B(element->index(),j+2UL);
399 (~lhs)(i,j+3UL) += element->value() * B(element->index(),j+3UL);
401 for(
size_t j=jend; j<B.columns(); ++j ) {
402 (~lhs)(i,j) += element->value() * B(element->index(),j);
422 template<
typename MT
428 typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
440 const TmpType tmp( rhs );
458 template<
typename MT
467 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
479 BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == ( B.columns() & size_t(-4) ),
"Invalid end calculation" );
480 const size_t kend( B.columns() & size_t(-4) );
482 for(
size_t i=0UL; i<A.rows(); ++i ) {
483 const ConstIterator end( A.end(i) );
484 ConstIterator element( A.begin(i) );
485 for( ; element!=end; ++element ) {
486 for(
size_t k=0UL; k<kend; k+=4UL ) {
487 (~lhs)(i,k ) += element->value() * B(element->index(),k );
488 (~lhs)(i,k+1UL) += element->value() * B(element->index(),k+1UL);
489 (~lhs)(i,k+2UL) += element->value() * B(element->index(),k+2UL);
490 (~lhs)(i,k+3UL) += element->value() * B(element->index(),k+3UL);
492 for(
size_t k=kend; k<B.columns(); ++k ) {
493 (~lhs)(i,k) += element->value() * B(element->index(),k);
517 template<
typename MT
526 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
538 BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == ( B.columns() & size_t(-4) ),
"Invalid end calculation" );
539 const size_t kend( B.columns() & size_t(-4) );
541 for(
size_t i=0UL; i<A.rows(); ++i ) {
542 const ConstIterator end( A.end(i) );
543 ConstIterator element( A.begin(i) );
544 for( ; element!=end; ++element ) {
545 for(
size_t k=0UL; k<kend; k+=4UL ) {
546 (~lhs)(i,k ) -= element->value() * B(element->index(),k );
547 (~lhs)(i,k+1UL) -= element->value() * B(element->index(),k+1UL);
548 (~lhs)(i,k+2UL) -= element->value() * B(element->index(),k+2UL);
549 (~lhs)(i,k+3UL) -= element->value() * B(element->index(),k+3UL);
551 for(
size_t k=kend; k<B.columns(); ++k ) {
552 (~lhs)(i,k) -= element->value() * B(element->index(),k);
621 template<
typename T1
623 inline const SMatDMatMultExpr<T1,T2>
629 throw std::invalid_argument(
"Matrix sizes do not match" );
656 template<
typename MT1
658 inline typename RowExprTrait< SMatDMatMultExpr<MT1,MT2> >::Type
659 row(
const SMatDMatMultExpr<MT1,MT2>& dm,
size_t index )
663 return row( dm.leftOperand(), index ) * dm.rightOperand();
681 template<
typename MT1
683 inline typename ColumnExprTrait< SMatDMatMultExpr<MT1,MT2> >::Type
684 column(
const SMatDMatMultExpr<MT1,MT2>& dm,
size_t index )
688 return dm.leftOperand() *
column( dm.rightOperand(), index );
704 template<
typename MT1,
typename MT2,
typename VT >
705 struct DMatDVecMultExprTrait< SMatDMatMultExpr<MT1,MT2>, VT >
709 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
710 IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
711 IsDenseVector<VT>::value && !IsTransposeVector<VT>::value
712 ,
typename SMatDVecMultExprTrait< MT1, typename DMatDVecMultExprTrait<MT2,VT>::Type >::Type
713 , INVALID_TYPE >::Type Type;
722 template<
typename MT1,
typename MT2,
typename VT >
723 struct DMatSVecMultExprTrait< SMatDMatMultExpr<MT1,MT2>, VT >
727 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
728 IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
729 IsSparseVector<VT>::value && !IsTransposeVector<VT>::value
730 ,
typename SMatDVecMultExprTrait< MT1, typename DMatSVecMultExprTrait<MT2,VT>::Type >::Type
731 , INVALID_TYPE >::Type Type;
740 template<
typename VT,
typename MT1,
typename MT2 >
741 struct TDVecDMatMultExprTrait< VT, SMatDMatMultExpr<MT1,MT2> >
745 typedef typename SelectType< IsDenseVector<VT>::value && IsTransposeVector<VT>::value &&
746 IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
747 IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
748 ,
typename TDVecDMatMultExprTrait< typename TDVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
749 , INVALID_TYPE >::Type Type;
758 template<
typename VT,
typename MT1,
typename MT2 >
759 struct TSVecDMatMultExprTrait< VT, SMatDMatMultExpr<MT1,MT2> >
763 typedef typename SelectType< IsSparseVector<VT>::value && IsTransposeVector<VT>::value &&
764 IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
765 IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
766 ,
typename TSVecDMatMultExprTrait< typename TSVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
767 , INVALID_TYPE >::Type Type;
776 template<
typename MT1,
typename MT2 >
777 struct RowExprTrait< SMatDMatMultExpr<MT1,MT2> >
781 typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
790 template<
typename MT1,
typename MT2 >
791 struct ColumnExprTrait< SMatDMatMultExpr<MT1,MT2> >
795 typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;