22 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATTSMATSUBEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_SMATTSMATSUBEXPR_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::ReturnType
RN1;
77 typedef typename MT2::ReturnType
RN2;
78 typedef typename MT1::CompositeType
CT1;
79 typedef typename MT2::CompositeType
CT2;
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 j=0UL; j<(~lhs).
columns(); ++j ) {
269 const RightIterator end( B.end(j) );
270 for( RightIterator element=B.begin(j); element!=end; ++element ) {
271 if(
isDefault( (~lhs)(element->index(),j) ) )
272 (~lhs)(element->index(),j) = -element->value();
274 (~lhs)(element->index(),j) -= element->value();
294 template<
typename MT >
300 typedef typename boost::remove_reference<CT1>::type::ConstIterator LeftIterator;
301 typedef typename RT2::OppositeType::ConstIterator RightIterator;
307 const typename RT2::OppositeType B( rhs.
rhs_ );
316 for(
size_t i=0UL; i<(~lhs).
rows(); ++i )
318 const LeftIterator lend( A.end(i) );
319 const RightIterator rend( B.end(i) );
321 LeftIterator l( A.begin(i) );
322 RightIterator r( B.begin(i) );
323 size_t nonzeros( A.nonZeros(i) + B.nonZeros(i) );
325 for( ; l!=lend && r!=rend; ++l ) {
326 while( r->index() < l->index() && ++r != rend ) {}
327 if( r!=rend && l->index() == r->index() ) {
335 (~lhs).reserve( i, nonzeros );
340 while( l != lend && r != rend )
342 if( l->index() < r->index() ) {
343 (~lhs).append( i, l->index(), l->value() );
346 else if( l->index() > r->index() ) {
347 (~lhs).append( i, r->index(), -r->value() );
351 (~lhs).append( i, l->index(), l->value()-r->value() );
358 (~lhs).append( i, l->index(), l->value() );
363 (~lhs).append( i, r->index(), -r->value() );
383 template<
typename MT >
389 typedef typename RT1::OppositeType::ConstIterator LeftIterator;
390 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
393 const typename RT1::OppositeType A( rhs.lhs_ );
405 for(
size_t j=0UL; j<(~lhs).
columns(); ++j )
407 const LeftIterator lend( A.end(j) );
408 const RightIterator rend( B.end(j) );
410 LeftIterator l( A.begin(j) );
411 RightIterator r( B.begin(j) );
412 size_t nonzeros( A.nonZeros(j) + B.nonZeros(j) );
414 for( ; l!=lend && r!=rend; ++l ) {
415 while( r->index() < l->index() && ++r != rend ) {}
416 if( r!=rend && l->index() == r->index() ) {
424 (~lhs).reserve( j, nonzeros );
429 while( l != lend && r != rend )
431 if( l->index() < r->index() ) {
432 (~lhs).append( l->index(), j, l->value() );
435 else if( l->index() > r->index() ) {
436 (~lhs).append( r->index(), j, -r->value() );
440 (~lhs).append( l->index(), j, l->value()-r->value() );
447 (~lhs).append( l->index(), j, l->value() );
452 (~lhs).append( r->index(), j, -r->value() );
473 template<
typename MT
503 template<
typename MT
577 template<
typename T1
583 throw std::invalid_argument(
"Matrix sizes do not match" );