22 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATDMATMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_SMATDMATMULTEXPR_H_
31 #include <boost/type_traits/remove_reference.hpp>
81 template<
typename MT1
89 typedef typename MT1::ResultType
RT1;
90 typedef typename MT2::ResultType
RT2;
91 typedef typename MT1::ElementType
ET1;
92 typedef typename MT2::ElementType
ET2;
93 typedef typename MT1::CompositeType
CT1;
94 typedef typename MT2::CompositeType
CT2;
122 enum { vectorizable = 0 };
153 typedef typename boost::remove_reference<CT1>::type::ConstIterator ConstIterator;
158 if(
lhs_.columns() == 0 )
166 const ConstIterator end( A.end(i) );
167 ConstIterator element( A.begin(i) );
174 tmp = element->value() *
rhs_(element->index(),j);
176 for( ; element!=end; ++element )
177 tmp += element->value() *
rhs_(element->index(),j);
183 for(
size_t k=1; k<
lhs_.columns(); ++k ) {
208 return rhs_.columns();
238 template<
typename T >
263 template<
typename MT
271 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
283 for(
size_t i=0; i<A.rows(); ++i )
285 const ConstIterator end( A.end(i) );
287 for(
size_t j=0; j<B.columns(); ++j )
289 ConstIterator element( A.begin(i) );
291 if( element != end ) {
292 (~lhs)(i,j) = element->value() * B(element->index(),j);
294 for( ; element!=end; ++element ) {
295 (~lhs)(i,j) += element->value() * B(element->index(),j);
299 reset( (~lhs)(i,j) );
320 template<
typename MT
328 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
343 const size_t jend( B.columns() &
size_t(-4) );
345 for(
size_t i=0UL; i<A.rows(); ++i ) {
346 const ConstIterator end( A.end(i) );
347 ConstIterator element( A.begin(i) );
349 const size_t nonzeros( A.nonZeros(i) );
350 const size_t kend( nonzeros &
size_t(-4) );
352 for(
size_t k=0UL; k<kend; k+=4UL ) {
353 const size_t i1( element->index() );
354 const ET1 v1( element->value() );
356 const size_t i2( element->index() );
357 const ET1 v2( element->value() );
359 const size_t i3( element->index() );
360 const ET1 v3( element->value() );
362 const size_t i4( element->index() );
363 const ET1 v4( element->value() );
366 for(
size_t j=0UL; j<jend; j+=4UL ) {
367 (~lhs)(i,j ) += v1 * B(i1,j ) + v2 * B(i2,j ) + v3 * B(i3,j ) + v4 * B(i4,j );
368 (~lhs)(i,j+1UL) += v1 * B(i1,j+1UL) + v2 * B(i2,j+1UL) + v3 * B(i3,j+1UL) + v4 * B(i4,j+1UL);
369 (~lhs)(i,j+2UL) += v1 * B(i1,j+2UL) + v2 * B(i2,j+2UL) + v3 * B(i3,j+2UL) + v4 * B(i4,j+2UL);
370 (~lhs)(i,j+3UL) += v1 * B(i1,j+3UL) + v2 * B(i2,j+3UL) + v3 * B(i3,j+3UL) + v4 * B(i4,j+3UL);
372 for(
size_t j=jend; j<B.columns(); ++j ) {
373 (~lhs)(i,j) += v1 * B(i1,j) + v2 * B(i2,j) + v3 * B(i3,j) + v4 * B(i4,j);
377 for( ; element!=end; ++element ) {
378 for(
size_t j=0UL; j<jend; j+=4UL ) {
379 (~lhs)(i,j ) += element->value() * B(element->index(),j );
380 (~lhs)(i,j+1UL) += element->value() * B(element->index(),j+1UL);
381 (~lhs)(i,j+2UL) += element->value() * B(element->index(),j+2UL);
382 (~lhs)(i,j+3UL) += element->value() * B(element->index(),j+3UL);
384 for(
size_t j=jend; j<B.columns(); ++j ) {
385 (~lhs)(i,j) += element->value() * B(element->index(),j);
405 template<
typename MT
409 typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
421 const TmpType tmp( rhs );
439 template<
typename MT
446 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
458 BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == ( B.columns() & size_t(-4) ),
"Invalid end calculation" );
459 const size_t kend( B.columns() & size_t(-4) );
461 for(
size_t i=0UL; i<A.rows(); ++i ) {
462 const ConstIterator end( A.end(i) );
463 ConstIterator element( A.begin(i) );
464 for( ; element!=end; ++element ) {
465 for(
size_t k=0UL; k<kend; k+=4UL ) {
466 (~lhs)(i,k ) += element->value() * B(element->index(),k );
467 (~lhs)(i,k+1UL) += element->value() * B(element->index(),k+1UL);
468 (~lhs)(i,k+2UL) += element->value() * B(element->index(),k+2UL);
469 (~lhs)(i,k+3UL) += element->value() * B(element->index(),k+3UL);
471 for(
size_t k=kend; k<B.columns(); ++k ) {
472 (~lhs)(i,k) += element->value() * B(element->index(),k);
496 template<
typename MT
503 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
515 BLAZE_INTERNAL_ASSERT( ( B.columns() - ( B.columns() % 4UL ) ) == ( B.columns() & size_t(-4) ),
"Invalid end calculation" );
516 const size_t kend( B.columns() & size_t(-4) );
518 for(
size_t i=0UL; i<A.rows(); ++i ) {
519 const ConstIterator end( A.end(i) );
520 ConstIterator element( A.begin(i) );
521 for( ; element!=end; ++element ) {
522 for(
size_t k=0UL; k<kend; k+=4UL ) {
523 (~lhs)(i,k ) -= element->value() * B(element->index(),k );
524 (~lhs)(i,k+1UL) -= element->value() * B(element->index(),k+1UL);
525 (~lhs)(i,k+2UL) -= element->value() * B(element->index(),k+2UL);
526 (~lhs)(i,k+3UL) -= element->value() * B(element->index(),k+3UL);
528 for(
size_t k=kend; k<B.columns(); ++k ) {
529 (~lhs)(i,k) -= element->value() * B(element->index(),k);
598 template<
typename T1
604 throw std::invalid_argument(
"Matrix sizes do not match" );
621 template<
typename MT1,
typename MT2,
typename VT >
626 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
627 IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
628 IsDenseVector<VT>::value && !IsTransposeVector<VT>::value
629 ,
typename SMatDVecMultExprTrait< MT1, typename DMatDVecMultExprTrait<MT2,VT>::Type >::Type
630 , INVALID_TYPE >::Type Type;
639 template<
typename MT1,
typename MT2,
typename VT >
644 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
645 IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
646 IsSparseVector<VT>::value && !IsTransposeVector<VT>::value
647 ,
typename SMatDVecMultExprTrait< MT1, typename DMatSVecMultExprTrait<MT2,VT>::Type >::Type
648 , INVALID_TYPE >::Type Type;
657 template<
typename VT,
typename MT1,
typename MT2 >
662 typedef typename SelectType< IsDenseVector<VT>::value && IsTransposeVector<VT>::value &&
663 IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
664 IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
665 ,
typename TDVecDMatMultExprTrait< typename TDVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
666 , INVALID_TYPE >::Type Type;
675 template<
typename VT,
typename MT1,
typename MT2 >
680 typedef typename SelectType< IsSparseVector<VT>::value && IsTransposeVector<VT>::value &&
681 IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
682 IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
683 ,
typename TSVecDMatMultExprTrait< typename TSVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
684 , INVALID_TYPE >::Type Type;