22 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATSMATMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_SMATSMATMULTEXPR_H_
33 #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::CompositeType
CT1;
92 typedef typename MT2::CompositeType
CT2;
143 typedef typename boost::remove_reference<CT1>::type::ConstIterator ConstIterator;
148 if(
lhs_.columns() == 0UL )
157 const ConstIterator end( A.end(i) );
158 ConstIterator element( A.begin(i) );
165 tmp = element->value() *
rhs_(element->index(),j);
167 for( ; element!=end; ++element )
168 tmp += element->value() *
rhs_(element->index(),j);
174 for(
size_t k=1UL; k<
lhs_.columns(); ++k ) {
199 return rhs_.columns();
250 template<
typename T >
278 template<
typename MT
286 typedef typename boost::remove_reference<CT1>::type::ConstIterator LeftIterator;
287 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
299 for(
size_t i=0UL; i<(~lhs).
rows(); ++i ) {
300 const LeftIterator lend( A.end(i) );
301 for( LeftIterator lelem=A.begin(i); lelem!=lend; ++lelem ) {
302 const RightIterator rend( B.end( lelem->index() ) );
303 for( RightIterator relem=B.begin( lelem->index() ); relem!=rend; ++relem )
305 if(
isDefault( (~lhs)(i,relem->index()) ) ) {
306 (~lhs)(i,relem->index()) = lelem->value() * relem->value();
309 (~lhs)(i,relem->index()) += lelem->value() * relem->value();
331 template<
typename MT
339 typedef typename boost::remove_reference<CT1>::type::ConstIterator LeftIterator;
340 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
352 for(
size_t i=0UL; i<(~lhs).
rows(); ++i ) {
353 const LeftIterator lend( A.end(i) );
354 for( LeftIterator lelem=A.begin(i); lelem!=lend; ++lelem ) {
355 const RightIterator rend( B.end( lelem->index() ) );
356 for( RightIterator relem=B.begin( lelem->index() ); relem!=rend; ++relem ) {
357 (~lhs)(i,relem->index()) += lelem->value() * relem->value();
377 template<
typename MT >
383 typedef typename boost::remove_reference<CT1>::type::ConstIterator LeftIterator;
384 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
397 size_t nonzeros( 0UL );
399 for(
size_t i=0UL; i<(~lhs).
rows(); ++i ) {
400 const LeftIterator lend( A.end(i) );
401 for( LeftIterator lelem=A.begin(i); lelem!=lend; ++lelem ) {
402 nonzeros += B.nonZeros( lelem->index() );
406 if( nonzeros > (~lhs).rows() * (~lhs).
columns() ) {
410 (~lhs).reserve( nonzeros );
415 std::vector<size_t> indices( (~lhs).
columns(), 0UL );
416 size_t minIndex(
inf ), maxIndex( 0UL );
418 for(
size_t i=0UL; i<(~lhs).
rows(); ++i )
420 const LeftIterator lend( A.end(i) );
421 for( LeftIterator lelem=A.begin(i); lelem!=lend; ++lelem )
423 const RightIterator rend( B.end( lelem->index() ) );
424 for( RightIterator relem=B.begin( lelem->index() ); relem!=rend; ++relem )
426 if(
isDefault( values[relem->index()] ) ) {
427 values[relem->index()] = lelem->value() * relem->value();
428 indices[nonzeros] = relem->index();
430 if( relem->index() < minIndex ) minIndex = relem->index();
431 if( relem->index() > maxIndex ) maxIndex = relem->index();
434 values[relem->index()] += lelem->value() * relem->value();
443 if( ( nonzeros + nonzeros ) < ( maxIndex - minIndex ) )
445 std::sort( indices.begin(), indices.begin() + nonzeros );
447 for(
size_t j=0UL; j<nonzeros; ++j ) {
448 const size_t index( indices[j] );
449 (~lhs).append( i, index, values[index] );
450 reset( values[index] );
454 for(
size_t j=minIndex; j<=maxIndex; ++j ) {
456 (~lhs).append( i, j, values[j] );
467 (~lhs).finalize( i );
485 template<
typename MT >
494 const typename MT1::OppositeType A( rhs.lhs_ );
495 const typename MT2::OppositeType B( rhs.rhs_ );
513 template<
typename MT
520 typedef typename boost::remove_reference<CT1>::type::ConstIterator LeftIterator;
521 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
533 for(
size_t i=0UL; i<(~lhs).
rows(); ++i ) {
534 const LeftIterator lend( A.end(i) );
535 for( LeftIterator lelem=A.begin(i); lelem!=lend; ++lelem ) {
536 const RightIterator rend( B.end( lelem->index() ) );
537 for( RightIterator relem=B.begin( lelem->index() ); relem!=rend; ++relem ) {
538 (~lhs)(i,relem->index()) += lelem->value() * relem->value();
563 template<
typename MT
570 typedef typename boost::remove_reference<CT1>::type::ConstIterator LeftIterator;
571 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
583 for(
size_t i=0UL; i<(~lhs).
rows(); ++i ) {
584 const LeftIterator lend( A.end(i) );
585 for( LeftIterator lelem=A.begin(i); lelem!=lend; ++lelem ) {
586 const RightIterator rend( B.end( lelem->index() ) );
587 for( RightIterator relem=B.begin( lelem->index() ); relem!=rend; ++relem ) {
588 (~lhs)(i,relem->index()) -= lelem->value() * relem->value();
655 template<
typename T1
661 throw std::invalid_argument(
"Matrix sizes do not match" );
678 template<
typename MT1,
typename MT2,
typename VT >
683 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
684 IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
685 IsDenseVector<VT>::value && !IsTransposeVector<VT>::value
686 ,
typename SMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
687 , INVALID_TYPE >::Type Type;
696 template<
typename MT1,
typename MT2,
typename VT >
701 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
702 IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
703 IsSparseVector<VT>::value && !IsTransposeVector<VT>::value
704 ,
typename SMatSVecMultExprTrait< MT1, typename SMatSVecMultExprTrait<MT2,VT>::Type >::Type
705 , INVALID_TYPE >::Type Type;
714 template<
typename VT,
typename MT1,
typename MT2 >
719 typedef typename SelectType< IsDenseVector<VT>::value && IsTransposeVector<VT>::value &&
720 IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
721 IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
722 ,
typename TDVecSMatMultExprTrait< typename TDVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
723 , INVALID_TYPE >::Type Type;
732 template<
typename VT,
typename MT1,
typename MT2 >
737 typedef typename SelectType< IsSparseVector<VT>::value && IsTransposeVector<VT>::value &&
738 IsSparseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
739 IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
740 ,
typename TSVecSMatMultExprTrait< typename TSVecSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
741 , INVALID_TYPE >::Type Type;