22 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATSMATSUBEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_TSMATSMATSUBEXPR_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 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();
295 template<
typename MT >
301 typedef typename RT1::OppositeType::ConstIterator LeftIterator;
302 typedef typename boost::remove_reference<CT2>::type::ConstIterator RightIterator;
305 const typename RT1::OppositeType A( rhs.
lhs_ );
317 for(
size_t i=0UL; i<(~lhs).
rows(); ++i )
319 const LeftIterator lend( A.end(i) );
320 const RightIterator rend( B.end(i) );
322 LeftIterator l( A.begin(i) );
323 RightIterator r( B.begin(i) );
324 size_t nonzeros( A.nonZeros(i) + B.nonZeros(i) );
326 for( ; l!=lend && r!=rend; ++l ) {
327 while( r->index() < l->index() && ++r != rend ) {}
328 if( r!=rend && l->index() == r->index() ) {
336 (~lhs).reserve( i, nonzeros );
341 while( l != lend && r != rend )
343 if( l->index() < r->index() ) {
344 (~lhs).append( i, l->index(), l->value() );
347 else if( l->index() > r->index() ) {
348 (~lhs).append( i, r->index(), -r->value() );
352 (~lhs).append( i, l->index(), l->value()-r->value() );
359 (~lhs).append( i, l->index(), l->value() );
364 (~lhs).append( i, r->index(), -r->value() );
385 template<
typename MT >
391 typedef typename boost::remove_reference<CT1>::type::ConstIterator LeftIterator;
392 typedef typename RT2::OppositeType::ConstIterator RightIterator;
398 const typename RT2::OppositeType B( rhs.rhs_ );
407 for(
size_t j=0UL; j<(~lhs).
columns(); ++j )
409 const LeftIterator lend( A.end(j) );
410 const RightIterator rend( B.end(j) );
412 LeftIterator l( A.begin(j) );
413 RightIterator r( B.begin(j) );
414 size_t nonzeros( A.nonZeros(j) + B.nonZeros(j) );
416 for( ; l!=lend && r!=rend; ++l ) {
417 while( r->index() < l->index() && ++r != rend ) {}
418 if( r!=rend && l->index() == r->index() ) {
426 (~lhs).reserve( j, nonzeros );
431 while( l != lend && r != rend )
433 if( l->index() < r->index() ) {
434 (~lhs).append( l->index(), j, l->value() );
437 else if( l->index() > r->index() ) {
438 (~lhs).append( r->index(), j, -r->value() );
442 (~lhs).append( l->index(), j, l->value()-r->value() );
449 (~lhs).append( l->index(), j, l->value() );
454 (~lhs).append( r->index(), j, -r->value() );
475 template<
typename MT
505 template<
typename MT
579 template<
typename T1
585 throw std::invalid_argument(
"Matrix sizes do not match" );