22 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATTSMATMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_TSMATTSMATMULTEXPR_H_
90 template<
typename MT1
92 class TSMatTSMatMultExpr :
public SparseMatrix< TSMatTSMatMultExpr<MT1,MT2>, true >
93 ,
private MatMatMultExpr
98 typedef typename MT1::ResultType
RT1;
99 typedef typename MT2::ResultType
RT2;
100 typedef typename MT1::CompositeType
CT1;
101 typedef typename MT2::CompositeType
CT2;
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
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
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 >
409 (~lhs).reserve( tmp.nonZeros() );
428 template<
typename MT >
436 typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
437 typedef typename RemoveReference<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 RemoveReference<CT1>::Type::ConstIterator LeftIterator;
561 typedef typename RemoveReference<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 RemoveReference<CT1>::Type::ConstIterator LeftIterator;
613 typedef typename RemoveReference<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" );
722 template<
typename MT1,
typename MT2,
typename VT >
723 struct TSMatDVecMultExprTrait< TSMatTSMatMultExpr<MT1,MT2>, VT >
727 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
728 IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
729 IsDenseVector<VT>::value && !IsTransposeVector<VT>::value
730 ,
typename TSMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
731 , INVALID_TYPE >::Type Type;
740 template<
typename MT1,
typename MT2,
typename VT >
741 struct TSMatSVecMultExprTrait< TSMatTSMatMultExpr<MT1,MT2>, VT >
745 typedef typename SelectType< IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
746 IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
747 IsSparseVector<VT>::value && !IsTransposeVector<VT>::value
748 ,
typename TSMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
749 , INVALID_TYPE >::Type Type;
758 template<
typename VT,
typename MT1,
typename MT2 >
759 struct TDVecTSMatMultExprTrait< VT, TSMatTSMatMultExpr<MT1,MT2> >
763 typedef typename SelectType< IsDenseVector<VT>::value && IsTransposeVector<VT>::value &&
764 IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
765 IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
766 ,
typename TDVecTSMatMultExprTrait< typename TDVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
767 , INVALID_TYPE >::Type Type;
776 template<
typename VT,
typename MT1,
typename MT2 >
777 struct TSVecTSMatMultExprTrait< VT, TSMatTSMatMultExpr<MT1,MT2> >
781 typedef typename SelectType< IsSparseVector<VT>::value && IsTransposeVector<VT>::value &&
782 IsSparseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
783 IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
784 ,
typename TSVecTSMatMultExprTrait< typename TSVecTSMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
785 , INVALID_TYPE >::Type Type;
794 template<
typename MT1,
typename MT2 >
795 struct RowExprTrait< TSMatTSMatMultExpr<MT1,MT2> >
799 typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
808 template<
typename MT1,
typename MT2 >
809 struct ColumnExprTrait< TSMatTSMatMultExpr<MT1,MT2> >
813 typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;