22 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATTSMATMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_TSMATTSMATMULTEXPR_H_
33 #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::CompositeType
CT1;
96 typedef typename MT2::CompositeType
CT2;
147 typedef typename boost::remove_reference<CT2>::type::ConstIterator ConstIterator;
152 if(
lhs_.columns() == 0UL )
161 const ConstIterator end( B.end(j) );
162 ConstIterator element( B.begin(j) );
169 tmp =
lhs_(i,element->index()) * element->value();
171 for( ; element!=end; ++element )
172 tmp +=
lhs_(i,element->index()) * element->value();
178 for(
size_t k=1UL; k<
lhs_.columns(); ++k ) {
203 return rhs_.columns();
254 template<
typename T >
283 template<
typename MT
291 typedef typename boost::remove_reference<CT1>::type::ConstIterator LeftIterator;
292 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
304 for(
size_t j=0UL; j<(~lhs).
columns(); ++j ) {
305 const RightIterator rend( B.end(j) );
306 for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
307 const LeftIterator lend( A.end( relem->index() ) );
308 for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem )
310 if(
isDefault( (~lhs)(lelem->index(),j) ) ) {
311 (~lhs)(lelem->index(),j) = lelem->value() * relem->value();
314 (~lhs)(lelem->index(),j) += lelem->value() * relem->value();
337 template<
typename MT
345 typedef typename boost::remove_reference<CT1>::type::ConstIterator LeftIterator;
346 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
358 for(
size_t j=0UL; j<(~lhs).
columns(); ++j ) {
359 const RightIterator rend( B.end(j) );
360 for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
361 const LeftIterator lend( A.end( relem->index() ) );
362 for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem ) {
363 (~lhs)(lelem->index(),j) += lelem->value() * relem->value();
384 template<
typename MT >
393 const typename MT1::OppositeType A( rhs.lhs_ );
394 const typename MT2::OppositeType B( rhs.rhs_ );
413 template<
typename MT >
419 typedef typename boost::remove_reference<CT1>::type::ConstIterator LeftIterator;
420 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
433 size_t nonzeros( 0UL );
435 for(
size_t j=0UL; j<(~lhs).
columns(); ++j ) {
436 const RightIterator rend( B.end(j) );
437 for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
438 nonzeros += A.nonZeros( relem->index() );
442 if( nonzeros > (~lhs).rows() * (~lhs).
columns() ) {
446 (~lhs).reserve( nonzeros );
451 std::vector<size_t> indices( (~lhs).
rows(), 0UL );
452 size_t minIndex(
inf ), maxIndex( 0UL );
454 for(
size_t j=0UL; j<(~lhs).
columns(); ++j )
456 const RightIterator rend( B.end(j) );
457 for( RightIterator relem=B.begin(j); relem!=rend; ++relem )
459 const LeftIterator lend( A.end( relem->index() ) );
460 for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem )
462 if(
isDefault( values[lelem->index()] ) ) {
463 values[lelem->index()] = lelem->value() * relem->value();
464 indices[nonzeros] = lelem->index();
466 if( lelem->index() < minIndex ) minIndex = lelem->index();
467 if( lelem->index() > maxIndex ) maxIndex = lelem->index();
470 values[lelem->index()] += lelem->value() * relem->value();
479 if( ( nonzeros + nonzeros ) < ( maxIndex - minIndex ) )
481 std::sort( indices.begin(), indices.begin() + nonzeros );
483 for(
size_t i=0UL; i<nonzeros; ++i ) {
484 const size_t index( indices[i] );
485 (~lhs).append( index, j, values[index] );
486 reset( values[index] );
490 for(
size_t i=minIndex; i<=maxIndex; ++i ) {
492 (~lhs).append( i, j, values[i] );
503 (~lhs).finalize( j );
522 template<
typename MT
529 typedef typename boost::remove_reference<CT1>::type::ConstIterator LeftIterator;
530 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
542 for(
size_t j=0UL; j<(~lhs).
columns(); ++j ) {
543 const RightIterator rend( B.end(j) );
544 for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
545 const LeftIterator lend( A.end( relem->index() ) );
546 for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem ) {
547 (~lhs)(lelem->index(),j) += lelem->value() * relem->value();
572 template<
typename MT
579 typedef typename boost::remove_reference<CT1>::type::ConstIterator LeftIterator;
580 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
592 for(
size_t j=0UL; j<(~lhs).
columns(); ++j ) {
593 const RightIterator rend( B.end(j) );
594 for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
595 const LeftIterator lend( A.end( relem->index() ) );
596 for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem ) {
597 (~lhs)(lelem->index(),j) -= lelem->value() * relem->value();
664 template<
typename T1
670 throw std::invalid_argument(
"Matrix sizes do not match" );
687 template<
typename MT1,
typename MT2,
typename VT >
692 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
693 IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
694 IsDenseVector<VT>::value && !IsTransposeVector<VT>::value
695 ,
typename TSMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
696 , INVALID_TYPE >::Type Type;
705 template<
typename MT1,
typename MT2,
typename VT >
710 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
711 IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
712 IsSparseVector<VT>::value && !IsTransposeVector<VT>::value
713 ,
typename TSMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
714 , INVALID_TYPE >::Type Type;
723 template<
typename VT,
typename MT1,
typename MT2 >
728 typedef typename SelectType< IsDenseVector<VT>::value && IsTransposeVector<VT>::value &&
729 IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
730 IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
731 ,
typename TDVecTSMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
732 , INVALID_TYPE >::Type Type;
741 template<
typename VT,
typename MT1,
typename MT2 >
746 typedef typename SelectType< IsSparseVector<VT>::value && IsTransposeVector<VT>::value &&
747 IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
748 IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
749 ,
typename TSVecTSMatMultExprTrait< typename TSVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
750 , INVALID_TYPE >::Type Type;