Blaze  3.6
DVecDVecOuterExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_DVECDVECOUTEREXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_DVECDVECOUTEREXPR_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/SIMD.h>
76 #include <blaze/system/Inline.h>
79 #include <blaze/util/Assert.h>
80 #include <blaze/util/EnableIf.h>
83 #include <blaze/util/mpl/If.h>
84 #include <blaze/util/Types.h>
86 
87 
88 namespace blaze {
89 
90 //=================================================================================================
91 //
92 // CLASS DVECDVECOUTEREXPR
93 //
94 //=================================================================================================
95 
96 //*************************************************************************************************
103 template< typename VT1 // Type of the left-hand side dense vector
104  , typename VT2 > // Type of the right-hand side dense vector
106  : public VecTVecMultExpr< DenseMatrix< DVecDVecOuterExpr<VT1,VT2>, false > >
107  , private Computation
108 {
109  private:
110  //**Type definitions****************************************************************************
119  //**********************************************************************************************
120 
121  //**********************************************************************************************
123  static constexpr bool evaluateLeft = ( IsComputation_v<VT1> || RequiresEvaluation_v<VT1> );
124  //**********************************************************************************************
125 
126  //**********************************************************************************************
128  static constexpr bool evaluateRight = ( IsComputation_v<VT2> || RequiresEvaluation_v<VT2> );
129  //**********************************************************************************************
130 
131  //**Return type evaluation**********************************************************************
133 
138  static constexpr bool returnExpr = ( !IsTemporary_v<RN1> && !IsTemporary_v<RN2> );
139 
141  using ExprReturnType = decltype( std::declval<RN1>() * std::declval<RN2>() );
142  //**********************************************************************************************
143 
144  //**Serial evaluation strategy******************************************************************
146 
152  static constexpr bool useAssign = ( evaluateLeft || evaluateRight );
153 
155  template< typename VT >
157  static constexpr bool UseAssign_v = useAssign;
159  //**********************************************************************************************
160 
161  //**Parallel evaluation strategy****************************************************************
163 
167  template< typename VT >
168  static constexpr bool UseSMPAssign_v = evaluateRight;
170  //**********************************************************************************************
171 
172  //**********************************************************************************************
174 
177  template< typename T1, typename T2, typename T3 >
178  static constexpr bool UseVectorizedKernel_v =
179  ( useOptimizedKernels &&
180  T1::simdEnabled && T2::simdEnabled && T3::simdEnabled &&
181  IsSIMDCombinable_v< ElementType_t<T1>
183  , ElementType_t<T3> > &&
184  HasSIMDMult_v< ElementType_t<T2>, ElementType_t<T3> > );
186  //**********************************************************************************************
187 
188  //**********************************************************************************************
190 
193  template< typename T1, typename T2, typename T3 >
194  static constexpr bool UseDefaultKernel_v = !UseVectorizedKernel_v<T1,T2,T3>;
196  //**********************************************************************************************
197 
198  public:
199  //**Type definitions****************************************************************************
207 
210 
213 
215  using LeftOperand = If_t< IsExpression_v<VT1>, const VT1, const VT1& >;
216 
218  using RightOperand = If_t< IsExpression_v<VT2>, const VT2, const VT2& >;
219 
222 
225  //**********************************************************************************************
226 
227  //**ConstIterator class definition**************************************************************
231  {
232  public:
233  //**Type definitions*************************************************************************
234  using IteratorCategory = std::random_access_iterator_tag;
239 
240  // STL iterator requirements
246 
249 
252  //*******************************************************************************************
253 
254  //**Constructor******************************************************************************
260  explicit inline ConstIterator( LeftIteratorType left, RightIteratorType right )
261  : left_ ( left ) // Iterator to the current left-hand side element
262  , right_( right ) // Iterator to the current right-hand side element
263  {}
264  //*******************************************************************************************
265 
266  //**Addition assignment operator*************************************************************
273  right_ += inc;
274  return *this;
275  }
276  //*******************************************************************************************
277 
278  //**Subtraction assignment operator**********************************************************
285  right_ -= dec;
286  return *this;
287  }
288  //*******************************************************************************************
289 
290  //**Prefix increment operator****************************************************************
296  ++right_;
297  return *this;
298  }
299  //*******************************************************************************************
300 
301  //**Postfix increment operator***************************************************************
307  return ConstIterator( left_, right_++ );
308  }
309  //*******************************************************************************************
310 
311  //**Prefix decrement operator****************************************************************
317  --right_;
318  return *this;
319  }
320  //*******************************************************************************************
321 
322  //**Postfix decrement operator***************************************************************
328  return ConstIterator( left_, right_-- );
329  }
330  //*******************************************************************************************
331 
332  //**Element access operator******************************************************************
337  inline ReturnType operator*() const {
338  return (*left_) * (*right_);
339  }
340  //*******************************************************************************************
341 
342  //**Load function****************************************************************************
347  inline auto load() const noexcept {
348  return set( *left_ ) * right_.load();
349  }
350  //*******************************************************************************************
351 
352  //**Equality operator************************************************************************
358  inline bool operator==( const ConstIterator& rhs ) const {
359  return right_ == rhs.right_;
360  }
361  //*******************************************************************************************
362 
363  //**Inequality operator**********************************************************************
369  inline bool operator!=( const ConstIterator& rhs ) const {
370  return right_ != rhs.right_;
371  }
372  //*******************************************************************************************
373 
374  //**Less-than operator***********************************************************************
380  inline bool operator<( const ConstIterator& rhs ) const {
381  return right_ < rhs.right_;
382  }
383  //*******************************************************************************************
384 
385  //**Greater-than operator********************************************************************
391  inline bool operator>( const ConstIterator& rhs ) const {
392  return right_ > rhs.right_;
393  }
394  //*******************************************************************************************
395 
396  //**Less-or-equal-than operator**************************************************************
402  inline bool operator<=( const ConstIterator& rhs ) const {
403  return right_ <= rhs.right_;
404  }
405  //*******************************************************************************************
406 
407  //**Greater-or-equal-than operator***********************************************************
413  inline bool operator>=( const ConstIterator& rhs ) const {
414  return right_ >= rhs.right_;
415  }
416  //*******************************************************************************************
417 
418  //**Subtraction operator*********************************************************************
424  inline DifferenceType operator-( const ConstIterator& rhs ) const {
425  return right_ - rhs.right_;
426  }
427  //*******************************************************************************************
428 
429  //**Addition operator************************************************************************
436  friend inline const ConstIterator operator+( const ConstIterator& it, size_t inc ) {
437  return ConstIterator( it.left_, it.right_ + inc );
438  }
439  //*******************************************************************************************
440 
441  //**Addition operator************************************************************************
448  friend inline const ConstIterator operator+( size_t inc, const ConstIterator& it ) {
449  return ConstIterator( it.left_, it.right_ + inc );
450  }
451  //*******************************************************************************************
452 
453  //**Subtraction operator*********************************************************************
460  friend inline const ConstIterator operator-( const ConstIterator& it, size_t dec ) {
461  return ConstIterator( it.left_, it.right_ - dec );
462  }
463  //*******************************************************************************************
464 
465  private:
466  //**Member variables*************************************************************************
469  //*******************************************************************************************
470  };
471  //**********************************************************************************************
472 
473  //**Compilation flags***************************************************************************
475  static constexpr bool simdEnabled =
476  ( VT1::simdEnabled && VT2::simdEnabled && HasSIMDMult_v<ET1,ET2> );
477 
479  static constexpr bool smpAssignable = ( VT1::smpAssignable && !evaluateRight );
480  //**********************************************************************************************
481 
482  //**SIMD properties*****************************************************************************
484  static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
485  //**********************************************************************************************
486 
487  //**Constructor*********************************************************************************
493  explicit inline DVecDVecOuterExpr( const VT1& lhs, const VT2& rhs ) noexcept
494  : lhs_( lhs ) // Left-hand side dense vector of the multiplication expression
495  , rhs_( rhs ) // Right-hand side dense vector of the multiplication expression
496  {}
497  //**********************************************************************************************
498 
499  //**Access operator*****************************************************************************
506  inline ReturnType operator()( size_t i, size_t j ) const {
507  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
508  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
509 
510  return lhs_[i] * rhs_[j];
511  }
512  //**********************************************************************************************
513 
514  //**At function*********************************************************************************
522  inline ReturnType at( size_t i, size_t j ) const {
523  if( i >= lhs_.size() ) {
524  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
525  }
526  if( j >= rhs_.size() ) {
527  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
528  }
529  return (*this)(i,j);
530  }
531  //**********************************************************************************************
532 
533  //**Load function*******************************************************************************
540  BLAZE_ALWAYS_INLINE auto load( size_t i, size_t j ) const noexcept {
541  BLAZE_INTERNAL_ASSERT( i < lhs_.size() , "Invalid row access index" );
542  BLAZE_INTERNAL_ASSERT( j < rhs_.size() , "Invalid column access index" );
543  BLAZE_INTERNAL_ASSERT( j % SIMDSIZE == 0UL, "Invalid column access index" );
544  return set( lhs_[i] ) * rhs_.load( j );
545  }
546  //**********************************************************************************************
547 
548  //**Begin function******************************************************************************
554  inline ConstIterator begin( size_t i ) const {
555  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
556  return ConstIterator( lhs_.begin()+i, rhs_.begin() );
557  }
558  //**********************************************************************************************
559 
560  //**End function********************************************************************************
566  inline ConstIterator end( size_t i ) const {
567  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
568  return ConstIterator( lhs_.begin()+i, rhs_.end() );
569  }
570  //**********************************************************************************************
571 
572  //**Rows function*******************************************************************************
577  inline size_t rows() const noexcept {
578  return lhs_.size();
579  }
580  //**********************************************************************************************
581 
582  //**Columns function****************************************************************************
587  inline size_t columns() const noexcept {
588  return rhs_.size();
589  }
590  //**********************************************************************************************
591 
592  //**Left operand access*************************************************************************
597  inline LeftOperand leftOperand() const noexcept {
598  return lhs_;
599  }
600  //**********************************************************************************************
601 
602  //**Right operand access************************************************************************
607  inline RightOperand rightOperand() const noexcept {
608  return rhs_;
609  }
610  //**********************************************************************************************
611 
612  //**********************************************************************************************
618  template< typename T >
619  inline bool canAlias( const T* alias ) const noexcept {
620  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
621  }
622  //**********************************************************************************************
623 
624  //**********************************************************************************************
630  template< typename T >
631  inline bool isAliased( const T* alias ) const noexcept {
632  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
633  }
634  //**********************************************************************************************
635 
636  //**********************************************************************************************
641  inline bool isAligned() const noexcept {
642  return lhs_.isAligned() && rhs_.isAligned();
643  }
644  //**********************************************************************************************
645 
646  //**********************************************************************************************
651  inline bool canSMPAssign() const noexcept {
652  return ( rows() * columns() >= SMP_DVECDVECOUTER_THRESHOLD );
653  }
654  //**********************************************************************************************
655 
656  private:
657  //**Member variables****************************************************************************
660  //**********************************************************************************************
661 
662  //**Assignment to row-major dense matrices******************************************************
676  template< typename MT > // Type of the target dense matrix
677  friend inline auto assign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
679  {
681 
682  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
683  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
684 
685  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
686  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
687 
688  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
689  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
690  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
691  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
692 
693  DVecDVecOuterExpr::selectAssignKernel( ~lhs, x, y );
694  }
696  //**********************************************************************************************
697 
698  //**Default assignment to row-major dense matrices**********************************************
712  template< typename MT // Type of the left-hand side target matrix
713  , typename VT3 // Type of the left-hand side vector operand
714  , typename VT4 > // Type of the right-hand side vector operand
715  static inline auto selectAssignKernel( MT& A, const VT3& x, const VT4& y )
716  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
717  {
718  const size_t M( A.rows() );
719  const size_t N( A.columns() );
720 
721  const size_t jpos( N & size_t(-2) );
722  BLAZE_INTERNAL_ASSERT( ( N - ( N % 2UL ) ) == jpos, "Invalid end calculation" );
723 
724  for( size_t i=0UL; i<M; ++i ) {
725  for( size_t j=0UL; j<jpos; j+=2UL ) {
726  A(i,j ) = x[i] * y[j ];
727  A(i,j+1UL) = x[i] * y[j+1];
728  }
729  if( jpos < N ) {
730  A(i,jpos) = x[i] * y[jpos];
731  }
732  }
733  }
735  //**********************************************************************************************
736 
737  //**Vectorized assignment to row-major dense matrices*******************************************
751  template< typename MT // Type of the left-hand side target matrix
752  , typename VT3 // Type of the left-hand side vector operand
753  , typename VT4 > // Type of the right-hand side vector operand
754  static inline auto selectAssignKernel( MT& A, const VT3& x, const VT4& y )
755  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
756  {
757  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT4> );
758 
759  const size_t M( A.rows() );
760  const size_t N( A.columns() );
761 
762  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
763  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
764 
765  for( size_t i=0UL; i<M; ++i )
766  {
767  const SIMDType x1( set( x[i] ) );
768 
769  size_t j( 0UL );
770 
771  for( ; j<jpos; j+=SIMDSIZE ) {
772  A.store( i, j, x1 * y.load(j) );
773  }
774  for( ; remainder && j<N; ++j ) {
775  A(i,j) = x[i] * y[j];
776  }
777  }
778  }
780  //**********************************************************************************************
781 
782  //**Assignment to column-major dense matrices***************************************************
794  template< typename MT > // Type of the target dense matrix
795  friend inline void assign( DenseMatrix<MT,true>& lhs, const DVecDVecOuterExpr& rhs )
796  {
798 
800 
801  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
802  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
803 
804  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
805  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
806 
807  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
808  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
809  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
810  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
811 
812  DVecDVecOuterExpr::selectAssignKernel( ~lhs, x, y );
813  }
815  //**********************************************************************************************
816 
817  //**Default assignment to column-major dense matrices*******************************************
831  template< typename MT // Type of the left-hand side target matrix
832  , typename VT3 // Type of the left-hand side vector operand
833  , typename VT4 > // Type of the right-hand side vector operand
834  static inline auto selectAssignKernel( MT& A, const VT3& x, const VT4& y )
835  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
836  {
837  const size_t M( A.rows() );
838  const size_t N( A.columns() );
839 
840  const size_t ipos( M & size_t(-2) );
841  BLAZE_INTERNAL_ASSERT( ( M - ( M % 2UL ) ) == ipos, "Invalid end calculation" );
842 
843  for( size_t j=0UL; j<N; ++j ) {
844  for( size_t i=0UL; i<ipos; i+=2UL ) {
845  A(i ,j) = x[i ] * y[j];
846  A(i+1UL,j) = x[i+1] * y[j];
847  }
848  if( ipos < M ) {
849  A(ipos,j) = x[ipos] * y[j];
850  }
851  }
852  }
854  //**********************************************************************************************
855 
856  //**Vectorized assignment to column-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 selectAssignKernel( MT& A, const VT3& x, const VT4& y )
874  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
875  {
876  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT3> );
877 
878  const size_t M( A.rows() );
879  const size_t N( A.columns() );
880 
881  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
882  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
883 
884  for( size_t j=0UL; j<N; ++j )
885  {
886  const SIMDType y1( set( y[j] ) );
887 
888  size_t i( 0UL );
889 
890  for( ; i<ipos; i+=SIMDSIZE ) {
891  A.store( i, j, x.load(i) * y1 );
892  }
893  for( ; remainder && i<M; ++i ) {
894  A(i,j) = x[i] * y[j];
895  }
896  }
897  }
899  //**********************************************************************************************
900 
901  //**Assignment to sparse matrices***************************************************************
913  template< typename MT // Type of the target sparse matrix
914  , bool SO > // Storage order of the target sparse matrix
915  friend inline void assign( SparseMatrix<MT,SO>& lhs, const DVecDVecOuterExpr& rhs )
916  {
918 
919  using TmpType = If_t< SO, OppositeType, ResultType >;
920 
927 
928  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
929  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
930 
931  const TmpType tmp( serial( rhs ) );
932  assign( ~lhs, tmp );
933  }
935  //**********************************************************************************************
936 
937  //**Addition assignment to row-major dense matrices*********************************************
952  template< typename MT > // Type of the target dense matrix
953  friend inline auto addAssign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
954  -> EnableIf_t< UseAssign_v<MT> >
955  {
957 
958  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
959  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
960 
961  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
962  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
963 
964  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
965  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
966  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
967  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
968 
969  DVecDVecOuterExpr::selectAddAssignKernel( ~lhs, x, y );
970  }
972  //**********************************************************************************************
973 
974  //**Default addition assignment to row-major dense matrices*************************************
988  template< typename MT // Type of the left-hand side target matrix
989  , typename VT3 // Type of the left-hand side vector operand
990  , typename VT4 > // Type of the right-hand side vector operand
991  static inline auto selectAddAssignKernel( MT& A, const VT3& x, const VT4& y )
992  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
993  {
994  const size_t M( A.rows() );
995  const size_t N( A.columns() );
996 
997  const size_t jpos( N & size_t(-2) );
998  BLAZE_INTERNAL_ASSERT( ( N - ( N % 2UL ) ) == jpos, "Invalid end calculation" );
999 
1000  for( size_t i=0UL; i<M; ++i ) {
1001  for( size_t j=0UL; j<jpos; j+=2UL ) {
1002  A(i,j ) += x[i] * y[j ];
1003  A(i,j+1UL) += x[i] * y[j+1UL];
1004  }
1005  if( jpos < N ) {
1006  A(i,jpos) += x[i] * y[jpos];
1007  }
1008  }
1009  }
1011  //**********************************************************************************************
1012 
1013  //**Vectorized addition assignment to row-major dense matrices**********************************
1027  template< typename MT // Type of the left-hand side target matrix
1028  , typename VT3 // Type of the left-hand side vector operand
1029  , typename VT4 > // Type of the right-hand side vector operand
1030  static inline auto selectAddAssignKernel( MT& A, const VT3& x, const VT4& y )
1031  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
1032  {
1033  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT4> );
1034 
1035  const size_t M( A.rows() );
1036  const size_t N( A.columns() );
1037 
1038  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
1039  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
1040 
1041  for( size_t i=0UL; i<M; ++i )
1042  {
1043  const SIMDType x1( set( x[i] ) );
1044 
1045  size_t j( 0UL );
1046 
1047  for( ; j<jpos; j+=SIMDSIZE ) {
1048  A.store( i, j, A.load(i,j) + x1 * y.load(j) );
1049  }
1050  for( ; remainder && j<N; ++j ) {
1051  A(i,j) += x[i] * y[j];
1052  }
1053  }
1054  }
1056  //**********************************************************************************************
1057 
1058  //**Addition assignment to column-major dense matrices******************************************
1071  template< typename MT > // Type of the target dense matrix
1072  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const DVecDVecOuterExpr& rhs )
1073  {
1075 
1077 
1078  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1079  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1080 
1081  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1082  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1083 
1084  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1085  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1086  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1087  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1088 
1089  DVecDVecOuterExpr::selectAddAssignKernel( ~lhs, x, y );
1090  }
1092  //**********************************************************************************************
1093 
1094  //**Default addition assignment to column dense matrices****************************************
1108  template< typename MT // Type of the left-hand side target matrix
1109  , typename VT3 // Type of the left-hand side vector operand
1110  , typename VT4 > // Type of the right-hand side vector operand
1111  static inline auto selectAddAssignKernel( MT& A, const VT3& x, const VT4& y )
1112  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
1113  {
1114  const size_t M( A.rows() );
1115  const size_t N( A.columns() );
1116 
1117  const size_t ipos( M & size_t(-2) );
1118  BLAZE_INTERNAL_ASSERT( ( M - ( M % 2UL ) ) == ipos, "Invalid end calculation" );
1119 
1120  for( size_t j=0UL; j<N; ++j ) {
1121  for( size_t i=0UL; i<ipos; i+=2UL ) {
1122  A(i ,j) += x[i ] * y[j];
1123  A(i+1UL,j) += x[i+1UL] * y[j];
1124  }
1125  if( ipos < M ) {
1126  A(ipos,j) += x[ipos] * y[j];
1127  }
1128  }
1129  }
1131  //**********************************************************************************************
1132 
1133  //**Vectorized addition assignment to column-major dense matrices*******************************
1147  template< typename MT // Type of the left-hand side target matrix
1148  , typename VT3 // Type of the left-hand side vector operand
1149  , typename VT4 > // Type of the right-hand side vector operand
1150  static inline auto selectAddAssignKernel( MT& A, const VT3& x, const VT4& y )
1151  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
1152  {
1153  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT3> );
1154 
1155  const size_t M( A.rows() );
1156  const size_t N( A.columns() );
1157 
1158  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
1159  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
1160 
1161  for( size_t j=0UL; j<N; ++j )
1162  {
1163  const SIMDType y1( set( y[j] ) );
1164 
1165  size_t i( 0UL );
1166 
1167  for( ; i<ipos; i+=SIMDSIZE ) {
1168  A.store( i, j, A.load(i,j) + x.load(i) * y1 );
1169  }
1170  for( ; remainder && i<M; ++i ) {
1171  A(i,j) += x[i] * y[j];
1172  }
1173  }
1174  }
1176  //**********************************************************************************************
1177 
1178  //**Addition assignment to sparse matrices******************************************************
1179  // No special implementation for the addition assignment to sparse matrices.
1180  //**********************************************************************************************
1181 
1182  //**Subtraction assignment to row-major dense matrices******************************************
1197  template< typename MT > // Type of the target dense matrix
1198  friend inline auto subAssign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
1199  -> EnableIf_t< UseAssign_v<MT> >
1200  {
1202 
1203  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1204  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1205 
1206  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1207  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1208 
1209  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1210  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1211  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1212  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1213 
1214  DVecDVecOuterExpr::selectSubAssignKernel( ~lhs, x, y );
1215  }
1217  //**********************************************************************************************
1218 
1219  //**Default subtraction assignment to row-major dense matrices**********************************
1233  template< typename MT // Type of the left-hand side target matrix
1234  , typename VT3 // Type of the left-hand side vector operand
1235  , typename VT4 > // Type of the right-hand side vector operand
1236  static inline auto selectSubAssignKernel( MT& A, const VT3& x, const VT4& y )
1237  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
1238  {
1239  const size_t M( A.rows() );
1240  const size_t N( A.columns() );
1241 
1242  const size_t jpos( N & size_t(-2) );
1243  BLAZE_INTERNAL_ASSERT( ( N - ( N % 2UL ) ) == jpos, "Invalid end calculation" );
1244 
1245  for( size_t i=0UL; i<M; ++i ) {
1246  for( size_t j=0UL; j<jpos; j+=2UL ) {
1247  A(i,j ) -= x[i] * y[j ];
1248  A(i,j+1UL) -= x[i] * y[j+1UL];
1249  }
1250  if( jpos < N ) {
1251  A(i,jpos) -= x[i] * y[jpos];
1252  }
1253  }
1254  }
1256  //**********************************************************************************************
1257 
1258  //**Vectorized subtraction assignment to row-major dense matrices*******************************
1272  template< typename MT // Type of the left-hand side target matrix
1273  , typename VT3 // Type of the left-hand side vector operand
1274  , typename VT4 > // Type of the right-hand side vector operand
1275  static inline auto selectSubAssignKernel( MT& A, const VT3& x, const VT4& y )
1276  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
1277  {
1278  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT4> );
1279 
1280  const size_t M( A.rows() );
1281  const size_t N( A.columns() );
1282 
1283  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
1284  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
1285 
1286  for( size_t i=0UL; i<M; ++i )
1287  {
1288  const SIMDType x1( set( x[i] ) );
1289 
1290  size_t j( 0UL );
1291 
1292  for( ; j<jpos; j+=SIMDSIZE ) {
1293  A.store( i, j, A.load(i,j) - x1 * y.load(j) );
1294  }
1295  for( ; remainder && j<N; ++j ) {
1296  A(i,j) -= x[i] * y[j];
1297  }
1298  }
1299  }
1301  //**********************************************************************************************
1302 
1303  //**Subtraction assignment to column-major dense matrices***************************************
1316  template< typename MT > // Type of the target dense matrix
1317  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const DVecDVecOuterExpr& rhs )
1318  {
1320 
1322 
1323  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1324  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1325 
1326  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1327  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1328 
1329  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1330  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1331  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1332  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1333 
1334  DVecDVecOuterExpr::selectSubAssignKernel( ~lhs, x, y );
1335  }
1337  //**********************************************************************************************
1338 
1339  //**Default subtraction assignment to column dense matrices*************************************
1353  template< typename MT // Type of the left-hand side target matrix
1354  , typename VT3 // Type of the left-hand side vector operand
1355  , typename VT4 > // Type of the right-hand side vector operand
1356  static inline auto selectSubAssignKernel( MT& A, const VT3& x, const VT4& y )
1357  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
1358  {
1359  const size_t M( A.rows() );
1360  const size_t N( A.columns() );
1361 
1362  const size_t ipos( M & size_t(-2) );
1363  BLAZE_INTERNAL_ASSERT( ( M - ( M % 2UL ) ) == ipos, "Invalid end calculation" );
1364 
1365  for( size_t j=0UL; j<N; ++j ) {
1366  for( size_t i=0UL; i<ipos; i+=2UL ) {
1367  A(i ,j) -= x[i ] * y[j];
1368  A(i+1UL,j) -= x[i+1UL] * y[j];
1369  }
1370  if( ipos < M ) {
1371  A(ipos,j) -= x[ipos] * y[j];
1372  }
1373  }
1374  }
1376  //**********************************************************************************************
1377 
1378  //**Vectorized subtraction assignment to column-major dense matrices****************************
1392  template< typename MT // Type of the left-hand side target matrix
1393  , typename VT3 // Type of the left-hand side vector operand
1394  , typename VT4 > // Type of the right-hand side vector operand
1395  static inline auto selectSubAssignKernel( MT& A, const VT3& x, const VT4& y )
1396  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
1397  {
1398  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT3> );
1399 
1400  const size_t M( A.rows() );
1401  const size_t N( A.columns() );
1402 
1403  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
1404  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
1405 
1406  for( size_t j=0UL; j<N; ++j )
1407  {
1408  const SIMDType y1( set( y[j] ) );
1409 
1410  size_t i( 0UL );
1411 
1412  for( ; i<ipos; i+=SIMDSIZE ) {
1413  A.store( i, j, A.load(i,j) - x.load(i) * y1 );
1414  }
1415  for( ; remainder && i<M; ++i ) {
1416  A(i,j) -= x[i] * y[j];
1417  }
1418  }
1419  }
1421  //**********************************************************************************************
1422 
1423  //**Subtraction assignment to sparse matrices***************************************************
1424  // No special implementation for the subtraction assignment to sparse matrices.
1425  //**********************************************************************************************
1426 
1427  //**Schur product assignment to row-major dense matrices****************************************
1442  template< typename MT > // Type of the target dense matrix
1443  friend inline auto schurAssign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
1444  -> EnableIf_t< UseAssign_v<MT> >
1445  {
1447 
1448  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1449  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1450 
1451  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1452  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1453 
1454  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1455  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1456  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1457  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1458 
1459  DVecDVecOuterExpr::selectSchurAssignKernel( ~lhs, x, y );
1460  }
1462  //**********************************************************************************************
1463 
1464  //**Default Schur product assignment to row-major dense matrices********************************
1478  template< typename MT // Type of the left-hand side target matrix
1479  , typename VT3 // Type of the left-hand side vector operand
1480  , typename VT4 > // Type of the right-hand side vector operand
1481  static inline auto selectSchurAssignKernel( MT& A, const VT3& x, const VT4& y )
1482  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
1483  {
1484  const size_t M( A.rows() );
1485  const size_t N( A.columns() );
1486 
1487  const size_t jpos( N & size_t(-2) );
1488  BLAZE_INTERNAL_ASSERT( ( N - ( N % 2UL ) ) == jpos, "Invalid end calculation" );
1489 
1490  for( size_t i=0UL; i<M; ++i ) {
1491  for( size_t j=0UL; j<jpos; j+=2UL ) {
1492  A(i,j ) *= x[i] * y[j ];
1493  A(i,j+1UL) *= x[i] * y[j+1UL];
1494  }
1495  if( jpos < N ) {
1496  A(i,jpos) *= x[i] * y[jpos];
1497  }
1498  }
1499  }
1501  //**********************************************************************************************
1502 
1503  //**Vectorized Schur product assignment to row-major dense matrices*****************************
1517  template< typename MT // Type of the left-hand side target matrix
1518  , typename VT3 // Type of the left-hand side vector operand
1519  , typename VT4 > // Type of the right-hand side vector operand
1520  static inline auto selectSchurAssignKernel( MT& A, const VT3& x, const VT4& y )
1521  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
1522  {
1523  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT4> );
1524 
1525  const size_t M( A.rows() );
1526  const size_t N( A.columns() );
1527 
1528  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
1529  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
1530 
1531  for( size_t i=0UL; i<M; ++i )
1532  {
1533  const SIMDType x1( set( x[i] ) );
1534 
1535  size_t j( 0UL );
1536 
1537  for( ; j<jpos; j+=SIMDSIZE ) {
1538  A.store( i, j, A.load(i,j) * ( x1 * y.load(j) ) );
1539  }
1540  for( ; remainder && j<N; ++j ) {
1541  A(i,j) *= x[i] * y[j];
1542  }
1543  }
1544  }
1546  //**********************************************************************************************
1547 
1548  //**Schur product assignment to column-major dense matrices*************************************
1561  template< typename MT > // Type of the target dense matrix
1562  friend inline void schurAssign( DenseMatrix<MT,true>& lhs, const DVecDVecOuterExpr& rhs )
1563  {
1565 
1567 
1568  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1569  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1570 
1571  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1572  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1573 
1574  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1575  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1576  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1577  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1578 
1579  DVecDVecOuterExpr::selectSchurAssignKernel( ~lhs, x, y );
1580  }
1582  //**********************************************************************************************
1583 
1584  //**Default Schur product assignment to column dense matrices***********************************
1598  template< typename MT // Type of the left-hand side target matrix
1599  , typename VT3 // Type of the left-hand side vector operand
1600  , typename VT4 > // Type of the right-hand side vector operand
1601  static inline auto selectSchurAssignKernel( MT& A, const VT3& x, const VT4& y )
1602  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
1603  {
1604  const size_t M( A.rows() );
1605  const size_t N( A.columns() );
1606 
1607  const size_t ipos( M & size_t(-2) );
1608  BLAZE_INTERNAL_ASSERT( ( M - ( M % 2UL ) ) == ipos, "Invalid end calculation" );
1609 
1610  for( size_t j=0UL; j<N; ++j ) {
1611  for( size_t i=0UL; i<ipos; i+=2UL ) {
1612  A(i ,j) *= x[i ] * y[j];
1613  A(i+1UL,j) *= x[i+1UL] * y[j];
1614  }
1615  if( ipos < M ) {
1616  A(ipos,j) *= x[ipos] * y[j];
1617  }
1618  }
1619  }
1621  //**********************************************************************************************
1622 
1623  //**Vectorized Schur product assignment to column-major dense matrices**************************
1637  template< typename MT // Type of the left-hand side target matrix
1638  , typename VT3 // Type of the left-hand side vector operand
1639  , typename VT4 > // Type of the right-hand side vector operand
1640  static inline auto selectSchurAssignKernel( MT& A, const VT3& x, const VT4& y )
1641  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
1642  {
1643  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT3> );
1644 
1645  const size_t M( A.rows() );
1646  const size_t N( A.columns() );
1647 
1648  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
1649  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
1650 
1651  for( size_t j=0UL; j<N; ++j )
1652  {
1653  const SIMDType y1( set( y[j] ) );
1654 
1655  size_t i( 0UL );
1656 
1657  for( ; i<ipos; i+=SIMDSIZE ) {
1658  A.store( i, j, A.load(i,j) * ( x.load(i) * y1 ) );
1659  }
1660  for( ; remainder && i<M; ++i ) {
1661  A(i,j) *= x[i] * y[j];
1662  }
1663  }
1664  }
1666  //**********************************************************************************************
1667 
1668  //**Schur product assignment to sparse matrices*************************************************
1669  // No special implementation for the Schur product assignment to sparse matrices.
1670  //**********************************************************************************************
1671 
1672  //**Multiplication assignment to dense matrices*************************************************
1673  // No special implementation for the multiplication assignment to dense matrices.
1674  //**********************************************************************************************
1675 
1676  //**Multiplication assignment to sparse matrices************************************************
1677  // No special implementation for the multiplication assignment to sparse matrices.
1678  //**********************************************************************************************
1679 
1680  //**SMP assignment to dense matrices************************************************************
1694  template< typename MT // Type of the target dense matrix
1695  , bool SO > // Storage order of the target dense matrix
1696  friend inline auto smpAssign( DenseMatrix<MT,SO>& lhs, const DVecDVecOuterExpr& rhs )
1697  -> EnableIf_t< UseSMPAssign_v<MT> >
1698  {
1700 
1701  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1702  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1703 
1704  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
1705  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
1706 
1707  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1708  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1709  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1710  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1711 
1712  smpAssign( ~lhs, x * y );
1713  }
1715  //**********************************************************************************************
1716 
1717  //**SMP assignment to sparse matrices***********************************************************
1731  template< typename MT // Type of the target sparse matrix
1732  , bool SO > // Storage order of the target sparse matrix
1733  friend inline auto smpAssign( SparseMatrix<MT,SO>& lhs, const DVecDVecOuterExpr& rhs )
1734  -> EnableIf_t< UseSMPAssign_v<MT> >
1735  {
1737 
1738  using TmpType = If_t< SO, OppositeType, ResultType >;
1739 
1746 
1747  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1748  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1749 
1750  const TmpType tmp( rhs );
1751  smpAssign( ~lhs, tmp );
1752  }
1754  //**********************************************************************************************
1755 
1756  //**SMP addition assignment to dense matrices***************************************************
1770  template< typename MT > // Type of the target dense matrix
1771  friend inline auto smpAddAssign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
1772  -> EnableIf_t< UseSMPAssign_v<MT> >
1773  {
1775 
1776  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1777  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1778 
1779  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
1780  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
1781 
1782  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1783  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1784  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1785  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1786 
1787  smpAddAssign( ~lhs, x * y );
1788  }
1790  //**********************************************************************************************
1791 
1792  //**SMP addition assignment to sparse matrices**************************************************
1793  // No special implementation for the SMP addition assignment to sparse matrices.
1794  //**********************************************************************************************
1795 
1796  //**SMP subtraction assignment to dense matrices************************************************
1811  template< typename MT > // Type of the target dense matrix
1812  friend inline auto smpSubAssign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
1813  -> EnableIf_t< UseSMPAssign_v<MT> >
1814  {
1816 
1817  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1818  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1819 
1820  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
1821  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
1822 
1823  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1824  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1825  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1826  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1827 
1828  smpSubAssign( ~lhs, x * y );
1829  }
1831  //**********************************************************************************************
1832 
1833  //**SMP subtraction assignment to sparse matrices***********************************************
1834  // No special implementation for the SMP subtraction assignment to sparse matrices.
1835  //**********************************************************************************************
1836 
1837  //**SMP Schur product assignment to dense matrices**********************************************
1852  template< typename MT > // Type of the target dense matrix
1853  friend inline auto smpSchurAssign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
1854  -> EnableIf_t< UseSMPAssign_v<MT> >
1855  {
1857 
1858  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1859  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1860 
1861  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
1862  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
1863 
1864  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1865  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1866  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1867  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1868 
1869  smpSchurAssign( ~lhs, x * y );
1870  }
1872  //**********************************************************************************************
1873 
1874  //**SMP Schur product assignment to sparse matrices*********************************************
1875  // No special implementation for the SMP Schur product assignment to sparse matrices.
1876  //**********************************************************************************************
1877 
1878  //**SMP multiplication assignment to dense matrices*********************************************
1879  // No special implementation for the SMP multiplication assignment to dense matrices.
1880  //**********************************************************************************************
1881 
1882  //**SMP multiplication assignment to sparse matrices********************************************
1883  // No special implementation for the SMP multiplication assignment to sparse matrices.
1884  //**********************************************************************************************
1885 
1886  //**Compile time checks*************************************************************************
1894  //**********************************************************************************************
1895 };
1896 //*************************************************************************************************
1897 
1898 
1899 
1900 
1901 //=================================================================================================
1902 //
1903 // GLOBAL BINARY ARITHMETIC OPERATORS
1904 //
1905 //=================================================================================================
1906 
1907 //*************************************************************************************************
1934 template< typename VT1 // Type of the left-hand side dense vector
1935  , typename VT2 > // Type of the right-hand side dense vector
1936 inline decltype(auto)
1937  operator*( const DenseVector<VT1,false>& lhs, const DenseVector<VT2,true>& rhs )
1938 {
1940 
1941  using ReturnType = const DVecDVecOuterExpr<VT1,VT2>;
1942  return ReturnType( ~lhs, ~rhs );
1943 }
1944 //*************************************************************************************************
1945 
1946 
1947 
1948 
1949 //=================================================================================================
1950 //
1951 // SIZE SPECIALIZATIONS
1952 //
1953 //=================================================================================================
1954 
1955 //*************************************************************************************************
1957 template< typename VT1, typename VT2 >
1958 struct Size< DVecDVecOuterExpr<VT1,VT2>, 0UL >
1959  : public Size<VT1,0UL>
1960 {};
1961 
1962 template< typename VT1, typename VT2 >
1963 struct Size< DVecDVecOuterExpr<VT1,VT2>, 1UL >
1964  : public Size<VT2,0UL>
1965 {};
1967 //*************************************************************************************************
1968 
1969 
1970 
1971 
1972 //=================================================================================================
1973 //
1974 // ISALIGNED SPECIALIZATIONS
1975 //
1976 //=================================================================================================
1977 
1978 //*************************************************************************************************
1980 template< typename VT1, typename VT2 >
1981 struct IsAligned< DVecDVecOuterExpr<VT1,VT2> >
1982  : public BoolConstant< IsAligned_v<VT1> && IsAligned_v<VT2> >
1983 {};
1985 //*************************************************************************************************
1986 
1987 
1988 
1989 
1990 //=================================================================================================
1991 //
1992 // ISPADDED SPECIALIZATIONS
1993 //
1994 //=================================================================================================
1995 
1996 //*************************************************************************************************
1998 template< typename VT1, typename VT2 >
1999 struct IsPadded< DVecDVecOuterExpr<VT1,VT2> >
2000  : public IsPadded<VT2>
2001 {};
2003 //*************************************************************************************************
2004 
2005 } // namespace blaze
2006 
2007 #endif
Pointer difference type of the Blaze library.
Header file for auxiliary alias declarations.
static constexpr bool evaluateLeft
Compilation switch for the composite type of the left-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:123
Header file for basic type definitions.
bool operator!=(const ConstIterator &rhs) const
Inequality comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:369
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
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: DVecDVecOuterExpr.h:577
ConstIterator_t< VT1 > LeftIteratorType
ConstIterator type of the left-hand side dense matrix expression.
Definition: DVecDVecOuterExpr.h:248
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.
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type,...
Definition: DenseMatrix.h:61
ElementType * PointerType
Pointer return type.
Definition: DVecDVecOuterExpr.h:236
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: DVecDVecOuterExpr.h:506
Header file for the IsColumnMajorMatrix type trait.
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: DVecDVecOuterExpr.h:138
friend const ConstIterator operator+(size_t inc, const ConstIterator &it)
Addition between an integral value and a ConstIterator.
Definition: DVecDVecOuterExpr.h:448
typename SIMDTrait< T >::Type SIMDTrait_t
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_t alias declaration provid...
Definition: SIMDTrait.h:315
LeftOperand leftOperand() const noexcept
Returns the left-hand side dense vector operand.
Definition: DVecDVecOuterExpr.h:597
MultTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: DVecDVecOuterExpr.h:202
Header file for the Computation base class.
Constraints on the storage order of matrix types.
BLAZE_ALWAYS_INLINE auto load(size_t i, size_t j) const noexcept
Access to the SIMD elements of the matrix.
Definition: DVecDVecOuterExpr.h:540
If_t< IsExpression_v< VT2 >, const VT2, const VT2 & > RightOperand
Composite type of the right-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:218
Header file for the RequiresEvaluation type trait.
BLAZE_DEVICE_CALLABLE ConstIterator & operator++()
Pre-increment operator.
Definition: DVecDVecOuterExpr.h:295
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
ElementType_t< RT1 > ET1
Element type of the left-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:113
ValueType value_type
Type of the underlying elements.
Definition: DVecDVecOuterExpr.h:242
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: DVecDVecOuterExpr.h:479
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes....
Definition: DenseMatrix.h:81
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: DVecDVecOuterExpr.h:587
Constraint on the transpose flag of vector types.
RightOperand rightOperand() const noexcept
Returns the right-hand side dense vector operand.
Definition: DVecDVecOuterExpr.h:607
Constraint on the data type.
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
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: DVecDVecOuterExpr.h:619
ResultType_t< VT1 > RT1
Result type of the left-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:111
Header file for the IsTemporary type trait class.
ConstIterator(LeftIteratorType left, RightIteratorType right)
Constructor for the ConstIterator class.
Definition: DVecDVecOuterExpr.h:260
static constexpr bool simdEnabled
Compilation switch for the expression template evaluation strategy.
Definition: DVecDVecOuterExpr.h:475
Header file for the multiplication trait.
ResultType_t< VT2 > RT2
Result type of the right-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:112
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
auto load() const noexcept
Access to the SIMD elements of the matrix.
Definition: DVecDVecOuterExpr.h:347
If_t< useAssign, const ResultType, const DVecDVecOuterExpr & > CompositeType
Data type for composite expression templates.
Definition: DVecDVecOuterExpr.h:212
Header file for the If class template.
BLAZE_DEVICE_CALLABLE ConstIterator & operator-=(size_t dec)
Subtraction assignment operator.
Definition: DVecDVecOuterExpr.h:284
#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
BLAZE_DEVICE_CALLABLE const ConstIterator operator--(int)
Post-decrement operator.
Definition: DVecDVecOuterExpr.h:327
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: DVecDVecOuterExpr.h:205
#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
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: DVecDVecOuterExpr.h:631
LeftIteratorType left_
Iterator to the current left-hand side element.
Definition: DVecDVecOuterExpr.h:467
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: DVecDVecOuterExpr.h:209
ConstIterator_t< VT2 > RightIteratorType
ConstIterator type of the right-hand side dense matrix expression.
Definition: DVecDVecOuterExpr.h:251
#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 the DenseMatrix base class.
Header file for all SIMD functionality.
RightOperand rhs_
Right-hand side dense vector of the multiplication expression.
Definition: DVecDVecOuterExpr.h:659
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DVecDVecOuterExpr.h:203
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:76
BLAZE_DEVICE_CALLABLE ConstIterator & operator+=(size_t inc)
Addition assignment operator.
Definition: DVecDVecOuterExpr.h:272
Header file for the IsAligned type trait.
bool operator==(const ConstIterator &rhs) const
Equality comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:358
CompositeType_t< VT2 > CT2
Composite type of the right-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:118
ReturnType operator *() const
Direct access to the element at the current iterator position.
Definition: DVecDVecOuterExpr.h:337
BLAZE_DEVICE_CALLABLE ConstIterator & operator--()
Pre-decrement operator.
Definition: DVecDVecOuterExpr.h:316
bool operator<(const ConstIterator &rhs) const
Less-than comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:380
static constexpr bool useAssign
Compilation switch for the serial evaluation strategy of the outer product expression.
Definition: DVecDVecOuterExpr.h:152
Constraints on the storage order of matrix types.
Constraint on the data type.
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: DVecDVecOuterExpr.h:651
Header file for the exception macros of the math module.
ConstIterator end(size_t i) const
Returns an iterator just past the last non-zero element of row i.
Definition: DVecDVecOuterExpr.h:566
Constraint on the data type.
ReturnType_t< VT1 > RN1
Return type of the left-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:115
Header file for the VecTVecMultExpr base class.
Header file for the EnableIf class template.
DVecDVecOuterExpr(const VT1 &lhs, const VT2 &rhs) noexcept
Constructor for the DVecDVecOuterExpr class.
Definition: DVecDVecOuterExpr.h:493
Header file for the IsPadded type trait.
decltype(std::declval< RN1 >() *std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: DVecDVecOuterExpr.h:141
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
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: DVecDVecOuterExpr.h:522
bool operator<=(const ConstIterator &rhs) const
Less-than comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:402
Header file for the IsSIMDCombinable type trait.
#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
#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.
bool operator>=(const ConstIterator &rhs) const
Greater-than comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:413
DifferenceType operator-(const ConstIterator &rhs) const
Calculating the number of elements between two iterators.
Definition: DVecDVecOuterExpr.h:424
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
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
static constexpr size_t SIMDSIZE
The number of elements packed within a single SIMD element.
Definition: DVecDVecOuterExpr.h:484
If_t< IsExpression_v< VT1 >, const VT1, const VT1 & > LeftOperand
Composite type of the left-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:215
Expression object for outer products between two dense vectors.The DVecDVecOuterExpr class represents...
Definition: DVecDVecOuterExpr.h:105
RightIteratorType right_
Iterator to the current right-hand side element.
Definition: DVecDVecOuterExpr.h:468
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 all forward declarations for expression class templates.
ptrdiff_t DifferenceType
Difference between two iterators.
Definition: DVecDVecOuterExpr.h:238
ConstIterator begin(size_t i) const
Returns an iterator to the first non-zero element of row i.
Definition: DVecDVecOuterExpr.h:554
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
CompositeType_t< VT1 > CT1
Composite type of the left-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:117
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
Constraint on the data type.
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
IntegralConstant< bool, B > BoolConstant
Generic wrapper for a compile time constant boolean value.The BoolConstant alias template represents ...
Definition: IntegralConstant.h:110
Constraint on the data type.
Header file for the IsReference type trait.
auto smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:194
BLAZE_DEVICE_CALLABLE const ConstIterator operator++(int)
Post-increment operator.
Definition: DVecDVecOuterExpr.h:306
Base class for all outer product expression templates.The VecTVecMultExpr class serves as a tag for a...
Definition: VecTVecMultExpr.h:67
#define BLAZE_CONSTRAINT_MATRICES_MUST_HAVE_SAME_STORAGE_ORDER(T1, T2)
Constraint on the data type.In case either of the two given data types T1 or T2 is not a matrix type ...
Definition: StorageOrder.h:84
ReturnType_t< VT2 > RN2
Return type of the right-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:116
typename T::ConstIterator ConstIterator_t
Alias declaration for nested ConstIterator type definitions.The ConstIterator_t alias declaration pro...
Definition: Aliases.h:110
#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
If_t< evaluateRight, const RT2, CT2 > RT
Type for the assignment of the right-hand side dense vector operand.
Definition: DVecDVecOuterExpr.h:224
Macro for CUDA compatibility.
Header file for the IsRowMajorMatrix type trait.
Header file for the IsComputation type trait class.
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: DVecDVecOuterExpr.h:204
bool operator>(const ConstIterator &rhs) const
Greater-than comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:391
Base class for all compute expression templates.The Computation class serves as a tag for all computa...
Definition: Computation.h:66
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: DVecDVecOuterExpr.h:641
ElementType & ReferenceType
Reference return type.
Definition: DVecDVecOuterExpr.h:237
Header file for the IntegralConstant class template.
friend const ConstIterator operator-(const ConstIterator &it, size_t dec)
Subtraction between a ConstIterator and an integral value.
Definition: DVecDVecOuterExpr.h:460
If_t< evaluateLeft, const RT1, CT1 > LT
Type for the assignment of the left-hand side dense vector operand.
Definition: DVecDVecOuterExpr.h:221
PointerType pointer
Pointer return type.
Definition: DVecDVecOuterExpr.h:243
#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
static constexpr bool evaluateRight
Compilation switch for the composite type of the right-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:128
#define BLAZE_DEVICE_CALLABLE
Conditional macro that sets host and device attributes when compiled with CUDA.
Definition: HostDevice.h:94
std::random_access_iterator_tag IteratorCategory
The iterator category.
Definition: DVecDVecOuterExpr.h:234
LeftOperand lhs_
Left-hand side dense vector of the multiplication expression.
Definition: DVecDVecOuterExpr.h:658
friend const ConstIterator operator+(const ConstIterator &it, size_t inc)
Addition between a ConstIterator and an integral value.
Definition: DVecDVecOuterExpr.h:436
IteratorCategory iterator_category
The iterator category.
Definition: DVecDVecOuterExpr.h:241
Iterator over the elements of the dense matrix.
Definition: DVecDVecOuterExpr.h:230
ReferenceType reference
Reference return type.
Definition: DVecDVecOuterExpr.h:244
System settings for the inline keywords.
Header file for the Size type trait.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
ElementType_t< RT2 > ET2
Element type of the right-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:114
#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
SIMDTrait_t< ElementType > SIMDType
Resulting SIMD element type.
Definition: DVecDVecOuterExpr.h:206
ElementType ValueType
Type of the underlying elements.
Definition: DVecDVecOuterExpr.h:235
Constraint on the transpose flag of vector types.
Header file for the IsExpression type trait class.
Header file for the function trace functionality.