22 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATTSMATMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_TSMATTSMATMULTEXPR_H_
33 #include <boost/type_traits/remove_reference.hpp>
90 template<
typename MT1
92 class TSMatTSMatMultExpr :
public SparseMatrix< TSMatTSMatMultExpr<MT1,MT2>, true >
98 typedef typename MT1::ResultType
RT1;
99 typedef typename MT2::ResultType
RT2;
100 typedef typename MT1::CompositeType
CT1;
101 typedef typename MT2::CompositeType
CT2;
146 typedef typename boost::remove_reference<CT2>::type::ConstIterator ConstIterator;
151 if(
lhs_.columns() == 0UL )
160 const ConstIterator end( B.end(j) );
161 ConstIterator element( B.begin(j) );
168 tmp =
lhs_(i,element->index()) * element->value();
170 for( ; element!=end; ++element )
171 tmp +=
lhs_(i,element->index()) * element->value();
177 for(
size_t k=1UL; k<
lhs_.columns(); ++k ) {
202 return rhs_.columns();
254 template<
typename T >
256 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
266 template<
typename T >
268 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
292 template<
typename MT
302 typedef typename boost::remove_reference<CT1>::type::ConstIterator LeftIterator;
303 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
315 for(
size_t j=0UL; j<(~lhs).
columns(); ++j ) {
316 const RightIterator rend( B.end(j) );
317 for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
318 const LeftIterator lend( A.end( relem->index() ) );
319 for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem )
321 if(
isDefault( (~lhs)(lelem->index(),j) ) ) {
322 (~lhs)(lelem->index(),j) = lelem->value() * relem->value();
325 (~lhs)(lelem->index(),j) += lelem->value() * relem->value();
348 template<
typename MT
358 typedef typename boost::remove_reference<CT1>::type::ConstIterator LeftIterator;
359 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
371 for(
size_t j=0UL; j<(~lhs).
columns(); ++j ) {
372 const RightIterator rend( B.end(j) );
373 for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
374 const LeftIterator lend( A.end( relem->index() ) );
375 for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem ) {
376 (~lhs)(lelem->index(),j) += lelem->value() * relem->value();
397 template<
typename MT >
408 const typename MT1::OppositeType A( rhs.lhs_ );
409 const typename MT2::OppositeType B( rhs.rhs_ );
428 template<
typename MT >
436 typedef typename boost::remove_reference<CT1>::type::ConstIterator LeftIterator;
437 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
450 size_t nonzeros( 0UL );
452 for(
size_t j=0UL; j<(~lhs).
columns(); ++j ) {
453 const RightIterator rend( B.end(j) );
454 for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
455 nonzeros += A.nonZeros( relem->index() );
459 if( nonzeros > (~lhs).rows() * (~lhs).
columns() ) {
463 (~lhs).reserve( nonzeros );
468 std::vector<byte> valid ( (~lhs).
rows(), 0 );
469 std::vector<size_t> indices( (~lhs).
rows(), 0UL );
470 size_t minIndex(
inf ), maxIndex( 0UL );
472 for(
size_t j=0UL; j<(~lhs).
columns(); ++j )
474 const RightIterator rend( B.end(j) );
475 for( RightIterator relem=B.begin(j); relem!=rend; ++relem )
477 const LeftIterator lend( A.end( relem->index() ) );
478 for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem )
480 if( !valid[lelem->index()] ) {
481 values[lelem->index()] = lelem->value() * relem->value();
482 valid [lelem->index()] = 1;
483 indices[nonzeros] = lelem->index();
485 if( lelem->index() < minIndex ) minIndex = lelem->index();
486 if( lelem->index() > maxIndex ) maxIndex = lelem->index();
489 values[lelem->index()] += lelem->value() * relem->value();
500 if( ( nonzeros + nonzeros ) < ( maxIndex - minIndex ) )
502 std::sort( indices.begin(), indices.begin() + nonzeros );
504 for(
size_t i=0UL; i<nonzeros; ++i )
506 const size_t index( indices[i] );
508 (~lhs).append( index, j, values[index] );
509 reset( values[index] );
512 reset( valid [index] );
516 for(
size_t i=minIndex; i<=maxIndex; ++i )
519 (~lhs).append( i, j, values[i] );
532 (~lhs).finalize( j );
551 template<
typename MT
560 typedef typename boost::remove_reference<CT1>::type::ConstIterator LeftIterator;
561 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
573 for(
size_t j=0UL; j<(~lhs).
columns(); ++j ) {
574 const RightIterator rend( B.end(j) );
575 for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
576 const LeftIterator lend( A.end( relem->index() ) );
577 for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem ) {
578 (~lhs)(lelem->index(),j) += lelem->value() * relem->value();
603 template<
typename MT
612 typedef typename boost::remove_reference<CT1>::type::ConstIterator LeftIterator;
613 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
625 for(
size_t j=0UL; j<(~lhs).
columns(); ++j ) {
626 const RightIterator rend( B.end(j) );
627 for( RightIterator relem=B.begin(j); relem!=rend; ++relem ) {
628 const LeftIterator lend( A.end( relem->index() ) );
629 for( LeftIterator lelem=A.begin( relem->index() ); lelem!=lend; ++lelem ) {
630 (~lhs)(lelem->index(),j) -= lelem->value() * relem->value();
697 template<
typename T1
699 inline const TSMatTSMatMultExpr<T1,T2>
705 throw std::invalid_argument(
"Matrix sizes do not match" );
733 template<
typename T1
735 inline typename RowExprTrait< TSMatTSMatMultExpr<T1,T2> >::Type
736 row(
const TSMatTSMatMultExpr<T1,T2>& sm,
size_t index )
740 return row( sm.leftOperand(), index ) * sm.rightOperand();
759 template<
typename T1
761 inline typename ColumnExprTrait< TSMatTSMatMultExpr<T1,T2> >::Type
762 column(
const TSMatTSMatMultExpr<T1,T2>& sm,
size_t index )
766 return sm.leftOperand() *
column( sm.rightOperand(), index );
782 template<
typename MT1,
typename MT2,
typename VT >
783 struct TSMatDVecMultExprTrait< TSMatTSMatMultExpr<MT1,MT2>, VT >
787 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
788 IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
789 IsDenseVector<VT>::value && !IsTransposeVector<VT>::value
790 ,
typename TSMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
791 , INVALID_TYPE >::Type Type;
800 template<
typename MT1,
typename MT2,
typename VT >
801 struct TSMatSVecMultExprTrait< TSMatTSMatMultExpr<MT1,MT2>, VT >
805 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
806 IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
807 IsSparseVector<VT>::value && !IsTransposeVector<VT>::value
808 ,
typename TSMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
809 , INVALID_TYPE >::Type Type;
818 template<
typename VT,
typename MT1,
typename MT2 >
819 struct TDVecTSMatMultExprTrait< VT, TSMatTSMatMultExpr<MT1,MT2> >
823 typedef typename SelectType< IsDenseVector<VT>::value && IsTransposeVector<VT>::value &&
824 IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
825 IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
826 ,
typename TDVecTSMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
827 , INVALID_TYPE >::Type Type;
836 template<
typename VT,
typename MT1,
typename MT2 >
837 struct TSVecTSMatMultExprTrait< VT, TSMatTSMatMultExpr<MT1,MT2> >
841 typedef typename SelectType< IsSparseVector<VT>::value && IsTransposeVector<VT>::value &&
842 IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
843 IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
844 ,
typename TSVecTSMatMultExprTrait< typename TSVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
845 , INVALID_TYPE >::Type Type;
854 template<
typename MT1,
typename MT2 >
855 struct RowExprTrait< TSMatTSMatMultExpr<MT1,MT2> >
859 typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
868 template<
typename MT1,
typename MT2 >
869 struct ColumnExprTrait< TSMatTSMatMultExpr<MT1,MT2> >
873 typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;