22 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATSMATADDEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_SMATSMATADDEXPR_H_
31 #include <boost/type_traits/remove_reference.hpp>
66 template<
typename MT1
74 typedef typename MT1::ResultType
RT1;
75 typedef typename MT2::ResultType
RT2;
76 typedef typename MT1::CompositeType
CT1;
77 typedef typename MT2::CompositeType
CT2;
78 typedef typename MT1::ReturnType
RN1;
79 typedef typename MT2::ReturnType
RN2;
167 return lhs_.columns();
177 return lhs_.nonZeros() +
rhs_.nonZeros();
188 return lhs_.nonZeros(i) +
rhs_.nonZeros(i);
218 template<
typename T >
245 template<
typename MT
252 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
268 for(
size_t i=0UL; i<(~lhs).
rows(); ++i ) {
269 const RightIterator end( B.end(i) );
270 for( RightIterator element=B.begin(i); element!=end; ++element ) {
271 if(
isDefault( (~lhs)(i,element->index()) ) )
272 (~lhs)(i,element->index()) = element->value();
274 (~lhs)(i,element->index()) += element->value();
294 template<
typename MT >
300 typedef typename boost::remove_reference<CT1>::type::ConstIterator LeftIterator;
301 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
313 for(
size_t i=0UL; i<(~lhs).
rows(); ++i )
315 const LeftIterator lend( A.end(i) );
316 const RightIterator rend( B.end(i) );
318 LeftIterator l( A.begin(i) );
319 RightIterator r( B.begin(i) );
320 size_t nonzeros( A.nonZeros(i) + B.nonZeros(i) );
322 for( ; l!=lend && r!=rend; ++l ) {
323 while( r->index() < l->index() && ++r != rend ) {}
324 if( r!=rend && l->index() == r->index() ) {
332 (~lhs).reserve( i, nonzeros );
337 while( l != lend && r != rend )
339 if( l->index() < r->index() ) {
340 (~lhs).append( i, l->index(), l->value() );
343 else if( l->index() > r->index() ) {
344 (~lhs).append( i, r->index(), r->value() );
348 (~lhs).append( i, l->index(), l->value()+r->value() );
355 (~lhs).append( i, l->index(), l->value() );
360 (~lhs).append( i, r->index(), r->value() );
380 template<
typename MT >
386 typedef typename boost::remove_reference<CT1>::type::ConstIterator LeftIterator;
387 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
399 const size_t m( rhs.rows() );
400 const size_t n( rhs.columns() );
403 std::vector<size_t> nonzeros( n, 0UL );
404 for(
size_t i=0UL; i<m; ++i )
406 const LeftIterator lend( A.end(i) );
407 const RightIterator rend( B.end(i) );
409 LeftIterator l( A.begin(i) );
410 RightIterator r( B.begin(i) );
412 while( l != lend && r != rend )
414 if( l->index() < r->index() ) {
415 ++nonzeros[l->index()];
418 else if( l->index() > r->index() ) {
419 ++nonzeros[r->index()];
423 ++nonzeros[l->index()];
430 ++nonzeros[l->index()];
435 ++nonzeros[r->index()];
441 for(
size_t j=0UL; j<n; ++j ) {
442 (~lhs).reserve( j, nonzeros[j] );
446 for(
size_t i=0UL; i<m; ++i )
448 const LeftIterator lend( A.end(i) );
449 const RightIterator rend( B.end(i) );
451 LeftIterator l( A.begin(i) );
452 RightIterator r( B.begin(i) );
454 while( l != lend && r != rend )
456 if( l->index() < r->index() ) {
457 (~lhs).append( i, l->index(), l->value() );
460 else if( l->index() > r->index() ) {
461 (~lhs).append( i, r->index(), r->value() );
465 (~lhs).append( i, l->index(), l->value()+r->value() );
472 (~lhs).append( i, l->index(), l->value() );
477 (~lhs).append( i, r->index(), r->value() );
497 template<
typename MT
526 template<
typename MT
597 template<
typename T1
603 throw std::invalid_argument(
"Matrix sizes do not match" );