DVecSVecOuterExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_DVECSVECOUTEREXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_DVECSVECOUTEREXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <utility>
45 #include <blaze/math/Aliases.h>
56 #include <blaze/math/Exception.h>
62 #include <blaze/math/shims/Reset.h>
64 #include <blaze/math/SIMD.h>
76 #include <blaze/util/Assert.h>
77 #include <blaze/util/EnableIf.h>
79 #include <blaze/util/mpl/If.h>
80 #include <blaze/util/Types.h>
84 #include <blaze/util/Unused.h>
85 
86 
87 namespace blaze {
88 
89 //=================================================================================================
90 //
91 // CLASS DVECSVECOUTEREXPR
92 //
93 //=================================================================================================
94 
95 //*************************************************************************************************
102 template< typename VT1 // Type of the left-hand side dense vector
103  , typename VT2 > // Type of the right-hand side sparse vector
105  : public VecTVecMultExpr< SparseMatrix< DVecSVecOuterExpr<VT1,VT2>, false > >
106  , private Computation
107 {
108  private:
109  //**Type definitions****************************************************************************
118  //**********************************************************************************************
119 
120  //**Return type evaluation**********************************************************************
122 
127  static constexpr bool returnExpr = ( !IsTemporary_v<RN1> && !IsTemporary_v<RN2> );
128 
130  using ExprReturnType = decltype( std::declval<RN1>() * std::declval<RN2>() );
131  //**********************************************************************************************
132 
133  //**Evaluation strategy*************************************************************************
135 
142  static constexpr bool useAssign =
143  ( IsComputation_v<VT1> || !IsNumeric_v<ET1> || IsComputation_v<VT2> || !IsNumeric_v<ET2> );
144 
146  template< typename MT >
148  static constexpr bool UseAssign_v = useAssign;
150  //**********************************************************************************************
151 
152  //**********************************************************************************************
154 
157  template< typename T1, typename T2, typename T3 >
158  static constexpr bool UseVectorizedKernel_v =
159  ( useOptimizedKernels &&
160  T1::simdEnabled && T2::simdEnabled &&
161  IsSame_v< ElementType_t<T1>, ElementType_t<T2> > &&
162  IsSame_v< ElementType_t<T1>, ElementType_t<T3> > &&
163  HasSIMDMult_v< ElementType_t<T1>, ElementType_t<T1> > );
165  //**********************************************************************************************
166 
167  //**********************************************************************************************
169 
172  template< typename T1, typename T2, typename T3 >
173  static constexpr bool UseDefaultKernel_v = !UseVectorizedKernel_v<T1,T2,T3>;
175  //**********************************************************************************************
176 
177  public:
178  //**Type definitions****************************************************************************
185 
188 
191 
193  using LeftOperand = If_t< IsExpression_v<VT1>, const VT1, const VT1& >;
194 
196  using RightOperand = If_t< IsExpression_v<VT2>, const VT2, const VT2& >;
197 
200 
203  //**********************************************************************************************
204 
205  //**ConstIterator class definition**************************************************************
209  {
210  public:
211  //**Type definitions*************************************************************************
214 
216  using LeftElement = ET1;
217 
220 
221  using IteratorCategory = std::forward_iterator_tag;
222  using ValueType = Element;
226 
227  // STL iterator requirements
233  //*******************************************************************************************
234 
235  //**Constructor******************************************************************************
239  : v_ ( v ) // Element of the left-hand side dense vector expression.
240  , it_( it ) // Iterator over the elements of the right-hand side sparse vector expression
241  {}
242  //*******************************************************************************************
243 
244  //**Prefix increment operator****************************************************************
250  ++it_;
251  return *this;
252  }
253  //*******************************************************************************************
254 
255  //**Element access operator******************************************************************
260  inline const Element operator*() const {
261  return Element( v_ * it_->value(), it_->index() );
262  }
263  //*******************************************************************************************
264 
265  //**Element access operator******************************************************************
270  inline const ConstIterator* operator->() const {
271  return this;
272  }
273  //*******************************************************************************************
274 
275  //**Value function***************************************************************************
280  inline ReturnType value() const {
281  return v_ * it_->value();
282  }
283  //*******************************************************************************************
284 
285  //**Index function***************************************************************************
290  inline size_t index() const {
291  return it_->index();
292  }
293  //*******************************************************************************************
294 
295  //**Equality operator************************************************************************
301  inline bool operator==( const ConstIterator& rhs ) const {
302  return it_ == rhs.it_;
303  }
304  //*******************************************************************************************
305 
306  //**Inequality operator**********************************************************************
312  inline bool operator!=( const ConstIterator& rhs ) const {
313  return it_ != rhs.it_;
314  }
315  //*******************************************************************************************
316 
317  //**Subtraction operator*********************************************************************
323  inline DifferenceType operator-( const ConstIterator& rhs ) const {
324  return it_ - rhs.it_;
325  }
326  //*******************************************************************************************
327 
328  private:
329  //**Member variables*************************************************************************
332  //*******************************************************************************************
333  };
334  //**********************************************************************************************
335 
336  //**Compilation flags***************************************************************************
338  static constexpr bool smpAssignable = false;
339  //**********************************************************************************************
340 
341  //**SIMD properties*****************************************************************************
343  static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
344  //**********************************************************************************************
345 
346  //**Constructor*********************************************************************************
352  explicit inline DVecSVecOuterExpr( const VT1& lhs, const VT2& rhs ) noexcept
353  : lhs_( lhs ) // Left-hand side dense vector of the multiplication expression
354  , rhs_( rhs ) // Right-hand side sparse vector of the multiplication expression
355  {}
356  //**********************************************************************************************
357 
358  //**Access operator*****************************************************************************
365  inline ReturnType operator()( size_t i, size_t j ) const {
366  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
367  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
368 
369  return lhs_[i] * rhs_[j];
370  }
371  //**********************************************************************************************
372 
373  //**At function*********************************************************************************
381  inline ReturnType at( size_t i, size_t j ) const {
382  if( i >= lhs_.size() ) {
383  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
384  }
385  if( j >= rhs_.size() ) {
386  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
387  }
388  return (*this)(i,j);
389  }
390  //**********************************************************************************************
391 
392  //**Begin function******************************************************************************
398  inline ConstIterator begin( size_t i ) const {
399  return ConstIterator( lhs_[i], rhs_.begin() );
400  }
401  //**********************************************************************************************
402 
403  //**End function********************************************************************************
409  inline ConstIterator end( size_t i ) const {
410  return ConstIterator( lhs_[i], rhs_.end() );
411  }
412  //**********************************************************************************************
413 
414  //**Rows function*******************************************************************************
419  inline size_t rows() const noexcept {
420  return lhs_.size();
421  }
422  //**********************************************************************************************
423 
424  //**Columns function****************************************************************************
429  inline size_t columns() const noexcept {
430  return rhs_.size();
431  }
432  //**********************************************************************************************
433 
434  //**NonZeros function***************************************************************************
439  inline size_t nonZeros() const {
440  return lhs_.size() * rhs_.nonZeros();
441  }
442  //**********************************************************************************************
443 
444  //**NonZeros function***************************************************************************
450  inline size_t nonZeros( size_t i ) const {
451  UNUSED_PARAMETER( i );
452  return rhs_.nonZeros();
453  }
454  //**********************************************************************************************
455 
456  //**Find function*******************************************************************************
463  inline ConstIterator find( size_t i, size_t j ) const {
465  return ConstIterator( lhs_[i], rhs_.find( j ) );
466  }
467  //**********************************************************************************************
468 
469  //**LowerBound function*************************************************************************
476  inline ConstIterator lowerBound( size_t i, size_t j ) const {
478  return ConstIterator( lhs_[i], rhs_.lowerBound( j ) );
479  }
480  //**********************************************************************************************
481 
482  //**UpperBound function*************************************************************************
489  inline ConstIterator upperBound( size_t i, size_t j ) const {
491  return ConstIterator( lhs_[i], rhs_.upperBound( j ) );
492  }
493  //**********************************************************************************************
494 
495  //**Left operand access*************************************************************************
500  inline LeftOperand leftOperand() const noexcept {
501  return lhs_;
502  }
503  //**********************************************************************************************
504 
505  //**Right operand access************************************************************************
510  inline RightOperand rightOperand() const noexcept {
511  return rhs_;
512  }
513  //**********************************************************************************************
514 
515  //**********************************************************************************************
521  template< typename T >
522  inline bool canAlias( const T* alias ) const noexcept {
523  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
524  }
525  //**********************************************************************************************
526 
527  //**********************************************************************************************
533  template< typename T >
534  inline bool isAliased( const T* alias ) const noexcept {
535  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
536  }
537  //**********************************************************************************************
538 
539  private:
540  //**Member variables****************************************************************************
543  //**********************************************************************************************
544 
545  //**Assignment to row-major dense matrices******************************************************
560  template< typename MT > // Type of the target dense matrix
561  friend inline auto assign( DenseMatrix<MT,false>& lhs, const DVecSVecOuterExpr& rhs )
563  {
565 
566  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
567  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
568 
569  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
570  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
571 
572  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
573  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
574  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
575  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
576 
577  const auto begin( y.begin() );
578  const auto end ( y.end() );
579 
580  for( size_t i=0UL; i<x.size(); ++i ) {
581  for( auto element=begin; element!=end; ++element ) {
582  (~lhs)(i,element->index()) = x[i] * element->value();
583  }
584  }
585  }
587  //**********************************************************************************************
588 
589  //**Assignment to column-major dense matrices***************************************************
602  template< typename MT > // Type of the target dense matrix
603  friend inline void assign( DenseMatrix<MT,true>& lhs, const DVecSVecOuterExpr& rhs )
604  {
606 
608 
609  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
610  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
611 
612  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
613  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
614 
615  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
616  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
617  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
618  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
619 
620  DVecSVecOuterExpr::selectAssignKernel( ~lhs, x, y );
621  }
623  //**********************************************************************************************
624 
625  //**Default assignment to column-major dense matrices*******************************************
639  template< typename MT // Type of the left-hand side target matrix
640  , typename VT3 // Type of the left-hand side vector operand
641  , typename VT4 > // Type of the right-hand side vector operand
642  static inline auto selectAssignKernel( MT& A, const VT3& x, const VT4& y )
643  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
644  {
645  const auto begin( y.begin() );
646  const auto end ( y.end() );
647 
648  for( auto element=begin; element!=end; ++element ) {
649  for( size_t i=0UL; i<x.size(); ++i ) {
650  A(i,element->index()) = x[i] * element->value();
651  }
652  }
653  }
655  //**********************************************************************************************
656 
657  //**Vectorized assignment to column-major dense matrices****************************************
671  template< typename MT // Type of the left-hand side target matrix
672  , typename VT3 // Type of the left-hand side vector operand
673  , typename VT4 > // Type of the right-hand side vector operand
674  static inline auto selectAssignKernel( MT& A, const VT3& x, const VT4& y )
675  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
676  {
677  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT3> );
678 
679  const size_t M( A.rows() );
680 
681  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
682  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
683 
684  const auto begin( y.begin() );
685  const auto end ( y.end() );
686 
687  for( auto element=begin; element!=end; ++element )
688  {
689  const SIMDTrait_t<ElementType> y1( set( element->value() ) );
690 
691  size_t i( 0UL );
692 
693  for( ; i<ipos; i+=SIMDSIZE ) {
694  A.store( i, element->index(), x.load(i) * y1 );
695  }
696  for( ; remainder && i<M; ++i ) {
697  A(i,element->index()) = x[i] * element->value();
698  }
699  }
700  }
702  //**********************************************************************************************
703 
704  //**Assignment to row-major sparse matrices*****************************************************
719  template< typename MT > // Type of the target sparse matrix
720  friend inline auto assign( SparseMatrix<MT,false>& lhs, const DVecSVecOuterExpr& rhs )
721  -> EnableIf_t< UseAssign_v<MT> >
722  {
724 
725  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
726  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns() , "Invalid number of columns" );
727  BLAZE_INTERNAL_ASSERT( (~lhs).capacity() >= rhs.nonZeros(), "Insufficient capacity" );
728 
729  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
730  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
731 
732  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
733  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
734  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
735  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
736 
737  // Final memory allocation (based on the evaluated operands)
738  (~lhs).reserve( x.size() * y.nonZeros() );
739 
740  // Performing the outer product
741  const auto begin( y.begin() );
742  const auto end ( y.end() );
743 
744  if( begin == end )
745  return;
746 
747  for( size_t i=0UL; i<x.size(); ++i ) {
748  if( !isDefault( x[i] ) ) {
749  for( auto element=begin; element!=end; ++element ) {
750  (~lhs).append( i, element->index(), x[i] * element->value() );
751  }
752  }
753  (~lhs).finalize( i );
754  }
755  }
757  //**********************************************************************************************
758 
759  //**Assignment to column-major sparse matrices*****************************************************
772  template< typename MT > // Type of the target sparse matrix
773  friend inline void assign( SparseMatrix<MT,true>& lhs, const DVecSVecOuterExpr& rhs )
774  {
776 
778 
779  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
780  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns() , "Invalid number of columns" );
781 
782  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
783  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
784 
785  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
786  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
787  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
788  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
789 
790  const auto begin( y.begin() );
791  const auto end ( y.end() );
792 
793  if( begin == end )
794  return;
795 
796  (~lhs).reserve( begin->index(), rhs.nonZeros() );
797 
798  size_t index( 0UL );
799 
800  for( auto element=begin; element!=end; ++element ) {
801  if( !isDefault( element->value() ) ) {
802  for( ; index < element->index(); ++index ) {
803  (~lhs).finalize( index );
804  }
805  for( size_t i=0UL; i<x.size(); ++i ) {
806  (~lhs).append( i, element->index(), x[i] * element->value() );
807  }
808  (~lhs).finalize( index++ );
809  }
810  }
811 
812  for( ; index < y.size(); ++index ) {
813  (~lhs).finalize( index );
814  }
815  }
817  //**********************************************************************************************
818 
819  //**Addition assignment to row-major dense matrices*********************************************
835  template< typename MT > // Type of the target dense matrix
836  friend inline auto addAssign( DenseMatrix<MT,false>& lhs, const DVecSVecOuterExpr& rhs )
837  -> EnableIf_t< UseAssign_v<MT> >
838  {
840 
841  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
842  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
843 
844  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
845  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
846 
847  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
848  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
849  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
850  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
851 
852  const auto begin( y.begin() );
853  const auto end ( y.end() );
854 
855  for( size_t i=0UL; i<x.size(); ++i ) {
856  if( !isDefault( x[i] ) ) {
857  for( auto element=begin; element!=end; ++element ) {
858  (~lhs)(i,element->index()) += x[i] * element->value();
859  }
860  }
861  }
862  }
864  //**********************************************************************************************
865 
866  //**Addition assignment to column-major dense matrices******************************************
879  template< typename MT > // Type of the target dense matrix
880  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const DVecSVecOuterExpr& rhs )
881  {
883 
885 
886  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
887  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
888 
889  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
890  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
891 
892  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
893  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
894  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
895  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
896 
897  DVecSVecOuterExpr::selectAddAssignKernel( ~lhs, x, y );
898  }
900  //**********************************************************************************************
901 
902  //**Default addition assignment to column dense matrices****************************************
916  template< typename MT // Type of the left-hand side target matrix
917  , typename VT3 // Type of the left-hand side vector operand
918  , typename VT4 > // Type of the right-hand side vector operand
919  static inline auto selectAddAssignKernel( MT& A, const VT3& x, const VT4& y )
920  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
921  {
922  const auto begin( y.begin() );
923  const auto end ( y.end() );
924 
925  for( auto element=begin; element!=end; ++element ) {
926  if( !isDefault( element->value() ) ) {
927  for( size_t i=0UL; i<x.size(); ++i ) {
928  A(i,element->index()) += x[i] * element->value();
929  }
930  }
931  }
932  }
934  //**********************************************************************************************
935 
936  //**Vectorized addition assignment to column-major dense matrices*******************************
950  template< typename MT // Type of the left-hand side target matrix
951  , typename VT3 // Type of the left-hand side vector operand
952  , typename VT4 > // Type of the right-hand side vector operand
953  static inline auto selectAddAssignKernel( MT& A, const VT3& x, const VT4& y )
954  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
955  {
956  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT3> );
957 
958  const size_t M( A.rows() );
959 
960  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
961  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
962 
963  const auto begin( y.begin() );
964  const auto end ( y.end() );
965 
966  for( auto element=begin; element!=end; ++element )
967  {
968  if( isDefault( element->value() ) ) continue;
969 
970  const SIMDTrait_t<ElementType> y1( set( element->value() ) );
971 
972  size_t i( 0UL );
973 
974  for( ; i<ipos; i+=SIMDSIZE ) {
975  A.store( i, element->index(), A.load(i,element->index()) + x.load(i) * y1 );
976  }
977  for( ; remainder && i<M; ++i ) {
978  A(i,element->index()) += x[i] * element->value();
979  }
980  }
981  }
983  //**********************************************************************************************
984 
985  //**Addition assignment to sparse matrices******************************************************
986  // No special implementation for the addition assignment to sparse matrices.
987  //**********************************************************************************************
988 
989  //**Subtraction assignment to row-major dense matrices******************************************
1005  template< typename MT > // Type of the target dense matrix
1006  friend inline auto subAssign( DenseMatrix<MT,false>& lhs, const DVecSVecOuterExpr& rhs )
1007  -> EnableIf_t< UseAssign_v<MT> >
1008  {
1010 
1011  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1012  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1013 
1014  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1015  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
1016 
1017  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1018  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1019  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1020  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1021 
1022  const auto begin( y.begin() );
1023  const auto end ( y.end() );
1024 
1025  for( size_t i=0UL; i<x.size(); ++i ) {
1026  if( !isDefault( x[i] ) ) {
1027  for( auto element=begin; element!=end; ++element ) {
1028  (~lhs)(i,element->index()) -= x[i] * element->value();
1029  }
1030  }
1031  }
1032  }
1034  //**********************************************************************************************
1035 
1036  //**Subtraction assignment to column-major dense matrices***************************************
1049  template< typename MT > // Type of the target dense matrix
1050  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const DVecSVecOuterExpr& rhs )
1051  {
1053 
1055 
1056  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1057  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1058 
1059  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1060  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
1061 
1062  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1063  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1064  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1065  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1066 
1067  DVecSVecOuterExpr::selectSubAssignKernel( ~lhs, x, y );
1068  }
1070  //**********************************************************************************************
1071 
1072  //**Default subtraction assignment to column dense matrices*************************************
1086  template< typename MT // Type of the left-hand side target matrix
1087  , typename VT3 // Type of the left-hand side vector operand
1088  , typename VT4 > // Type of the right-hand side vector operand
1089  static inline auto selectSubAssignKernel( MT& A, const VT3& x, const VT4& y )
1090  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
1091  {
1092  const auto begin( y.begin() );
1093  const auto end ( y.end() );
1094 
1095  for( auto element=begin; element!=end; ++element ) {
1096  if( !isDefault( element->value() ) ) {
1097  for( size_t i=0UL; i<x.size(); ++i ) {
1098  A(i,element->index()) -= x[i] * element->value();
1099  }
1100  }
1101  }
1102  }
1104  //**********************************************************************************************
1105 
1106  //**Vectorized subtraction assignment to column-major dense matrices****************************
1120  template< typename MT // Type of the left-hand side target matrix
1121  , typename VT3 // Type of the left-hand side vector operand
1122  , typename VT4 > // Type of the right-hand side vector operand
1123  static inline auto selectSubAssignKernel( MT& A, const VT3& x, const VT4& y )
1124  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
1125  {
1126  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT3> );
1127 
1128  const size_t M( A.rows() );
1129 
1130  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
1131  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
1132 
1133  const auto begin( y.begin() );
1134  const auto end ( y.end() );
1135 
1136  for( auto element=begin; element!=end; ++element )
1137  {
1138  if( isDefault( element->value() ) ) continue;
1139 
1140  const SIMDTrait_t<ElementType> y1( set( element->value() ) );
1141 
1142  size_t i( 0UL );
1143 
1144  for( ; i<ipos; i+=SIMDSIZE ) {
1145  A.store( i, element->index(), A.load(i,element->index()) - x.load(i) * y1 );
1146  }
1147  for( ; remainder && i<M; ++i ) {
1148  A(i,element->index()) -= x[i] * element->value();
1149  }
1150  }
1151  }
1153  //**********************************************************************************************
1154 
1155  //**Subtraction assignment to sparse matrices***************************************************
1156  // No special implementation for the subtraction assignment to sparse matrices.
1157  //**********************************************************************************************
1158 
1159  //**Schur product assignment to row-major dense matrices****************************************
1175  template< typename MT > // Type of the target dense matrix
1176  friend inline auto schurAssign( DenseMatrix<MT,false>& lhs, const DVecSVecOuterExpr& rhs )
1177  -> EnableIf_t< UseAssign_v<MT> >
1178  {
1180 
1181  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1182  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1183 
1184  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1185  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
1186 
1187  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1188  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1189  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1190  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1191 
1192  const auto end( y.end() );
1193 
1194  for( size_t i=0UL; i<x.size(); ++i )
1195  {
1196  size_t j( 0UL );
1197 
1198  for( auto element=y.begin(); element!=end; ++element, ++j ) {
1199  for( ; j<element->index(); ++j )
1200  reset( (~lhs)(i,j) );
1201  (~lhs)(i,element->index()) *= x[i] * element->value();
1202  }
1203 
1204  for( ; j<y.size(); ++j ) {
1205  reset( (~lhs)(i,j) );
1206  }
1207  }
1208  }
1210  //**********************************************************************************************
1211 
1212  //**Schur product assignment to column-major dense matrices*************************************
1225  template< typename MT > // Type of the target dense matrix
1226  friend inline void schurAssign( DenseMatrix<MT,true>& lhs, const DVecSVecOuterExpr& rhs )
1227  {
1229 
1231 
1232  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1233  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1234 
1235  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1236  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
1237 
1238  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1239  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1240  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1241  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1242 
1243  DVecSVecOuterExpr::selectSchurAssignKernel( ~lhs, x, y );
1244  }
1246  //**********************************************************************************************
1247 
1248  //**Default Schur product assignment to column dense matrices***********************************
1262  template< typename MT // Type of the left-hand side target matrix
1263  , typename VT3 // Type of the left-hand side vector operand
1264  , typename VT4 > // Type of the right-hand side vector operand
1265  static inline auto selectSchurAssignKernel( MT& A, const VT3& x, const VT4& y )
1266  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
1267  {
1268  const auto end( y.end() );
1269 
1270  size_t j( 0UL );
1271 
1272  for( auto element=y.begin(); element!=end; ++element )
1273  {
1274  if( isDefault( element->value() ) ) continue;
1275 
1276  for( ; j<element->index(); ++j ) {
1277  for( size_t i=0UL; i<x.size(); ++i )
1278  reset( A(i,j) );
1279  }
1280 
1281  for( size_t i=0UL; i<x.size(); ++i ) {
1282  A(i,element->index()) *= x[i] * element->value();
1283  }
1284 
1285  ++j;
1286  }
1287 
1288  for( ; j<y.size(); ++j ) {
1289  for( size_t i=0UL; i<x.size(); ++i )
1290  reset( A(i,j) );
1291  }
1292  }
1294  //**********************************************************************************************
1295 
1296  //**Vectorized Schur product assignment to column-major dense matrices**************************
1310  template< typename MT // Type of the left-hand side target matrix
1311  , typename VT3 // Type of the left-hand side vector operand
1312  , typename VT4 > // Type of the right-hand side vector operand
1313  static inline auto selectSchurAssignKernel( MT& A, const VT3& x, const VT4& y )
1314  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
1315  {
1316  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT3> );
1317 
1318  const size_t M( A.rows() );
1319  const size_t N( A.columns() );
1320 
1321  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
1322  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
1323 
1324  const auto begin( y.begin() );
1325  const auto end ( y.end() );
1326 
1327  size_t j( 0UL );
1328 
1329  for( auto element=begin; element!=end; ++element )
1330  {
1331  if( isDefault( element->value() ) ) continue;
1332 
1333  for( ; j<element->index(); ++j ) {
1334  for( size_t i=0UL; i<M; ++i )
1335  reset( A(i,j) );
1336  }
1337 
1338  const SIMDTrait_t<ElementType> y1( set( element->value() ) );
1339 
1340  size_t i( 0UL );
1341 
1342  for( ; i<ipos; i+=SIMDSIZE ) {
1343  A.store( i, element->index(), A.load(i,element->index()) * ( x.load(i) * y1 ) );
1344  }
1345  for( ; remainder && i<M; ++i ) {
1346  A(i,element->index()) *= x[i] * element->value();
1347  }
1348 
1349  ++j;
1350  }
1351 
1352  for( ; j<N; ++j ) {
1353  for( size_t i=0UL; i<M; ++i )
1354  reset( A(i,j) );
1355  }
1356  }
1358  //**********************************************************************************************
1359 
1360  //**Schur product assignment to sparse matrices*************************************************
1361  // No special implementation for the Schur product assignment to sparse matrices.
1362  //**********************************************************************************************
1363 
1364  //**Multiplication assignment to dense matrices*************************************************
1365  // No special implementation for the multiplication assignment to dense matrices.
1366  //**********************************************************************************************
1367 
1368  //**Multiplication assignment to sparse matrices************************************************
1369  // No special implementation for the multiplication assignment to sparse matrices.
1370  //**********************************************************************************************
1371 
1372  //**Compile time checks*************************************************************************
1381  //**********************************************************************************************
1382 };
1383 //*************************************************************************************************
1384 
1385 
1386 
1387 
1388 //=================================================================================================
1389 //
1390 // GLOBAL BINARY ARITHMETIC OPERATORS
1391 //
1392 //=================================================================================================
1393 
1394 //*************************************************************************************************
1407 template< typename VT1 // Type of the left-hand side dense vector
1408  , typename VT2 // Type of the right-hand side sparse vector
1409  , DisableIf_t< IsZero_v<VT2> >* = nullptr >
1410 inline const DVecSVecOuterExpr<VT1,VT2>
1411  dvecsvecouter( const DenseVector<VT1,false>& lhs, const SparseVector<VT2,true>& rhs )
1412 {
1414 
1415  return DVecSVecOuterExpr<VT1,VT2>( ~lhs, ~rhs );
1416 }
1418 //*************************************************************************************************
1419 
1420 
1421 //*************************************************************************************************
1434 template< typename VT1 // Type of the left-hand side dense vector
1435  , typename VT2 // Type of the right-hand side sparse vector
1436  , EnableIf_t< IsZero_v<VT2> >* = nullptr >
1437 inline decltype(auto)
1438  dvecsvecouter( const DenseVector<VT1,false>& lhs, const SparseVector<VT2,true>& rhs )
1439 {
1441 
1442  using ReturnType = const MultTrait_t< ResultType_t<VT1>, ResultType_t<VT2> >;
1443 
1446 
1447  return ReturnType( (~lhs).size(), (~rhs).size() );
1448 }
1450 //*************************************************************************************************
1451 
1452 
1453 //*************************************************************************************************
1482 template< typename VT1 // Type of the left-hand side dense vector
1483  , typename VT2 > // Type of the right-hand side sparse vector
1484 inline decltype(auto)
1485  operator*( const DenseVector<VT1,false>& lhs, const SparseVector<VT2,true>& rhs )
1486 {
1488 
1489  return dvecsvecouter( ~lhs, ~rhs );
1490 }
1491 //*************************************************************************************************
1492 
1493 
1494 
1495 
1496 //=================================================================================================
1497 //
1498 // SIZE SPECIALIZATIONS
1499 //
1500 //=================================================================================================
1501 
1502 //*************************************************************************************************
1504 template< typename VT1, typename VT2 >
1505 struct Size< DVecSVecOuterExpr<VT1,VT2>, 0UL >
1506  : public Size<VT1,0UL>
1507 {};
1508 
1509 template< typename VT1, typename VT2 >
1510 struct Size< DVecSVecOuterExpr<VT1,VT2>, 1UL >
1511  : public Size<VT2,0UL>
1512 {};
1514 //*************************************************************************************************
1515 
1516 } // namespace blaze
1517 
1518 #endif
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: DVecSVecOuterExpr.h:187
If_t< IsComputation_v< VT2 >, const RT2, CT2 > RT
Type for the assignment of the right-hand side dense vector operand.
Definition: DVecSVecOuterExpr.h:202
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: DVecSVecOuterExpr.h:534
Pointer difference type of the Blaze library.
Header file for auxiliary alias declarations.
static constexpr bool useAssign
Compilation switch for the evaluation strategy of the multiplication expression.
Definition: DVecSVecOuterExpr.h:142
LeftElement v_
Element of the left-hand side dense vector expression.
Definition: DVecSVecOuterExpr.h:330
Header file for the UNUSED_PARAMETER function template.
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:546
Header file for basic type definitions.
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: DVecSVecOuterExpr.h:184
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: DVecSVecOuterExpr.h:127
typename If< Condition, T1, T2 >::Type If_t
Auxiliary alias declaration for the If class template.The If_t alias declaration provides a convenien...
Definition: If.h:109
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: DVecSVecOuterExpr.h:429
ValueIndexPair< ElementType > Element
Element type of the sparse matrix expression.
Definition: DVecSVecOuterExpr.h:213
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.The ResultType_t alias declaration provides ...
Definition: Aliases.h:390
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a column dense or sparse vector type...
Definition: ColumnVector.h:61
Header file for the serial shim.
Expression object for dense vector-sparse vector outer products.The DVecSVecOuterExpr class represent...
Definition: DVecSVecOuterExpr.h:104
Header file for the IsSame and IsStrictlySame type traits.
const Element operator*() const
Direct access to the sparse matrix element at the current iterator position.
Definition: DVecSVecOuterExpr.h:260
Header file for the IsColumnMajorMatrix type trait.
If_t< IsExpression_v< VT2 >, const VT2, const VT2 &> RightOperand
Composite type of the right-hand side sparse vector expression.
Definition: DVecSVecOuterExpr.h:196
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:591
Constraint on the data type.
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: DVecSVecOuterExpr.h:381
Header file for the Computation base class.
Header file for the reset shim.
If_t< IsComputation_v< VT1 >, const RT1, CT1 > LT
Type for the assignment of the left-hand side dense vector operand.
Definition: DVecSVecOuterExpr.h:199
Constraints on the storage order of matrix types.
ResultType_t< VT1 > RT1
Result type of the left-hand side dense vector expression.
Definition: DVecSVecOuterExpr.h:110
System settings for performance optimizations.
constexpr void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
typename T::ReturnType ReturnType_t
Alias declaration for nested ReturnType type definitions.The ReturnType_t alias declaration provides ...
Definition: Aliases.h:410
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:137
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
ValueType & ReferenceType
Reference return type.
Definition: DVecSVecOuterExpr.h:224
ReturnType_t< VT1 > RN1
Return type of the left-hand side dense vector expression.
Definition: DVecSVecOuterExpr.h:112
static constexpr size_t SIMDSIZE
The number of elements packed within a single SIMD element.
Definition: DVecSVecOuterExpr.h:343
Header file for the SparseMatrix base class.
Constraint on the transpose flag of vector types.
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: DVecSVecOuterExpr.h:439
Constraint on the data type.
size_t index() const
Access to the current index of the sparse element.
Definition: DVecSVecOuterExpr.h:290
ValueType * PointerType
Pointer return type.
Definition: DVecSVecOuterExpr.h:223
ConstIterator end(size_t i) const
Returns an iterator just past the last non-zero element of row i.
Definition: DVecSVecOuterExpr.h:409
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.The EnableIf_t alias declaration provides a convenient...
Definition: EnableIf.h:138
IteratorType it_
Iterator over the elements of the right-hand side sparse vector expression.
Definition: DVecSVecOuterExpr.h:331
CompositeType_t< VT1 > CT1
Composite type of the left-hand side dense vector expression.
Definition: DVecSVecOuterExpr.h:114
IteratorCategory iterator_category
The iterator category.
Definition: DVecSVecOuterExpr.h:228
Header file for the ValueIndexPair class.
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: DVecSVecOuterExpr.h:338
Header file for the IsTemporary type trait class.
Header file for the multiplication trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
DVecSVecOuterExpr(const VT1 &lhs, const VT2 &rhs) noexcept
Constructor for the DVecSVecOuterExpr class.
Definition: DVecSVecOuterExpr.h:352
Iterator over the elements of the dense vector-sparse vector outer product expression.
Definition: DVecSVecOuterExpr.h:208
#define BLAZE_CONSTRAINT_MUST_BE_ZERO_TYPE(T)
Constraint on the data type.In case the given data type T is not a zero vector or matrix type...
Definition: Zero.h:61
ConstIterator lowerBound(size_t i, size_t j) const
Returns an iterator to the first index not less then the given index.
Definition: DVecSVecOuterExpr.h:476
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: DVecSVecOuterExpr.h:522
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_VECTVECMULTEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid vector/vector ...
Definition: VecTVecMultExpr.h:103
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DVecSVecOuterExpr.h:182
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
bool operator!=(const ConstIterator &rhs) const
Inequality comparison between two ConstIterator objects.
Definition: DVecSVecOuterExpr.h:312
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3086
ptrdiff_t DifferenceType
Difference between two iterators.
Definition: DVecSVecOuterExpr.h:225
Header file for all SIMD functionality.
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:76
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional vector type...
Definition: SparseVector.h:61
ElementType_t< VT2 > ET2
Element type of the right-hand side sparse vector expression.
Definition: DVecSVecOuterExpr.h:117
CompositeType_t< VT2 > CT2
Composite type of the right-hand side sparse vector expression.
Definition: DVecSVecOuterExpr.h:115
Constraint on the data type.
Header file for the exception macros of the math module.
bool operator==(const ConstIterator &rhs) const
Equality comparison between two ConstIterator objects.
Definition: DVecSVecOuterExpr.h:301
Constraint on the data type.
Header file for all forward declarations for expression class templates.
Constraint on the data type.
Header file for the VecTVecMultExpr base class.
If_t< useAssign, const ResultType, const DVecSVecOuterExpr &> CompositeType
Data type for composite expression templates.
Definition: DVecSVecOuterExpr.h:190
Header file for the EnableIf class template.
If_t< IsExpression_v< VT1 >, const VT1, const VT1 &> LeftOperand
Composite type of the left-hand side dense vector expression.
Definition: DVecSVecOuterExpr.h:193
Header file for the IsPadded type trait.
ResultType_t< VT2 > RT2
Result type of the right-hand side sparse vector expression.
Definition: DVecSVecOuterExpr.h:111
ReturnType value() const
Access to the current value of the sparse element.
Definition: DVecSVecOuterExpr.h:280
typename MultTrait< T1, T2 >::Type MultTrait_t
Auxiliary alias declaration for the MultTrait class template.The MultTrait_t alias declaration provid...
Definition: MultTrait.h:240
typename T::OppositeType OppositeType_t
Alias declaration for nested OppositeType type definitions.The OppositeType_t alias declaration provi...
Definition: Aliases.h:270
Header file for the IsNumeric type trait.
RightOperand rightOperand() const noexcept
Returns the right-hand side sparse vector operand.
Definition: DVecSVecOuterExpr.h:510
ConstIterator find(size_t i, size_t j) const
Searches for a specific matrix element.
Definition: DVecSVecOuterExpr.h:463
MultTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: DVecSVecOuterExpr.h:181
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
Header file for the HasSIMDMult type trait.
typename T::TransposeType TransposeType_t
Alias declaration for nested TransposeType type definitions.The TransposeType_t alias declaration pro...
Definition: Aliases.h:470
Header file for run time assertion macros.
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.The CompositeType_t alias declaration pro...
Definition: Aliases.h:90
ElementType_t< VT1 > ET1
Element type of the left-hand side dense vector expression.
Definition: DVecSVecOuterExpr.h:116
ET1 LeftElement
Element type of the dense vector expression.
Definition: DVecSVecOuterExpr.h:216
ConstIterator upperBound(size_t i, size_t j) const
Returns an iterator to the first index greater then the given index.
Definition: DVecSVecOuterExpr.h:489
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: DVecSVecOuterExpr.h:183
Header file for the IsZero type trait.
SIMD characteristics of data types.The SIMDTrait class template provides the SIMD characteristics of ...
Definition: SIMDTrait.h:295
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:94
Header file for the isDefault shim.
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
Constraint on the data type.
DifferenceType operator-(const ConstIterator &rhs) const
Calculating the number of elements between two expression iterators.
Definition: DVecSVecOuterExpr.h:323
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:808
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
Constraint on the data type.
Header file for the RemoveReference type trait.
Base class for all outer product expression templates.The VecTVecMultExpr class serves as a tag for a...
Definition: VecTVecMultExpr.h:67
typename T::ConstIterator ConstIterator_t
Alias declaration for nested ConstIterator type definitions.The ConstIterator_t alias declaration pro...
Definition: Aliases.h:110
std::forward_iterator_tag IteratorCategory
The iterator category.
Definition: DVecSVecOuterExpr.h:221
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3081
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional vector type...
Definition: DenseVector.h:61
LeftOperand lhs_
Left-hand side dense vector of the multiplication expression.
Definition: DVecSVecOuterExpr.h:541
Index-value-pair for sparse vectors and matrices.The ValueIndexPair class represents a single index-v...
Definition: ValueIndexPair.h:73
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: DVecSVecOuterExpr.h:365
ConstIterator_t< RemoveReference_t< RightOperand > > IteratorType
Iterator type of the sparse vector expression.
Definition: DVecSVecOuterExpr.h:219
RightOperand rhs_
Right-hand side sparse vector of the multiplication expression.
Definition: DVecSVecOuterExpr.h:542
Header file for the IsComputation type trait class.
Base class for all compute expression templates.The Computation class serves as a tag for all computa...
Definition: Computation.h:66
ConstIterator(LeftElement v, IteratorType it)
Constructor for the ConstIterator class.
Definition: DVecSVecOuterExpr.h:238
ConstIterator begin(size_t i) const
Returns an iterator to the first non-zero element of row i.
Definition: DVecSVecOuterExpr.h:398
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:138
ConstIterator & operator++()
Pre-increment operator.
Definition: DVecSVecOuterExpr.h:249
LeftOperand leftOperand() const noexcept
Returns the left-hand side dense vector operand.
Definition: DVecSVecOuterExpr.h:500
#define BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a row dense or sparse vector type (i...
Definition: RowVector.h:61
Element ValueType
Type of the underlying pointers.
Definition: DVecSVecOuterExpr.h:222
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:631
decltype(std::declval< RN1 >() *std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: DVecSVecOuterExpr.h:130
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: DVecSVecOuterExpr.h:450
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: DVecSVecOuterExpr.h:419
Header file for the Size type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_ZERO_TYPE(T)
Constraint on the data type.In case the given data type T is a zero vector or matrix type...
Definition: Zero.h:81
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
ReturnType_t< VT2 > RN2
Return type of the right-hand side sparse vector expression.
Definition: DVecSVecOuterExpr.h:113
Constraint on the transpose flag of vector types.
Header file for the IsExpression type trait class.
Header file for the function trace functionality.
const ConstIterator * operator->() const
Direct access to the sparse matrix element at the current iterator position.
Definition: DVecSVecOuterExpr.h:270