22 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATSVECMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_SMATSVECMULTEXPR_H_
31 #include <boost/type_traits/remove_reference.hpp>
74 class SMatSVecMultExpr :
public SparseVector< SMatSVecMultExpr<MT,VT>, false >
80 typedef typename MT::ResultType
MRT;
81 typedef typename VT::ResultType
VRT;
82 typedef typename MT::CompositeType
MCT;
83 typedef typename VT::CompositeType
VCT;
133 typedef typename boost::remove_reference<MCT>::type::ConstIterator MatrixIterator;
134 typedef typename boost::remove_reference<VCT>::type::ConstIterator VectorIterator;
139 if(
vec_.size() == 0UL )
149 MatrixIterator melem( A.begin(index) );
150 const MatrixIterator mend( A.end(index) );
151 if( melem == mend ) {
155 VectorIterator velem( x.begin() );
156 const VectorIterator vend( x.end() );
157 if( velem == vend ) {
162 if( melem->index() < velem->index() ) {
164 if( melem == mend )
break;
166 else if( velem->index() < melem->index() ) {
168 if( velem == vend )
break;
171 res = melem->value() * velem->value();
178 if( melem != mend && velem != vend )
181 if( melem->index() < velem->index() ) {
183 if( melem == mend )
break;
185 else if( velem->index() < melem->index() ) {
187 if( velem == vend )
break;
190 res += melem->value() * velem->value();
192 if( melem == mend )
break;
194 if( velem == vend )
break;
205 MatrixIterator melem( A.begin(index) );
206 const MatrixIterator mend( A.end(index) );
211 res = melem->value() *
vec_[melem->index()];
213 for( ; melem!=mend; ++melem ) {
214 res += melem->value() *
vec_[melem->index()];
223 VectorIterator velem( x.begin() );
224 const VectorIterator vend( x.end() );
229 res =
mat_(index,velem->index()) * velem->value();
231 for( ; velem!=vend; ++velem ) {
232 res +=
mat_(index,velem->index()) * velem->value();
239 for(
size_t j=1UL; j<
vec_.size(); ++j ) {
294 template<
typename T >
296 return (
mat_.isAliased( alias ) ||
vec_.isAliased( alias ) );
306 template<
typename T >
308 return (
mat_.isAliased( alias ) ||
vec_.isAliased( alias ) );
330 template<
typename VT1 >
337 typedef typename boost::remove_reference<LT>::type::ConstIterator MatrixIterator;
338 typedef typename boost::remove_reference<RT>::type::ConstIterator VectorIterator;
345 if( x.nonZeros() == 0UL )
return;
357 const VectorIterator vend( x.end() );
359 for(
size_t i=0UL; i<(~lhs).
size(); ++i )
361 const MatrixIterator mend ( A.end(i) );
362 MatrixIterator melem( A.begin(i) );
364 if( melem == mend )
continue;
366 VectorIterator velem( x.begin() );
369 if( melem->index() < velem->index() ) {
371 if( melem == mend )
break;
373 else if( velem->index() < melem->index() ) {
375 if( velem == vend )
break;
378 (~lhs)[i] = melem->value() * velem->value();
385 if( melem != mend && velem != vend )
388 if( melem->index() < velem->index() ) {
390 if( melem == mend )
break;
392 else if( velem->index() < melem->index() ) {
394 if( velem == vend )
break;
397 (~lhs)[i] += melem->value() * velem->value();
399 if( melem == mend )
break;
401 if( velem == vend )
break;
422 template<
typename VT1 >
429 typedef typename boost::remove_reference<LT>::type::ConstIterator MatrixIterator;
430 typedef typename boost::remove_reference<RT>::type::ConstIterator VectorIterator;
433 if( x.nonZeros() == 0UL )
return;
443 const VectorIterator vend( x.end() );
445 for(
size_t i=0UL; i<(~lhs).
size(); ++i )
447 const MatrixIterator mend ( A.end(i) );
448 MatrixIterator melem( A.begin(i) );
450 if( melem == mend )
continue;
452 VectorIterator velem( x.begin() );
457 if( melem->index() < velem->index() ) {
459 if( melem == mend )
break;
461 else if( velem->index() < melem->index() ) {
463 if( velem == vend )
break;
466 accu = melem->value() * velem->value();
473 if( melem != mend && velem != vend )
476 if( melem->index() < velem->index() ) {
478 if( melem == mend )
break;
480 else if( velem->index() < melem->index() ) {
482 if( velem == vend )
break;
485 accu += melem->value() * velem->value();
487 if( melem == mend )
break;
489 if( velem == vend )
break;
495 (~lhs).insert( i, accu );
513 template<
typename VT1 >
520 typedef typename boost::remove_reference<LT>::type::ConstIterator MatrixIterator;
521 typedef typename boost::remove_reference<RT>::type::ConstIterator VectorIterator;
525 if( x.nonZeros() == 0UL )
return;
537 const VectorIterator vend( x.end() );
539 for(
size_t i=0UL; i<(~lhs).
size(); ++i )
541 const MatrixIterator mend ( A.end(i) );
542 MatrixIterator melem( A.begin(i) );
544 if( melem == mend )
continue;
546 VectorIterator velem( x.begin() );
549 if( melem->index() < velem->index() ) {
551 if( melem == mend )
break;
553 else if( velem->index() < melem->index() ) {
555 if( velem == vend )
break;
558 (~lhs)[i] += melem->value() * velem->value();
560 if( melem == mend )
break;
562 if( velem == vend )
break;
586 template<
typename VT1 >
593 typedef typename boost::remove_reference<LT>::type::ConstIterator MatrixIterator;
594 typedef typename boost::remove_reference<RT>::type::ConstIterator VectorIterator;
598 if( x.nonZeros() == 0UL )
return;
610 const VectorIterator vend( x.end() );
612 for(
size_t i=0UL; i<(~lhs).
size(); ++i )
614 const MatrixIterator mend ( A.end(i) );
615 MatrixIterator melem( A.begin(i) );
617 if( melem == mend )
continue;
619 VectorIterator velem( x.begin() );
622 if( melem->index() < velem->index() ) {
624 if( melem == mend )
break;
626 else if( velem->index() < melem->index() ) {
628 if( velem == vend )
break;
631 (~lhs)[i] -= melem->value() * velem->value();
633 if( melem == mend )
break;
635 if( velem == vend )
break;
659 template<
typename VT1 >
731 template<
typename T1
733 inline const typename DisableIf< IsMatMatMultExpr<T1>, SMatSVecMultExpr<T1,T2> >::Type
738 if( (~mat).
columns() != (~vec).size() )
739 throw std::invalid_argument(
"Matrix and vector sizes do not match" );
767 template<
typename T1
770 inline const typename EnableIf< IsMatMatMultExpr<T1>, MultExprTrait<T1,T2> >::Type::Type
775 return (~mat).leftOperand() * ( (~mat).rightOperand() * vec );