22 #ifndef _BLAZE_MATH_EXPRESSIONS_SVECSVECMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_SVECSVECMULTEXPR_H_
66 template<
typename VT1
69 class SVecSVecMultExpr :
public SparseVector< SVecSVecMultExpr<VT1,VT2,TF>, TF >
70 ,
private VecVecMultExpr
75 typedef typename VT1::ResultType
RT1;
76 typedef typename VT2::ResultType
RT2;
77 typedef typename VT1::ReturnType
RN1;
78 typedef typename VT2::ReturnType
RN2;
79 typedef typename VT1::CompositeType
CT1;
80 typedef typename VT2::CompositeType
CT2;
81 typedef typename VT1::TransposeType
TT1;
82 typedef typename VT2::TransposeType
TT2;
187 template<
typename T >
189 return (
lhs_.canAlias( alias ) ||
rhs_.canAlias( alias ) );
199 template<
typename T >
201 return (
lhs_.isAliased( alias ) ||
rhs_.isAliased( alias ) );
223 template<
typename VT >
240 const LeftIterator lend( x.end() );
241 const RightIterator rend( y.end() );
243 LeftIterator l( x.begin() );
244 RightIterator r( y.begin() );
246 for( ; l!=lend; ++l ) {
247 while( r!=rend && r->index() < l->index() ) ++r;
249 if( l->index() == r->index() ) {
250 (~lhs)[l->index()] = l->value() * r->value();
270 template<
typename VT >
287 const LeftIterator lend( x.end() );
288 const RightIterator rend( y.end() );
290 LeftIterator l( x.begin() );
291 RightIterator r( y.begin() );
293 for( ; l!=lend; ++l ) {
294 while( r!=rend && r->index() < l->index() ) ++r;
296 if( l->index() == r->index() ) {
297 (~lhs).append( l->index(), l->value() * r->value() );
317 template<
typename VT >
324 typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
325 typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
334 const LeftIterator lend( x.end() );
335 const RightIterator rend( y.end() );
337 LeftIterator l( x.begin() );
338 RightIterator r( y.begin() );
340 for( ; l!=lend; ++l ) {
341 while( r!=rend && r->index() < l->index() ) ++r;
343 if( l->index() == r->index() ) {
344 (~lhs)[l->index()] += l->value() * r->value();
368 template<
typename VT >
375 typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
376 typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
385 const LeftIterator lend( x.end() );
386 const RightIterator rend( y.end() );
388 LeftIterator l( x.begin() );
389 RightIterator r( y.begin() );
391 for( ; l!=lend; ++l ) {
392 while( r!=rend && r->index() < l->index() ) ++r;
394 if( l->index() == r->index() ) {
395 (~lhs)[l->index()] -= l->value() * r->value();
419 template<
typename VT >
426 typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
427 typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
436 const LeftIterator lend( x.end() );
437 const RightIterator rend( y.end() );
439 LeftIterator l( x.begin() );
440 RightIterator r( y.begin() );
444 for( ; l!=lend; ++l ) {
445 while( r!=rend && r->index() < l->index() ) ++r;
447 if( l->index() == r->index() ) {
448 for( ; i<r->index(); ++i )
450 (~lhs)[l->index()] *= l->value() * r->value();
456 for( ; i<rhs.size(); ++i )
474 template<
typename VT >
481 typedef typename VT::ConstIterator Iterator1;
482 typedef typename RemoveReference<CT1>::Type::ConstIterator Iterator2;
483 typedef typename RemoveReference<CT2>::Type::ConstIterator Iterator3;
492 VT tmp( rhs.size(), rhs.nonZeros() );
494 const Iterator1 end1( (~lhs).end() );
495 const Iterator2 end2( x.end() );
496 const Iterator3 end3( y.end() );
498 Iterator1 i1( (~lhs).begin() );
499 Iterator2 i2( x.begin() );
500 Iterator3 i3( y.begin() );
502 for( ; i1!=end1; ++i1 ) {
503 while( i2!=end2 && i2->index() < i1->index() ) ++i2;
504 if( i2==end2 )
break;
505 while( i3!=end3 && i3->index() < i1->index() ) ++i3;
506 if( i3==end3 )
break;
507 if( i1->index() == i2->index() && i1->index() == i3->index() ) {
508 tmp.append( i1->index(), i1->value() * i2->value() * i3->value() );
564 template<
typename T1
567 inline const SVecSVecMultExpr<T1,T2,TF>
572 if( (~lhs).size() != (~rhs).size() )
573 throw std::invalid_argument(
"Vector sizes do not match" );