22 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATDMATMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_TSMATDMATMULTEXPR_H_
31 #include <boost/type_traits/remove_reference.hpp>
85 template<
typename MT1
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 };
159 if(
lhs_.columns() != 0UL ) {
161 for(
size_t k=1UL; k<
lhs_.columns(); ++k ) {
189 return rhs_.columns();
219 template<
typename T >
245 template<
typename MT
253 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
267 const size_t block( SO ? 8UL : 256UL );
269 for(
size_t jj=0UL; jj<B.columns(); jj+=block ) {
270 const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
271 for(
size_t i=0UL; i<A.columns(); ++i ) {
272 const ConstIterator end( A.end(i) );
273 ConstIterator element( A.begin(i) );
274 for( ; element!=end; ++element ) {
275 for(
size_t j=jj; j<jend; ++j ) {
276 if(
isDefault( (~lhs)(element->index(),j) ) )
277 (~lhs)(element->index(),j) = element->value() * B(i,j);
279 (~lhs)(element->index(),j) += element->value() * B(i,j);
302 template<
typename MT
310 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
322 const size_t block( SO ? 8UL : 256UL );
324 for(
size_t jj=0UL; jj<B.columns(); jj+=block ) {
325 const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
326 for(
size_t i=0UL; i<A.rows(); ++i ) {
327 for(
size_t j=jj; j<jend; ++j ) {
328 reset( (~lhs)(i,j) );
331 for(
size_t i=0UL; i<A.columns(); ++i )
333 const ConstIterator end( A.end(i) );
334 ConstIterator element( A.begin(i) );
336 const size_t nonzeros( A.nonZeros(i) );
338 BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == ( nonzeros &
size_t(-4) ),
"Invalid end calculation" );
339 const size_t kend( nonzeros &
size_t(-4) );
341 for(
size_t k=0UL; k<kend; k+=4UL ) {
342 const size_t i1( element->index() );
343 const ET1 v1( element->value() );
345 const size_t i2( element->index() );
346 const ET1 v2( element->value() );
348 const size_t i3( element->index() );
349 const ET1 v3( element->value() );
351 const size_t i4( element->index() );
352 const ET1 v4( element->value() );
355 for(
size_t j=jj; j<jend; ++j ) {
356 (~lhs)(i1,j) += v1 * B(i,j);
357 (~lhs)(i2,j) += v2 * B(i,j);
358 (~lhs)(i3,j) += v3 * B(i,j);
359 (~lhs)(i4,j) += v4 * B(i,j);
363 for( ; element!=end; ++element ) {
364 for(
size_t j=jj; j<jend; ++j ) {
365 (~lhs)(element->index(),j) += element->value() * B(i,j);
386 template<
typename MT
390 typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
402 const TmpType tmp( rhs );
421 template<
typename MT
428 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
440 const size_t block( SO ? 8UL : 256UL );
442 for(
size_t jj=0UL; jj<B.columns(); jj+=block ) {
443 const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
444 for(
size_t i=0UL; i<A.columns(); ++i )
446 const ConstIterator end( A.end(i) );
447 ConstIterator element( A.begin(i) );
449 const size_t nonzeros( A.nonZeros(i) );
451 BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == ( nonzeros &
size_t(-4) ),
"Invalid end calculation" );
452 const size_t kend( nonzeros &
size_t(-4) );
454 for(
size_t k=0UL; k<kend; k+=4UL ) {
455 const size_t i1( element->index() );
456 const ET1 v1( element->value() );
458 const size_t i2( element->index() );
459 const ET1 v2( element->value() );
461 const size_t i3( element->index() );
462 const ET1 v3( element->value() );
464 const size_t i4( element->index() );
465 const ET1 v4( element->value() );
468 for(
size_t j=jj; j<jend; ++j ) {
469 (~lhs)(i1,j) += v1 * B(i,j);
470 (~lhs)(i2,j) += v2 * B(i,j);
471 (~lhs)(i3,j) += v3 * B(i,j);
472 (~lhs)(i4,j) += v4 * B(i,j);
476 for( ; element!=end; ++element ) {
477 for(
size_t j=jj; j<jend; ++j ) {
478 (~lhs)(element->index(),j) += element->value() * B(i,j);
504 template<
typename MT
511 typedef typename boost::remove_reference<LT>::type::ConstIterator ConstIterator;
523 const size_t block( SO ? 8UL : 256UL );
525 for(
size_t jj=0UL; jj<B.columns(); jj+=block ) {
526 const size_t jend( ( jj+block > B.columns() )?( B.columns() ):( jj+block ) );
527 for(
size_t i=0UL; i<A.columns(); ++i )
529 const ConstIterator end( A.end(i) );
530 ConstIterator element( A.begin(i) );
532 const size_t nonzeros( A.nonZeros(i) );
534 BLAZE_INTERNAL_ASSERT( ( nonzeros - ( nonzeros % 4UL ) ) == ( nonzeros &
size_t(-4) ),
"Invalid end calculation" );
535 const size_t kend( nonzeros &
size_t(-4) );
537 for(
size_t k=0UL; k<kend; k+=4UL ) {
538 const size_t i1( element->index() );
539 const ET1 v1( element->value() );
541 const size_t i2( element->index() );
542 const ET1 v2( element->value() );
544 const size_t i3( element->index() );
545 const ET1 v3( element->value() );
547 const size_t i4( element->index() );
548 const ET1 v4( element->value() );
551 for(
size_t j=jj; j<jend; ++j ) {
552 (~lhs)(i1,j) -= v1 * B(i,j);
553 (~lhs)(i2,j) -= v2 * B(i,j);
554 (~lhs)(i3,j) -= v3 * B(i,j);
555 (~lhs)(i4,j) -= v4 * B(i,j);
559 for( ; element!=end; ++element ) {
560 for(
size_t j=jj; j<jend; ++j ) {
561 (~lhs)(element->index(),j) -= element->value() * B(i,j);
633 template<
typename T1
639 throw std::invalid_argument(
"Matrix sizes do not match" );
656 template<
typename MT1,
typename MT2,
typename VT >
661 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
662 IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
663 IsDenseVector<VT>::value && !IsTransposeVector<VT>::value
664 ,
typename TSMatDVecMultExprTrait< MT1, typename DMatDVecMultExprTrait<MT2,VT>::Type >::Type
665 , INVALID_TYPE >::Type Type;
674 template<
typename MT1,
typename MT2,
typename VT >
679 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
680 IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
681 IsSparseVector<VT>::value && !IsTransposeVector<VT>::value
682 ,
typename TSMatDVecMultExprTrait< MT1, typename DMatSVecMultExprTrait<MT2,VT>::Type >::Type
683 , INVALID_TYPE >::Type Type;
692 template<
typename VT,
typename MT1,
typename MT2 >
697 typedef typename SelectType< IsDenseVector<VT>::value && IsTransposeVector<VT>::value &&
698 IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
699 IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
700 ,
typename TDVecDMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
701 , INVALID_TYPE >::Type Type;
710 template<
typename VT,
typename MT1,
typename MT2 >
715 typedef typename SelectType< IsSparseVector<VT>::value && IsTransposeVector<VT>::value &&
716 IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
717 IsDenseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
718 ,
typename TDVecDMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
719 , INVALID_TYPE >::Type Type;