22 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATSMATADDEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_SMATSMATADDEXPR_H_
69 template<
typename MT1
71 class SMatSMatAddExpr :
public SparseMatrix< SMatSMatAddExpr<MT1,MT2>, false >
72 ,
private MatMatAddExpr
77 typedef typename MT1::ResultType
RT1;
78 typedef typename MT2::ResultType
RT2;
79 typedef typename MT1::CompositeType
CT1;
80 typedef typename MT2::CompositeType
CT2;
81 typedef typename MT1::ReturnType
RN1;
82 typedef typename MT2::ReturnType
RN2;
164 return lhs_.columns();
174 return lhs_.nonZeros() +
rhs_.nonZeros();
185 return lhs_.nonZeros(i) +
rhs_.nonZeros(i);
215 template<
typename T >
217 return (
lhs_.canAlias( alias ) ||
rhs_.canAlias( alias ) );
227 template<
typename T >
229 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
251 template<
typename MT
276 for(
size_t i=0UL; i<(~lhs).
rows(); ++i ) {
277 const RightIterator end( B.end(i) );
278 for( RightIterator element=B.begin(i); element!=end; ++element ) {
279 if(
isDefault( (~lhs)(i,element->index()) ) )
280 (~lhs)(i,element->index()) = element->value();
282 (~lhs)(i,element->index()) += element->value();
302 template<
typename MT >
323 for(
size_t i=0UL; i<(~lhs).
rows(); ++i )
325 const LeftIterator lend( A.end(i) );
326 const RightIterator rend( B.end(i) );
328 LeftIterator l( A.begin(i) );
329 RightIterator r( B.begin(i) );
330 size_t nonzeros( A.nonZeros(i) + B.nonZeros(i) );
332 for( ; l!=lend && r!=rend; ++l ) {
333 while( r->index() < l->index() && ++r != rend ) {}
334 if( r!=rend && l->index() == r->index() ) {
342 (~lhs).reserve( i, nonzeros );
347 while( l != lend && r != rend )
349 if( l->index() < r->index() ) {
350 (~lhs).append( i, l->index(), l->value() );
353 else if( l->index() > r->index() ) {
354 (~lhs).append( i, r->index(), r->value() );
358 (~lhs).append( i, l->index(), l->value()+r->value() );
365 (~lhs).append( i, l->index(), l->value() );
370 (~lhs).append( i, r->index(), r->value() );
390 template<
typename MT >
398 typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
399 typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
411 const size_t m( rhs.rows() );
412 const size_t n( rhs.columns() );
415 std::vector<size_t> nonzeros( n, 0UL );
416 for(
size_t i=0UL; i<m; ++i )
418 const LeftIterator lend( A.end(i) );
419 const RightIterator rend( B.end(i) );
421 LeftIterator l( A.begin(i) );
422 RightIterator r( B.begin(i) );
424 while( l != lend && r != rend )
426 if( l->index() < r->index() ) {
427 ++nonzeros[l->index()];
430 else if( l->index() > r->index() ) {
431 ++nonzeros[r->index()];
435 ++nonzeros[l->index()];
442 ++nonzeros[l->index()];
447 ++nonzeros[r->index()];
453 for(
size_t j=0UL; j<n; ++j ) {
454 (~lhs).reserve( j, nonzeros[j] );
458 for(
size_t i=0UL; i<m; ++i )
460 const LeftIterator lend( A.end(i) );
461 const RightIterator rend( B.end(i) );
463 LeftIterator l( A.begin(i) );
464 RightIterator r( B.begin(i) );
466 while( l != lend && r != rend )
468 if( l->index() < r->index() ) {
469 (~lhs).append( i, l->index(), l->value() );
472 else if( l->index() > r->index() ) {
473 (~lhs).append( i, r->index(), r->value() );
477 (~lhs).append( i, l->index(), l->value()+r->value() );
484 (~lhs).append( i, l->index(), l->value() );
489 (~lhs).append( i, r->index(), r->value() );
509 template<
typename MT
540 template<
typename MT
613 template<
typename T1
615 inline const SMatSMatAddExpr<T1,T2>
621 throw std::invalid_argument(
"Matrix sizes do not match" );
638 template<
typename MT1,
typename MT2 >
639 struct RowExprTrait< SMatSMatAddExpr<MT1,MT2> >
643 typedef typename AddExprTrait< typename RowExprTrait<const MT1>::Type
644 ,
typename RowExprTrait<const MT2>::Type >::Type Type;
653 template<
typename MT1,
typename MT2 >
654 struct ColumnExprTrait< SMatSMatAddExpr<MT1,MT2> >
658 typedef typename AddExprTrait< typename ColumnExprTrait<const MT1>::Type
659 ,
typename ColumnExprTrait<const MT2>::Type >::Type Type;