Blaze  3.6
SVecDVecOuterExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SVECDVECOUTEREXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SVECDVECOUTEREXPR_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/MaybeUnused.h>
80 #include <blaze/util/mpl/If.h>
81 #include <blaze/util/Types.h>
85 
86 
87 namespace blaze {
88 
89 //=================================================================================================
90 //
91 // CLASS SVECDVECOUTEREXPR
92 //
93 //=================================================================================================
94 
95 //*************************************************************************************************
102 template< typename VT1 // Type of the left-hand side sparse vector
103  , typename VT2 > // Type of the right-hand side dense vector
104 class SVecDVecOuterExpr
105  : public VecTVecMultExpr< SparseMatrix< SVecDVecOuterExpr<VT1,VT2>, true > >
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 
141  static constexpr bool useAssign =
142  ( IsComputation_v<VT1> || !IsNumeric_v<ET1> || IsComputation_v<VT2> || !IsNumeric_v<ET2> );
143 
145  template< typename MT >
147  static constexpr bool UseAssign_v = useAssign;
149  //**********************************************************************************************
150 
151  //**********************************************************************************************
153 
156  template< typename T1, typename T2, typename T3 >
157  static constexpr bool UseVectorizedKernel_v =
158  ( useOptimizedKernels &&
159  T1::simdEnabled && T3::simdEnabled &&
160  IsSame_v< ElementType_t<T1>, ElementType_t<T2> > &&
161  IsSame_v< ElementType_t<T1>, ElementType_t<T3> > &&
162  HasSIMDMult_v< ElementType_t<T1>, ElementType_t<T1> > );
164  //**********************************************************************************************
165 
166  //**********************************************************************************************
168 
171  template< typename T1, typename T2, typename T3 >
172  static constexpr bool UseDefaultKernel_v = !UseVectorizedKernel_v<T1,T2,T3>;
174  //**********************************************************************************************
175 
176  public:
177  //**Type definitions****************************************************************************
184 
187 
190 
192  using LeftOperand = If_t< IsExpression_v<VT1>, const VT1, const VT1& >;
193 
195  using RightOperand = If_t< IsExpression_v<VT2>, const VT2, const VT2& >;
196 
199 
202  //**********************************************************************************************
203 
204  //**ConstIterator class definition**************************************************************
208  {
209  public:
210  //**Type definitions*************************************************************************
213 
216 
218  using RightElement = ET2;
219 
220  using IteratorCategory = std::forward_iterator_tag;
221  using ValueType = Element;
225 
226  // STL iterator requirements
232  //*******************************************************************************************
233 
234  //**Constructor******************************************************************************
238  : it_( it ) // Iterator over the elements of the left-hand side sparse vector expression
239  , v_ ( v ) // Element of the right-hand side dense vector expression.
240  {}
241  //*******************************************************************************************
242 
243  //**Prefix increment operator****************************************************************
249  ++it_;
250  return *this;
251  }
252  //*******************************************************************************************
253 
254  //**Element access operator******************************************************************
259  inline const Element operator*() const {
260  return Element( it_->value() * v_, it_->index() );
261  }
262  //*******************************************************************************************
263 
264  //**Element access operator******************************************************************
269  inline const ConstIterator* operator->() const {
270  return this;
271  }
272  //*******************************************************************************************
273 
274  //**Value function***************************************************************************
279  inline ReturnType value() const {
280  return it_->value() * v_;
281  }
282  //*******************************************************************************************
283 
284  //**Index function***************************************************************************
289  inline size_t index() const {
290  return it_->index();
291  }
292  //*******************************************************************************************
293 
294  //**Equality operator************************************************************************
300  inline bool operator==( const ConstIterator& rhs ) const {
301  return it_ == rhs.it_;
302  }
303  //*******************************************************************************************
304 
305  //**Inequality operator**********************************************************************
311  inline bool operator!=( const ConstIterator& rhs ) const {
312  return it_ != rhs.it_;
313  }
314  //*******************************************************************************************
315 
316  //**Subtraction operator*********************************************************************
322  inline DifferenceType operator-( const ConstIterator& rhs ) const {
323  return it_ - rhs.it_;
324  }
325  //*******************************************************************************************
326 
327  private:
328  //**Member variables*************************************************************************
331  //*******************************************************************************************
332  };
333  //**********************************************************************************************
334 
335  //**Compilation flags***************************************************************************
337  static constexpr bool smpAssignable = false;
338  //**********************************************************************************************
339 
340  //**SIMD properties*****************************************************************************
342  static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
343  //**********************************************************************************************
344 
345  //**Constructor*********************************************************************************
351  explicit inline SVecDVecOuterExpr( const VT1& lhs, const VT2& rhs ) noexcept
352  : lhs_( lhs ) // Left-hand side sparse vector of the multiplication expression
353  , rhs_( rhs ) // Right-hand side dense vector of the multiplication expression
354  {}
355  //**********************************************************************************************
356 
357  //**Access operator*****************************************************************************
364  inline ReturnType operator()( size_t i, size_t j ) const {
365  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
366  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
367 
368  return lhs_[i] * rhs_[j];
369  }
370  //**********************************************************************************************
371 
372  //**At function*********************************************************************************
380  inline ReturnType at( size_t i, size_t j ) const {
381  if( i >= lhs_.size() ) {
382  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
383  }
384  if( j >= rhs_.size() ) {
385  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
386  }
387  return (*this)(i,j);
388  }
389  //**********************************************************************************************
390 
391  //**Begin function******************************************************************************
397  inline ConstIterator begin( size_t i ) const {
398  return ConstIterator( lhs_.begin(), rhs_[i] );
399  }
400  //**********************************************************************************************
401 
402  //**End function********************************************************************************
408  inline ConstIterator end( size_t i ) const {
409  return ConstIterator( lhs_.end(), rhs_[i] );
410  }
411  //**********************************************************************************************
412 
413  //**Rows function*******************************************************************************
418  inline size_t rows() const noexcept {
419  return lhs_.size();
420  }
421  //**********************************************************************************************
422 
423  //**Columns function****************************************************************************
428  inline size_t columns() const noexcept {
429  return rhs_.size();
430  }
431  //**********************************************************************************************
432 
433  //**NonZeros function***************************************************************************
438  inline size_t nonZeros() const {
439  return lhs_.nonZeros() * rhs_.size();
440  }
441  //**********************************************************************************************
442 
443  //**NonZeros function***************************************************************************
449  inline size_t nonZeros( size_t i ) const {
450  MAYBE_UNUSED( i );
451  return lhs_.nonZeros();
452  }
453  //**********************************************************************************************
454 
455  //**Find function*******************************************************************************
462  inline ConstIterator find( size_t i, size_t j ) const {
464  return ConstIterator( lhs_.find( i ), rhs_[j] );
465  }
466  //**********************************************************************************************
467 
468  //**LowerBound function*************************************************************************
475  inline ConstIterator lowerBound( size_t i, size_t j ) const {
477  return ConstIterator( lhs_.lowerBound( i ), rhs_[j] );
478  }
479  //**********************************************************************************************
480 
481  //**UpperBound function*************************************************************************
488  inline ConstIterator upperBound( size_t i, size_t j ) const {
490  return ConstIterator( lhs_.upperBound( i ), rhs_[j] );
491  }
492  //**********************************************************************************************
493 
494  //**Left operand access*************************************************************************
499  inline LeftOperand leftOperand() const noexcept {
500  return lhs_;
501  }
502  //**********************************************************************************************
503 
504  //**Right operand access************************************************************************
509  inline RightOperand rightOperand() const noexcept {
510  return rhs_;
511  }
512  //**********************************************************************************************
513 
514  //**********************************************************************************************
520  template< typename T >
521  inline bool canAlias( const T* alias ) const noexcept {
522  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
523  }
524  //**********************************************************************************************
525 
526  //**********************************************************************************************
532  template< typename T >
533  inline bool isAliased( const T* alias ) const noexcept {
534  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
535  }
536  //**********************************************************************************************
537 
538  private:
539  //**Member variables****************************************************************************
542  //**********************************************************************************************
543 
544  //**Assignment to row-major dense matrices******************************************************
556  template< typename MT > // Type of the target dense matrix
557  friend inline void assign( DenseMatrix<MT,false>& lhs, const SVecDVecOuterExpr& rhs )
558  {
560 
562 
563  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
564  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
565 
566  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
567  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
568 
569  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
570  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
571  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
572  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
573 
574  SVecDVecOuterExpr::selectAssignKernel( ~lhs, x, y );
575  }
577  //**********************************************************************************************
578 
579  //**Default assignment to row-major dense matrices**********************************************
593  template< typename MT // Type of the left-hand side target matrix
594  , typename VT3 // Type of the left-hand side vector operand
595  , typename VT4 > // Type of the right-hand side vector operand
596  static inline auto selectAssignKernel( MT& A, const VT3& x, const VT4& y )
597  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
598  {
599  const auto end( x.end() );
600 
601  for( auto element=x.begin(); element!=end; ++element ) {
602  if( !isDefault( element->value() ) ) {
603  for( size_t j=0UL; j<y.size(); ++j ) {
604  A(element->index(),j) = element->value() * y[j];
605  }
606  }
607  }
608  }
610  //**********************************************************************************************
611 
612  //**Vectorized assignment to row-major dense matrices*******************************************
626  template< typename MT // Type of the left-hand side target matrix
627  , typename VT3 // Type of the left-hand side vector operand
628  , typename VT4 > // Type of the right-hand side vector operand
629  static inline auto selectAssignKernel( MT& A, const VT3& x, const VT4& y )
630  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
631  {
632  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT4> );
633 
634  const size_t N( A.columns() );
635 
636  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
637  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
638 
639  const auto begin( x.begin() );
640  const auto end ( x.end() );
641 
642  for( auto element=begin; element!=end; ++element )
643  {
644  const SIMDTrait_t<ElementType> x1( set( element->value() ) );
645 
646  size_t j( 0UL );
647 
648  for( ; j<jpos; j+=SIMDSIZE ) {
649  A.store( element->index(), j, x1 * y.load(j) );
650  }
651  for( ; remainder && j<N; ++j ) {
652  A(element->index(),j) = element->value() * y[j];
653  }
654  }
655  }
657  //**********************************************************************************************
658 
659  //**Assignment to column-major dense matrices***************************************************
675  template< typename MT > // Type of the target dense matrix
676  friend inline auto assign( DenseMatrix<MT,true>& lhs, const SVecDVecOuterExpr& rhs )
677  -> EnableIf_t< UseAssign_v<MT> >
678  {
680 
681  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
682  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
683 
684  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
685  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
686 
687  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
688  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
689  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
690  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
691 
692  const auto end( x.end() );
693 
694  for( size_t i=0UL; i<y.size(); ++i ) {
695  if( !isDefault( y[i] ) ) {
696  for( auto element=x.begin(); element!=end; ++element ) {
697  (~lhs)(element->index(),i) = element->value() * y[i];
698  }
699  }
700  }
701  }
703  //**********************************************************************************************
704 
705  //**Assignment to row-major sparse matrices*****************************************************
717  template< typename MT > // Type of the target sparse matrix
718  friend inline void assign( SparseMatrix<MT,false>& lhs, const SVecDVecOuterExpr& rhs )
719  {
721 
723 
724  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
725  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns() , "Invalid number of columns" );
726 
727  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
728  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
729 
730  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
731  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
732  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
733  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
734 
735  // Final memory allocation (based on the evaluated operands)
736  (~lhs).reserve( x.nonZeros() * y.size() );
737 
738  // Performing the outer product
739  const auto begin( x.begin() );
740  const auto end ( x.end() );
741 
742  if( begin == end )
743  return;
744 
745  (~lhs).reserve( begin->index(), rhs.nonZeros() );
746 
747  size_t index( 0UL );
748 
749  for( auto element=begin; element!=end; ++element ) {
750  if( !isDefault( element->value() ) ) {
751  for( ; index < element->index(); ++index ) {
752  (~lhs).finalize( index );
753  }
754  for( size_t i=0UL; i<y.size(); ++i ) {
755  (~lhs).append( element->index(), i, element->value() * y[i] );
756  }
757  (~lhs).finalize( index++ );
758  }
759  }
760 
761  for( ; index < x.size(); ++index ) {
762  (~lhs).finalize( index );
763  }
764  }
766  //**********************************************************************************************
767 
768  //**Assignment to column-major sparse matrices**************************************************
784  template< typename MT > // Type of the target sparse matrix
785  friend inline auto assign( SparseMatrix<MT,true>& lhs, const SVecDVecOuterExpr& rhs )
786  -> EnableIf_t< UseAssign_v<MT> >
787  {
789 
790  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
791  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns() , "Invalid number of columns" );
792  BLAZE_INTERNAL_ASSERT( (~lhs).capacity() >= rhs.nonZeros(), "Insufficient capacity" );
793 
794  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
795  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
796 
797  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
798  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
799  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
800  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
801 
802  const auto begin( x.begin() );
803  const auto end ( x.end() );
804 
805  if( begin == end )
806  return;
807 
808  for( size_t i=0UL; i<y.size(); ++i ) {
809  if( !isDefault( y[i] ) ) {
810  for( auto element=begin; element!=end; ++element ) {
811  (~lhs).append( element->index(), i, element->value() * y[i] );
812  }
813  }
814  (~lhs).finalize( i );
815  }
816  }
818  //**********************************************************************************************
819 
820  //**Addition assignment to row-major dense matrices*********************************************
833  template< typename MT > // Type of the target dense matrix
834  friend inline void addAssign( DenseMatrix<MT,false>& lhs, const SVecDVecOuterExpr& rhs )
835  {
837 
839 
840  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
841  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
842 
843  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
844  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
845 
846  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
847  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
848  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
849  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
850 
851  SVecDVecOuterExpr::selectAddAssignKernel( ~lhs, x, y );
852  }
854  //**********************************************************************************************
855 
856  //**Default addition assignment to row-major dense matrices*************************************
870  template< typename MT // Type of the left-hand side target matrix
871  , typename VT3 // Type of the left-hand side vector operand
872  , typename VT4 > // Type of the right-hand side vector operand
873  static inline auto selectAddAssignKernel( MT& A, const VT3& x, const VT4& y )
874  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
875  {
876  const auto end( x.end() );
877 
878  for( auto element=x.begin(); element!=end; ++element ) {
879  if( !isDefault( element->value() ) ) {
880  for( size_t i=0UL; i<y.size(); ++i ) {
881  A(element->index(),i) += element->value() * y[i];
882  }
883  }
884  }
885  }
887  //**********************************************************************************************
888 
889  //**Vectorized addition assignment to row-major dense matrices**********************************
903  template< typename MT // Type of the left-hand side target matrix
904  , typename VT3 // Type of the left-hand side vector operand
905  , typename VT4 > // Type of the right-hand side vector operand
906  static inline auto selectAddAssignKernel( MT& A, const VT3& x, const VT4& y )
907  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
908  {
909  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT4> );
910 
911  const size_t N( A.columns() );
912 
913  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
914  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
915 
916  const auto begin( x.begin() );
917  const auto end ( x.end() );
918 
919  for( auto element=begin; element!=end; ++element )
920  {
921  if( isDefault( element->value() ) ) continue;
922 
923  const SIMDTrait_t<ElementType> x1( set( element->value() ) );
924 
925  size_t j( 0UL );
926 
927  for( ; j<jpos; j+=SIMDSIZE ) {
928  A.store( element->index(), j, A.load(element->index(),j) + x1 * y.load(j) );
929  }
930  for( ; remainder && j<N; ++j ) {
931  A(element->index(),j) += element->value() * y[j];
932  }
933  }
934  }
936  //**********************************************************************************************
937 
938  //**Addition assignment to column-major dense matrices******************************************
954  template< typename MT > // Type of the target dense matrix
955  friend inline auto addAssign( DenseMatrix<MT,true>& lhs, const SVecDVecOuterExpr& rhs )
956  -> EnableIf_t< UseAssign_v<MT> >
957  {
959 
960  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
961  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
962 
963  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
964  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
965 
966  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
967  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
968  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
969  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
970 
971  const auto end( x.end() );
972 
973  for( size_t i=0UL; i<y.size(); ++i ) {
974  if( !isDefault( y[i] ) ) {
975  for( auto element=x.begin(); element!=end; ++element ) {
976  (~lhs)(element->index(),i) += element->value() * y[i];
977  }
978  }
979  }
980  }
982  //**********************************************************************************************
983 
984  //**Addition assignment to sparse matrices******************************************************
985  // No special implementation for the addition assignment to sparse matrices.
986  //**********************************************************************************************
987 
988  //**Subtraction assignment to row-major dense matrices******************************************
1001  template< typename MT > // Type of the target dense matrix
1002  friend inline void subAssign( DenseMatrix<MT,false>& lhs, const SVecDVecOuterExpr& rhs )
1003  {
1005 
1007 
1008  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1009  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1010 
1011  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
1012  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1013 
1014  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1015  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1016  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1017  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1018 
1019  SVecDVecOuterExpr::selectSubAssignKernel( ~lhs, x, y );
1020  }
1022  //**********************************************************************************************
1023 
1024  //**Default subtraction assignment to row-major dense matrices**********************************
1038  template< typename MT // Type of the left-hand side target matrix
1039  , typename VT3 // Type of the left-hand side vector operand
1040  , typename VT4 > // Type of the right-hand side vector operand
1041  static inline auto selectSubAssignKernel( MT& A, const VT3& x, const VT4& y )
1042  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
1043  {
1044  const auto end( x.end() );
1045 
1046  for( auto element=x.begin(); element!=end; ++element ) {
1047  if( !isDefault( element->value() ) ) {
1048  for( size_t i=0UL; i<y.size(); ++i ) {
1049  A(element->index(),i) -= element->value() * y[i];
1050  }
1051  }
1052  }
1053  }
1055  //**********************************************************************************************
1056 
1057  //**Vectorized subtraction assignment to row-major dense matrices*******************************
1071  template< typename MT // Type of the left-hand side target matrix
1072  , typename VT3 // Type of the left-hand side vector operand
1073  , typename VT4 > // Type of the right-hand side vector operand
1074  static inline auto selectSubAssignKernel( MT& A, const VT3& x, const VT4& y )
1075  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
1076  {
1077  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT4> );
1078 
1079  const size_t N( A.columns() );
1080 
1081  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
1082  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
1083 
1084  const auto begin( x.begin() );
1085  const auto end ( x.end() );
1086 
1087  for( auto element=begin; element!=end; ++element )
1088  {
1089  if( isDefault( element->value() ) ) continue;
1090 
1091  const SIMDTrait_t<ElementType> x1( set( element->value() ) );
1092 
1093  size_t j( 0UL );
1094 
1095  for( ; j<jpos; j+=SIMDSIZE ) {
1096  A.store( element->index(), j, A.load(element->index(),j) - x1 * y.load(j) );
1097  }
1098  for( ; remainder && j<N; ++j ) {
1099  A(element->index(),j) -= element->value() * y[j];
1100  }
1101  }
1102  }
1104  //**********************************************************************************************
1105 
1106  //**Subtraction assignment to column-major dense matrices***************************************
1122  template< typename MT > // Type of the target dense matrix
1123  friend inline auto subAssign( DenseMatrix<MT,true>& lhs, const SVecDVecOuterExpr& rhs )
1124  -> EnableIf_t< UseAssign_v<MT> >
1125  {
1127 
1128  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1129  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1130 
1131  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
1132  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1133 
1134  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1135  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1136  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1137  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1138 
1139  const auto end( x.end() );
1140 
1141  for( size_t i=0UL; i<y.size(); ++i ) {
1142  if( !isDefault( y[i] ) ) {
1143  for( auto element=x.begin(); element!=end; ++element ) {
1144  (~lhs)(element->index(),i) -= element->value() * y[i];
1145  }
1146  }
1147  }
1148  }
1150  //**********************************************************************************************
1151 
1152  //**Subtraction assignment to sparse matrices***************************************************
1153  // No special implementation for the subtraction assignment to sparse matrices.
1154  //**********************************************************************************************
1155 
1156  //**Schur product assignment to row-major dense matrices****************************************
1169  template< typename MT > // Type of the target dense matrix
1170  friend inline void schurAssign( DenseMatrix<MT,false>& lhs, const SVecDVecOuterExpr& rhs )
1171  {
1173 
1175 
1176  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1177  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1178 
1179  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
1180  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1181 
1182  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1183  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1184  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1185  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1186 
1187  SVecDVecOuterExpr::selectSchurAssignKernel( ~lhs, x, y );
1188  }
1190  //**********************************************************************************************
1191 
1192  //**Default Schur product assignment to row-major dense matrices********************************
1206  template< typename MT // Type of the left-hand side target matrix
1207  , typename VT3 // Type of the left-hand side vector operand
1208  , typename VT4 > // Type of the right-hand side vector operand
1209  static inline auto selectSchurAssignKernel( MT& A, const VT3& x, const VT4& y )
1210  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
1211  {
1212  const auto end( x.end() );
1213 
1214  size_t i( 0UL );
1215 
1216  for( auto element=x.begin(); element!=end; ++element )
1217  {
1218  if( isDefault( element->value() ) ) continue;
1219 
1220  for( ; i<element->index(); ++i ) {
1221  for( size_t j=0UL; j<y.size(); ++j )
1222  reset( A(i,j) );
1223  }
1224 
1225  for( size_t j=0UL; j<y.size(); ++j ) {
1226  A(element->index(),j) *= element->value() * y[j];
1227  }
1228 
1229  ++i;
1230  }
1231 
1232  for( ; i<x.size(); ++i ) {
1233  for( size_t j=0UL; j<y.size(); ++j )
1234  reset( A(i,j) );
1235  }
1236  }
1238  //**********************************************************************************************
1239 
1240  //**Vectorized Schur product assignment to row-major dense matrices*****************************
1254  template< typename MT // Type of the left-hand side target matrix
1255  , typename VT3 // Type of the left-hand side vector operand
1256  , typename VT4 > // Type of the right-hand side vector operand
1257  static inline auto selectSchurAssignKernel( MT& A, const VT3& x, const VT4& y )
1258  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
1259  {
1260  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT4> );
1261 
1262  const size_t M( A.rows() );
1263  const size_t N( A.columns() );
1264 
1265  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
1266  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
1267 
1268  const auto begin( x.begin() );
1269  const auto end ( x.end() );
1270 
1271  size_t i( 0UL );
1272 
1273  for( auto element=begin; element!=end; ++element )
1274  {
1275  if( isDefault( element->value() ) ) continue;
1276 
1277  for( ; i<element->index(); ++i ) {
1278  for( size_t j=0UL; j<N; ++j )
1279  reset( A(i,j) );
1280  }
1281 
1282  const SIMDTrait_t<ElementType> x1( set( element->value() ) );
1283 
1284  size_t j( 0UL );
1285 
1286  for( ; j<jpos; j+=SIMDSIZE ) {
1287  A.store( element->index(), j, A.load(element->index(),j) * ( x1 * y.load(j) ) );
1288  }
1289  for( ; remainder && j<N; ++j ) {
1290  A(element->index(),j) *= element->value() * y[j];
1291  }
1292 
1293  ++i;
1294  }
1295 
1296  for( ; i<M; ++i ) {
1297  for( size_t j=0UL; j<N; ++j )
1298  reset( A(i,j) );
1299  }
1300  }
1302  //**********************************************************************************************
1303 
1304  //**Schur product assignment to column-major dense matrices*************************************
1320  template< typename MT > // Type of the target dense matrix
1321  friend inline auto schurAssign( DenseMatrix<MT,true>& lhs, const SVecDVecOuterExpr& rhs )
1322  -> EnableIf_t< UseAssign_v<MT> >
1323  {
1325 
1326  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1327  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1328 
1329  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
1330  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1331 
1332  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1333  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1334  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1335  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1336 
1337  const auto end( x.end() );
1338 
1339  for( size_t j=0UL; j<y.size(); ++j )
1340  {
1341  size_t i( 0UL );
1342 
1343  for( auto element=x.begin(); element!=end; ++element, ++i ) {
1344  for( ; i<element->index(); ++i )
1345  reset( (~lhs)(i,j) );
1346  (~lhs)(element->index(),j) *= element->value() * y[j];
1347  }
1348 
1349  for( ; i<x.size(); ++i ) {
1350  reset( (~lhs)(i,j) );
1351  }
1352  }
1353  }
1355  //**********************************************************************************************
1356 
1357  //**Addition assignment to sparse matrices******************************************************
1358  // No special implementation for the addition assignment to sparse matrices.
1359  //**********************************************************************************************
1360 
1361  //**Multiplication assignment to dense matrices*************************************************
1362  // No special implementation for the multiplication assignment to dense matrices.
1363  //**********************************************************************************************
1364 
1365  //**Multiplication assignment to sparse matrices************************************************
1366  // No special implementation for the multiplication assignment to sparse matrices.
1367  //**********************************************************************************************
1368 
1369  //**Compile time checks*************************************************************************
1378  //**********************************************************************************************
1379 };
1380 //*************************************************************************************************
1381 
1382 
1383 
1384 
1385 //=================================================================================================
1386 //
1387 // GLOBAL BINARY ARITHMETIC OPERATORS
1388 //
1389 //=================================================================================================
1390 
1391 //*************************************************************************************************
1404 template< typename VT1 // Type of the left-hand side sparse vector
1405  , typename VT2 // Type of the right-hand side dense vector
1406  , DisableIf_t< IsZero_v<VT1> >* = nullptr >
1407 inline const SVecDVecOuterExpr<VT1,VT2>
1408  svecdvecouter( const SparseVector<VT1,false>& lhs, const DenseVector<VT2,true>& rhs )
1409 {
1411 
1412  return SVecDVecOuterExpr<VT1,VT2>( ~lhs, ~rhs );
1413 }
1415 //*************************************************************************************************
1416 
1417 
1418 //*************************************************************************************************
1431 template< typename VT1 // Type of the left-hand side dense vector
1432  , typename VT2 // Type of the right-hand side sparse vector
1433  , EnableIf_t< IsZero_v<VT1> >* = nullptr >
1434 inline decltype(auto)
1435  svecdvecouter( const SparseVector<VT1,false>& lhs, const DenseVector<VT2,true>& rhs )
1436 {
1438 
1439  using ReturnType = const MultTrait_t< ResultType_t<VT1>, ResultType_t<VT2> >;
1440 
1442  BLAZE_CONSTRAINT_MUST_BE_ZERO_TYPE( ReturnType );
1443 
1444  return ReturnType( (~lhs).size(), (~rhs).size() );
1445 }
1447 //*************************************************************************************************
1448 
1449 
1450 //*************************************************************************************************
1479 template< typename VT1 // Type of the left-hand side sparse vector
1480  , typename VT2 > // Type of the right-hand side dense vector
1481 inline decltype(auto)
1482  operator*( const SparseVector<VT1,false>& lhs, const DenseVector<VT2,true>& rhs )
1483 {
1485 
1486  return svecdvecouter( ~lhs, ~rhs );
1487 }
1488 //*************************************************************************************************
1489 
1490 
1491 
1492 
1493 //=================================================================================================
1494 //
1495 // SIZE SPECIALIZATIONS
1496 //
1497 //=================================================================================================
1498 
1499 //*************************************************************************************************
1501 template< typename VT1, typename VT2 >
1502 struct Size< SVecDVecOuterExpr<VT1,VT2>, 0UL >
1503  : public Size<VT1,0UL>
1504 {};
1505 
1506 template< typename VT1, typename VT2 >
1507 struct Size< SVecDVecOuterExpr<VT1,VT2>, 1UL >
1508  : public Size<VT2,0UL>
1509 {};
1511 //*************************************************************************************************
1512 
1513 } // namespace blaze
1514 
1515 #endif
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SVecDVecOuterExpr.h:380
Pointer difference type of the Blaze library.
ValueType * PointerType
Pointer return type.
Definition: SVecDVecOuterExpr.h:222
Header file for auxiliary alias declarations.
CompositeType_t< VT2 > CT2
Composite type of the right-hand side dense vector expression.
Definition: SVecDVecOuterExpr.h:115
Element ValueType
Type of the underlying pointers.
Definition: SVecDVecOuterExpr.h:221
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.
SVecDVecOuterExpr(const VT1 &lhs, const VT2 &rhs) noexcept
Constructor for the SVecDVecOuterExpr class.
Definition: SVecDVecOuterExpr.h:351
typename If< Condition, T1, T2 >::Type If_t
Auxiliary alias template for the If class template.The If_t alias template provides a convenient shor...
Definition: If.h:109
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SVecDVecOuterExpr.h:533
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified column.
Definition: SVecDVecOuterExpr.h:449
RightOperand rhs_
Right-hand side dense vector of the multiplication expression.
Definition: SVecDVecOuterExpr.h:541
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.
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SVecDVecOuterExpr.h:428
ValueIndexPair< ElementType > Element
Element type of the sparse matrix expression.
Definition: SVecDVecOuterExpr.h:212
Header file for the IsSame and IsStrictlySame type traits.
std::forward_iterator_tag IteratorCategory
The iterator category.
Definition: SVecDVecOuterExpr.h:220
ConstIterator & operator++()
Pre-increment operator.
Definition: SVecDVecOuterExpr.h:248
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:595
IteratorType it_
Iterator over the elements of the left-hand side sparse vector expression.
Definition: SVecDVecOuterExpr.h:329
If_t< IsExpression_v< VT2 >, const VT2, const VT2 & > RightOperand
Composite type of the right-hand side dense vector expression.
Definition: SVecDVecOuterExpr.h:195
Constraint on the data type.
Header file for the MAYBE_UNUSED function template.
Header file for the Computation base class.
Header file for the reset shim.
System settings for performance optimizations.
typename T::ReturnType ReturnType_t
Alias declaration for nested ReturnType type definitions.The ReturnType_t alias declaration provides ...
Definition: Aliases.h:410
ET2 RightElement
Element type of the dense vector expression.
Definition: SVecDVecOuterExpr.h:218
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes....
Definition: DenseMatrix.h:81
RightElement v_
Element of the right-hand side dense vector expression.
Definition: SVecDVecOuterExpr.h:330
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes....
Definition: Forward.h:145
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
Header file for the SparseMatrix base class.
Constraint on the transpose flag of vector types.
Constraint on the data type.
ConstIterator find(size_t i, size_t j) const
Searches for a specific matrix element.
Definition: SVecDVecOuterExpr.h:462
If_t< IsComputation_v< VT1 >, const RT1, CT1 > LT
Type for the assignment of the left-hand side dense vector operand.
Definition: SVecDVecOuterExpr.h:198
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
If_t< useAssign, const ResultType, const SVecDVecOuterExpr & > CompositeType
Data type for composite expression templates.
Definition: SVecDVecOuterExpr.h:189
RightOperand rightOperand() const noexcept
Returns the right-hand side dense vector operand.
Definition: SVecDVecOuterExpr.h:509
Header file for the ValueIndexPair class.
Header file for the IsTemporary type trait class.
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: SVecDVecOuterExpr.h:337
Header file for the multiplication trait.
bool operator==(const ConstIterator &rhs) const
Equality comparison between two ConstIterator objects.
Definition: SVecDVecOuterExpr.h:300
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
static constexpr bool useAssign
Compilation switch for the evaluation strategy of the multiplication expression.
Definition: SVecDVecOuterExpr.h:141
#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
#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
ReturnType_t< VT1 > RN1
Return type of the left-hand side sparse vector expression.
Definition: SVecDVecOuterExpr.h:112
#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
Header file for all SIMD functionality.
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse vector operand.
Definition: SVecDVecOuterExpr.h:499
LeftOperand lhs_
Left-hand side sparse vector of the multiplication expression.
Definition: SVecDVecOuterExpr.h:540
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:76
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
#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
ConstIterator(IteratorType it, RightElement v)
Constructor for the ConstIterator class.
Definition: SVecDVecOuterExpr.h:237
const Element operator *() const
Direct access to the sparse matrix element at the current iterator position.
Definition: SVecDVecOuterExpr.h:259
ElementType_t< VT2 > ET2
Element type of the right-hand side dense vector expression.
Definition: SVecDVecOuterExpr.h:117
size_t index() const
Access to the current index of the sparse element.
Definition: SVecDVecOuterExpr.h:289
static constexpr size_t SIMDSIZE
The number of elements packed within a single SIMD element.
Definition: SVecDVecOuterExpr.h:342
Constraint on the data type.
Header file for the exception macros of the math module.
IteratorCategory iterator_category
The iterator category.
Definition: SVecDVecOuterExpr.h:227
DifferenceType operator-(const ConstIterator &rhs) const
Calculating the number of elements between two expression iterators.
Definition: SVecDVecOuterExpr.h:322
Constraint on the data type.
Constraint on the data type.
ReturnType_t< VT2 > RN2
Return type of the right-hand side dense vector expression.
Definition: SVecDVecOuterExpr.h:113
Header file for the VecTVecMultExpr base class.
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: SVecDVecOuterExpr.h:186
Iterator over the elements of the sparse vector-dense vector outer product expression.
Definition: SVecDVecOuterExpr.h:207
ElementType_t< VT1 > ET1
Element type of the left-hand side sparse vector expression.
Definition: SVecDVecOuterExpr.h:116
Header file for the EnableIf class template.
Header file for the IsPadded type trait.
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
ptrdiff_t DifferenceType
Difference between two iterators.
Definition: SVecDVecOuterExpr.h:224
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.
If_t< IsComputation_v< VT2 >, const RT2, CT2 > RT
Type for the assignment of the right-hand side dense vector operand.
Definition: SVecDVecOuterExpr.h:201
#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,...
Definition: Symmetric.h:79
Header file for the HasSIMDMult type trait.
Expression object for sparse vector-dense vector outer products.The SVecDVecOuterExpr class represent...
Definition: Forward.h:151
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.
If_t< IsExpression_v< VT1 >, const VT1, const VT1 & > LeftOperand
Composite type of the left-hand side sparse vector expression.
Definition: SVecDVecOuterExpr.h:192
const ConstIterator * operator->() const
Direct access to the sparse matrix element at the current iterator position.
Definition: SVecDVecOuterExpr.h:269
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.The CompositeType_t alias declaration pro...
Definition: Aliases.h:90
ConstIterator end(size_t i) const
Returns an iterator just past the last non-zero element of column i.
Definition: SVecDVecOuterExpr.h:408
ReturnType value() const
Access to the current value of the sparse element.
Definition: SVecDVecOuterExpr.h:279
ResultType_t< VT1 > RT1
Result type of the left-hand side sparse vector expression.
Definition: SVecDVecOuterExpr.h:110
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SVecDVecOuterExpr.h:521
Header file for the IsZero type trait.
bool operator!=(const ConstIterator &rhs) const
Inequality comparison between two ConstIterator objects.
Definition: SVecDVecOuterExpr.h:311
MultTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: SVecDVecOuterExpr.h:180
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SVecDVecOuterExpr.h:418
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
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SVecDVecOuterExpr.h:181
Header file for all forward declarations for expression class templates.
Header file for the isDefault shim.
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:75
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.
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: SVecDVecOuterExpr.h:127
Constraints on the storage order of matrix types.
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.
decltype(std::declval< RN1 >() *std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: SVecDVecOuterExpr.h:130
typename T::ConstIterator ConstIterator_t
Alias declaration for nested ConstIterator type definitions.The ConstIterator_t alias declaration pro...
Definition: Aliases.h:110
ResultType_t< VT2 > RT2
Result type of the right-hand side dense vector expression.
Definition: SVecDVecOuterExpr.h:111
#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
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: SVecDVecOuterExpr.h:183
ValueType & ReferenceType
Reference return type.
Definition: SVecDVecOuterExpr.h:223
Index-value-pair for sparse vectors and matrices.The ValueIndexPair class represents a single index-v...
Definition: ValueIndexPair.h:73
Header file for the IsRowMajorMatrix type trait.
Header file for the IsComputation type trait class.
ConstIterator begin(size_t i) const
Returns an iterator to the first non-zero element of column i.
Definition: SVecDVecOuterExpr.h:397
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:146
CompositeType_t< VT1 > CT1
Composite type of the left-hand side sparse vector expression.
Definition: SVecDVecOuterExpr.h:114
#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
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: SVecDVecOuterExpr.h:438
ConstIterator_t< RemoveReference_t< LeftOperand > > IteratorType
Iterator type of the sparse vector expression.
Definition: SVecDVecOuterExpr.h:215
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:635
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SVecDVecOuterExpr.h:182
ConstIterator upperBound(size_t i, size_t j) const
Returns an iterator to the first index greater then the given index.
Definition: SVecDVecOuterExpr.h:488
ConstIterator lowerBound(size_t i, size_t j) const
Returns an iterator to the first index not less then the given index.
Definition: SVecDVecOuterExpr.h:475
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,...
Definition: Assert.h:101
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SVecDVecOuterExpr.h:364
Constraint on the transpose flag of vector types.
Header file for the IsExpression type trait class.
Header file for the function trace functionality.