22 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATTDMATMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_TSMATTDMATMULTEXPR_H_
31 #include <boost/type_traits/remove_reference.hpp>
80 template<
typename MT1
88 typedef typename MT1::ResultType
RT1;
89 typedef typename MT2::ResultType
RT2;
90 typedef typename MT1::ElementType
ET1;
91 typedef typename MT2::ElementType
ET2;
92 typedef typename MT1::CompositeType
CT1;
93 typedef typename MT2::CompositeType
CT2;
121 enum { vectorizable = 0 };
154 if(
lhs_.columns() != 0UL ) {
156 for(
size_t k=1UL; k<
lhs_.columns(); ++k ) {
184 return rhs_.columns();
214 template<
typename T >
240 template<
typename MT
248 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
262 const size_t block( 64UL );
264 for(
size_t jj=0UL; jj<B.columns(); jj+=block ) {
265 const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
266 for(
size_t i=0UL; i<A.columns(); ++i ) {
267 const ConstIterator end( A.end(i) );
268 ConstIterator element( A.begin(i) );
269 for( ; element!=end; ++element ) {
270 for(
size_t j=jj; j<jend; ++j ) {
271 if(
isDefault( (~lhs)(element->index(),j) ) )
272 (~lhs)(element->index(),j) = element->value() * B(i,j);
274 (~lhs)(element->index(),j) += element->value() * B(i,j);
297 template<
typename MT
305 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
317 const size_t block( SO ? 64UL : 128UL );
319 for(
size_t jj=0UL; jj<B.columns(); jj+=block ) {
320 const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
321 for(
size_t i=0UL; i<A.rows(); ++i ) {
322 for(
size_t j=jj; j<jend; ++j ) {
323 reset( (~lhs)(i,j) );
326 for(
size_t i=0UL; i<A.columns(); ++i )
328 const ConstIterator end( A.end(i) );
329 ConstIterator element( A.begin(i) );
331 const size_t nonzeros( A.nonZeros(i) );
333 BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == ( nonzeros &
size_t(-4) ),
"Invalid end calculation" );
334 const size_t kend( nonzeros &
size_t(-4) );
336 for(
size_t k=0UL; k<kend; k+=4UL ) {
337 const size_t i1( element->index() );
338 const ET1 v1( element->value() );
340 const size_t i2( element->index() );
341 const ET1 v2( element->value() );
343 const size_t i3( element->index() );
344 const ET1 v3( element->value() );
346 const size_t i4( element->index() );
347 const ET1 v4( element->value() );
350 for(
size_t j=jj; j<jend; ++j ) {
351 (~lhs)(i1,j) += v1 * B(i,j);
352 (~lhs)(i2,j) += v2 * B(i,j);
353 (~lhs)(i3,j) += v3 * B(i,j);
354 (~lhs)(i4,j) += v4 * B(i,j);
358 for( ; element!=end; ++element ) {
359 for(
size_t j=jj; j<jend; ++j ) {
360 (~lhs)(element->index(),j) += element->value() * B(i,j);
382 template<
typename MT
386 typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
398 const TmpType tmp( rhs );
417 template<
typename MT
424 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
436 const size_t block( SO ? 64UL : 128UL );
438 for(
size_t jj=0UL; jj<B.columns(); jj+=block ) {
439 const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
440 for(
size_t i=0UL; i<A.columns(); ++i )
442 const ConstIterator end( A.end(i) );
443 ConstIterator element( A.begin(i) );
445 const size_t nonzeros( A.nonZeros(i) );
447 BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == ( nonzeros &
size_t(-4) ),
"Invalid end calculation" );
448 const size_t kend( nonzeros &
size_t(-4) );
450 for(
size_t k=0UL; k<kend; k+=4UL ) {
451 const size_t i1( element->index() );
452 const ET1 v1( element->value() );
454 const size_t i2( element->index() );
455 const ET1 v2( element->value() );
457 const size_t i3( element->index() );
458 const ET1 v3( element->value() );
460 const size_t i4( element->index() );
461 const ET1 v4( element->value() );
464 for(
size_t j=jj; j<jend; ++j ) {
465 (~lhs)(i1,j) += v1 * B(i,j);
466 (~lhs)(i2,j) += v2 * B(i,j);
467 (~lhs)(i3,j) += v3 * B(i,j);
468 (~lhs)(i4,j) += v4 * B(i,j);
472 for( ; element!=end; ++element ) {
473 for(
size_t j=jj; j<jend; ++j ) {
474 (~lhs)(element->index(),j) += element->value() * B(i,j);
500 template<
typename MT
507 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
519 const size_t block( SO ? 64UL : 128UL );
521 for(
size_t jj=0UL; jj<B.columns(); jj+=block ) {
522 const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
523 for(
size_t i=0UL; i<A.columns(); ++i )
525 const ConstIterator end( A.end(i) );
526 ConstIterator element( A.begin(i) );
528 const size_t nonzeros( A.nonZeros(i) );
530 BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == ( nonzeros &
size_t(-4) ),
"Invalid end calculation" );
531 const size_t kend( nonzeros &
size_t(-4) );
533 for(
size_t k=0UL; k<kend; k+=4UL ) {
534 const size_t i1( element->index() );
535 const ET1 v1( element->value() );
537 const size_t i2( element->index() );
538 const ET1 v2( element->value() );
540 const size_t i3( element->index() );
541 const ET1 v3( element->value() );
543 const size_t i4( element->index() );
544 const ET1 v4( element->value() );
547 for(
size_t j=jj; j<jend; ++j ) {
548 (~lhs)(i1,j) -= v1 * B(i,j);
549 (~lhs)(i2,j) -= v2 * B(i,j);
550 (~lhs)(i3,j) -= v3 * B(i,j);
551 (~lhs)(i4,j) -= v4 * B(i,j);
555 for( ; element!=end; ++element ) {
556 for(
size_t j=jj; j<jend; ++j ) {
557 (~lhs)(element->index(),j) -= element->value() * B(i,j);
627 template<
typename T1
633 throw std::invalid_argument(
"Matrix sizes do not match" );
650 template<
typename MT1,
typename MT2,
typename VT >
655 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
656 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
657 IsDenseVector<VT>::value && !IsTransposeVector<VT>::value
658 ,
typename TSMatDVecMultExprTrait< MT1, typename TDMatDVecMultExprTrait<MT2,VT>::Type >::Type
659 , INVALID_TYPE >::Type Type;
668 template<
typename MT1,
typename MT2,
typename VT >
673 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
674 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
675 IsSparseVector<VT>::value && !IsTransposeVector<VT>::value
676 ,
typename TSMatDVecMultExprTrait< MT1, typename TDMatSVecMultExprTrait<MT2,VT>::Type >::Type
677 , INVALID_TYPE >::Type Type;
686 template<
typename VT,
typename MT1,
typename MT2 >
691 typedef typename SelectType< IsDenseVector<VT>::value && !IsTransposeVector<VT>::value &&
692 IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
693 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
694 ,
typename TDVecTDMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
695 , INVALID_TYPE >::Type Type;
704 template<
typename VT,
typename MT1,
typename MT2 >
709 typedef typename SelectType< IsSparseVector<VT>::value && !IsTransposeVector<VT>::value &&
710 IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
711 IsDenseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
712 ,
typename TSVecTDMatMultExprTrait< typename TSVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
713 , INVALID_TYPE >::Type Type;