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>
75 #include <blaze/system/Inline.h>
78 #include <blaze/util/Assert.h>
79 #include <blaze/util/EnableIf.h>
82 #include <blaze/util/mpl/If.h>
83 #include <blaze/util/Types.h>
85 
86 
87 namespace blaze {
88 
89 //=================================================================================================
90 //
91 // CLASS DVECDVECOUTEREXPR
92 //
93 //=================================================================================================
94 
95 //*************************************************************************************************
102 template< typename VT1 // Type of the left-hand side dense vector
103  , typename VT2 > // Type of the right-hand side dense vector
105  : public VecTVecMultExpr< DenseMatrix< DVecDVecOuterExpr<VT1,VT2>, false > >
106  , private Computation
107 {
108  private:
109  //**Type definitions****************************************************************************
118  //**********************************************************************************************
119 
120  //**********************************************************************************************
122  static constexpr bool evaluateLeft = ( IsComputation_v<VT1> || RequiresEvaluation_v<VT1> );
123  //**********************************************************************************************
124 
125  //**********************************************************************************************
127  static constexpr bool evaluateRight = ( IsComputation_v<VT2> || RequiresEvaluation_v<VT2> );
128  //**********************************************************************************************
129 
130  //**Return type evaluation**********************************************************************
132 
137  static constexpr bool returnExpr = ( !IsTemporary_v<RN1> && !IsTemporary_v<RN2> );
138 
140  using ExprReturnType = decltype( std::declval<RN1>() * std::declval<RN2>() );
141  //**********************************************************************************************
142 
143  //**Serial evaluation strategy******************************************************************
145 
151  static constexpr bool useAssign = ( evaluateLeft || evaluateRight );
152 
154  template< typename VT >
156  static constexpr bool UseAssign_v = useAssign;
158  //**********************************************************************************************
159 
160  //**Parallel evaluation strategy****************************************************************
162 
166  template< typename VT >
167  static constexpr bool UseSMPAssign_v = evaluateRight;
169  //**********************************************************************************************
170 
171  //**********************************************************************************************
173 
176  template< typename T1, typename T2, typename T3 >
177  static constexpr bool UseVectorizedKernel_v =
178  ( useOptimizedKernels &&
179  T1::simdEnabled && T2::simdEnabled && T3::simdEnabled &&
180  IsSIMDCombinable_v< ElementType_t<T1>
182  , ElementType_t<T3> > &&
183  HasSIMDMult_v< ElementType_t<T2>, ElementType_t<T3> > );
185  //**********************************************************************************************
186 
187  //**********************************************************************************************
189 
192  template< typename T1, typename T2, typename T3 >
193  static constexpr bool UseDefaultKernel_v = !UseVectorizedKernel_v<T1,T2,T3>;
195  //**********************************************************************************************
196 
197  public:
198  //**Type definitions****************************************************************************
206 
209 
212 
214  using LeftOperand = If_t< IsExpression_v<VT1>, const VT1, const VT1& >;
215 
217  using RightOperand = If_t< IsExpression_v<VT2>, const VT2, const VT2& >;
218 
221 
224  //**********************************************************************************************
225 
226  //**ConstIterator class definition**************************************************************
230  {
231  public:
232  //**Type definitions*************************************************************************
233  using IteratorCategory = std::random_access_iterator_tag;
238 
239  // STL iterator requirements
245 
248 
251  //*******************************************************************************************
252 
253  //**Constructor******************************************************************************
259  explicit inline ConstIterator( LeftIteratorType left, RightIteratorType right )
260  : left_ ( left ) // Iterator to the current left-hand side element
261  , right_( right ) // Iterator to the current right-hand side element
262  {}
263  //*******************************************************************************************
264 
265  //**Addition assignment operator*************************************************************
271  inline ConstIterator& operator+=( size_t inc ) {
272  right_ += inc;
273  return *this;
274  }
275  //*******************************************************************************************
276 
277  //**Subtraction assignment operator**********************************************************
283  inline ConstIterator& operator-=( size_t dec ) {
284  right_ -= dec;
285  return *this;
286  }
287  //*******************************************************************************************
288 
289  //**Prefix increment operator****************************************************************
295  ++right_;
296  return *this;
297  }
298  //*******************************************************************************************
299 
300  //**Postfix increment operator***************************************************************
305  inline const ConstIterator operator++( int ) {
306  return ConstIterator( left_, right_++ );
307  }
308  //*******************************************************************************************
309 
310  //**Prefix decrement operator****************************************************************
316  --right_;
317  return *this;
318  }
319  //*******************************************************************************************
320 
321  //**Postfix decrement operator***************************************************************
326  inline const ConstIterator operator--( int ) {
327  return ConstIterator( left_, right_-- );
328  }
329  //*******************************************************************************************
330 
331  //**Element access operator******************************************************************
336  inline ReturnType operator*() const {
337  return (*left_) * (*right_);
338  }
339  //*******************************************************************************************
340 
341  //**Load function****************************************************************************
346  inline auto load() const noexcept {
347  return set( *left_ ) * right_.load();
348  }
349  //*******************************************************************************************
350 
351  //**Equality operator************************************************************************
357  inline bool operator==( const ConstIterator& rhs ) const {
358  return right_ == rhs.right_;
359  }
360  //*******************************************************************************************
361 
362  //**Inequality operator**********************************************************************
368  inline bool operator!=( const ConstIterator& rhs ) const {
369  return right_ != rhs.right_;
370  }
371  //*******************************************************************************************
372 
373  //**Less-than operator***********************************************************************
379  inline bool operator<( const ConstIterator& rhs ) const {
380  return right_ < rhs.right_;
381  }
382  //*******************************************************************************************
383 
384  //**Greater-than operator********************************************************************
390  inline bool operator>( const ConstIterator& rhs ) const {
391  return right_ > rhs.right_;
392  }
393  //*******************************************************************************************
394 
395  //**Less-or-equal-than operator**************************************************************
401  inline bool operator<=( const ConstIterator& rhs ) const {
402  return right_ <= rhs.right_;
403  }
404  //*******************************************************************************************
405 
406  //**Greater-or-equal-than operator***********************************************************
412  inline bool operator>=( const ConstIterator& rhs ) const {
413  return right_ >= rhs.right_;
414  }
415  //*******************************************************************************************
416 
417  //**Subtraction operator*********************************************************************
423  inline DifferenceType operator-( const ConstIterator& rhs ) const {
424  return right_ - rhs.right_;
425  }
426  //*******************************************************************************************
427 
428  //**Addition operator************************************************************************
435  friend inline const ConstIterator operator+( const ConstIterator& it, size_t inc ) {
436  return ConstIterator( it.left_, it.right_ + inc );
437  }
438  //*******************************************************************************************
439 
440  //**Addition operator************************************************************************
447  friend inline const ConstIterator operator+( size_t inc, const ConstIterator& it ) {
448  return ConstIterator( it.left_, it.right_ + inc );
449  }
450  //*******************************************************************************************
451 
452  //**Subtraction operator*********************************************************************
459  friend inline const ConstIterator operator-( const ConstIterator& it, size_t dec ) {
460  return ConstIterator( it.left_, it.right_ - dec );
461  }
462  //*******************************************************************************************
463 
464  private:
465  //**Member variables*************************************************************************
468  //*******************************************************************************************
469  };
470  //**********************************************************************************************
471 
472  //**Compilation flags***************************************************************************
474  static constexpr bool simdEnabled =
475  ( VT1::simdEnabled && VT2::simdEnabled && HasSIMDMult_v<ET1,ET2> );
476 
478  static constexpr bool smpAssignable = ( VT1::smpAssignable && !evaluateRight );
479  //**********************************************************************************************
480 
481  //**SIMD properties*****************************************************************************
483  static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
484  //**********************************************************************************************
485 
486  //**Constructor*********************************************************************************
492  explicit inline DVecDVecOuterExpr( const VT1& lhs, const VT2& rhs ) noexcept
493  : lhs_( lhs ) // Left-hand side dense vector of the multiplication expression
494  , rhs_( rhs ) // Right-hand side dense vector of the multiplication expression
495  {}
496  //**********************************************************************************************
497 
498  //**Access operator*****************************************************************************
505  inline ReturnType operator()( size_t i, size_t j ) const {
506  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
507  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
508 
509  return lhs_[i] * rhs_[j];
510  }
511  //**********************************************************************************************
512 
513  //**At function*********************************************************************************
521  inline ReturnType at( size_t i, size_t j ) const {
522  if( i >= lhs_.size() ) {
523  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
524  }
525  if( j >= rhs_.size() ) {
526  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
527  }
528  return (*this)(i,j);
529  }
530  //**********************************************************************************************
531 
532  //**Load function*******************************************************************************
539  BLAZE_ALWAYS_INLINE auto load( size_t i, size_t j ) const noexcept {
540  BLAZE_INTERNAL_ASSERT( i < lhs_.size() , "Invalid row access index" );
541  BLAZE_INTERNAL_ASSERT( j < rhs_.size() , "Invalid column access index" );
542  BLAZE_INTERNAL_ASSERT( j % SIMDSIZE == 0UL, "Invalid column access index" );
543  return set( lhs_[i] ) * rhs_.load( j );
544  }
545  //**********************************************************************************************
546 
547  //**Begin function******************************************************************************
553  inline ConstIterator begin( size_t i ) const {
554  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
555  return ConstIterator( lhs_.begin()+i, rhs_.begin() );
556  }
557  //**********************************************************************************************
558 
559  //**End function********************************************************************************
565  inline ConstIterator end( size_t i ) const {
566  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
567  return ConstIterator( lhs_.begin()+i, rhs_.end() );
568  }
569  //**********************************************************************************************
570 
571  //**Rows function*******************************************************************************
576  inline size_t rows() const noexcept {
577  return lhs_.size();
578  }
579  //**********************************************************************************************
580 
581  //**Columns function****************************************************************************
586  inline size_t columns() const noexcept {
587  return rhs_.size();
588  }
589  //**********************************************************************************************
590 
591  //**Left operand access*************************************************************************
596  inline LeftOperand leftOperand() const noexcept {
597  return lhs_;
598  }
599  //**********************************************************************************************
600 
601  //**Right operand access************************************************************************
606  inline RightOperand rightOperand() const noexcept {
607  return rhs_;
608  }
609  //**********************************************************************************************
610 
611  //**********************************************************************************************
617  template< typename T >
618  inline bool canAlias( const T* alias ) const noexcept {
619  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
620  }
621  //**********************************************************************************************
622 
623  //**********************************************************************************************
629  template< typename T >
630  inline bool isAliased( const T* alias ) const noexcept {
631  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
632  }
633  //**********************************************************************************************
634 
635  //**********************************************************************************************
640  inline bool isAligned() const noexcept {
641  return lhs_.isAligned() && rhs_.isAligned();
642  }
643  //**********************************************************************************************
644 
645  //**********************************************************************************************
650  inline bool canSMPAssign() const noexcept {
651  return ( rows() * columns() >= SMP_DVECDVECOUTER_THRESHOLD );
652  }
653  //**********************************************************************************************
654 
655  private:
656  //**Member variables****************************************************************************
659  //**********************************************************************************************
660 
661  //**Assignment to row-major dense matrices******************************************************
675  template< typename MT > // Type of the target dense matrix
676  friend inline auto assign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
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 dense 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  DVecDVecOuterExpr::selectAssignKernel( ~lhs, x, y );
693  }
695  //**********************************************************************************************
696 
697  //**Default assignment to row-major dense matrices**********************************************
711  template< typename MT // Type of the left-hand side target matrix
712  , typename VT3 // Type of the left-hand side vector operand
713  , typename VT4 > // Type of the right-hand side vector operand
714  static inline auto selectAssignKernel( MT& A, const VT3& x, const VT4& y )
715  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
716  {
717  const size_t M( A.rows() );
718  const size_t N( A.columns() );
719 
720  const size_t jpos( N & size_t(-2) );
721  BLAZE_INTERNAL_ASSERT( ( N - ( N % 2UL ) ) == jpos, "Invalid end calculation" );
722 
723  for( size_t i=0UL; i<M; ++i ) {
724  for( size_t j=0UL; j<jpos; j+=2UL ) {
725  A(i,j ) = x[i] * y[j ];
726  A(i,j+1UL) = x[i] * y[j+1];
727  }
728  if( jpos < N ) {
729  A(i,jpos) = x[i] * y[jpos];
730  }
731  }
732  }
734  //**********************************************************************************************
735 
736  //**Vectorized assignment to row-major dense matrices*******************************************
750  template< typename MT // Type of the left-hand side target matrix
751  , typename VT3 // Type of the left-hand side vector operand
752  , typename VT4 > // Type of the right-hand side vector operand
753  static inline auto selectAssignKernel( MT& A, const VT3& x, const VT4& y )
754  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
755  {
756  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT4> );
757 
758  const size_t M( A.rows() );
759  const size_t N( A.columns() );
760 
761  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
762  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
763 
764  for( size_t i=0UL; i<M; ++i )
765  {
766  const SIMDType x1( set( x[i] ) );
767 
768  size_t j( 0UL );
769 
770  for( ; j<jpos; j+=SIMDSIZE ) {
771  A.store( i, j, x1 * y.load(j) );
772  }
773  for( ; remainder && j<N; ++j ) {
774  A(i,j) = x[i] * y[j];
775  }
776  }
777  }
779  //**********************************************************************************************
780 
781  //**Assignment to column-major dense matrices***************************************************
793  template< typename MT > // Type of the target dense matrix
794  friend inline void assign( DenseMatrix<MT,true>& lhs, const DVecDVecOuterExpr& rhs )
795  {
797 
799 
800  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
801  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
802 
803  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
804  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
805 
806  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
807  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
808  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
809  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
810 
811  DVecDVecOuterExpr::selectAssignKernel( ~lhs, x, y );
812  }
814  //**********************************************************************************************
815 
816  //**Default assignment to column-major dense matrices*******************************************
830  template< typename MT // Type of the left-hand side target matrix
831  , typename VT3 // Type of the left-hand side vector operand
832  , typename VT4 > // Type of the right-hand side vector operand
833  static inline auto selectAssignKernel( MT& A, const VT3& x, const VT4& y )
834  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
835  {
836  const size_t M( A.rows() );
837  const size_t N( A.columns() );
838 
839  const size_t ipos( M & size_t(-2) );
840  BLAZE_INTERNAL_ASSERT( ( M - ( M % 2UL ) ) == ipos, "Invalid end calculation" );
841 
842  for( size_t j=0UL; j<N; ++j ) {
843  for( size_t i=0UL; i<ipos; i+=2UL ) {
844  A(i ,j) = x[i ] * y[j];
845  A(i+1UL,j) = x[i+1] * y[j];
846  }
847  if( ipos < M ) {
848  A(ipos,j) = x[ipos] * y[j];
849  }
850  }
851  }
853  //**********************************************************************************************
854 
855  //**Vectorized assignment to column-major dense matrices****************************************
869  template< typename MT // Type of the left-hand side target matrix
870  , typename VT3 // Type of the left-hand side vector operand
871  , typename VT4 > // Type of the right-hand side vector operand
872  static inline auto selectAssignKernel( MT& A, const VT3& x, const VT4& y )
873  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
874  {
875  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT3> );
876 
877  const size_t M( A.rows() );
878  const size_t N( A.columns() );
879 
880  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
881  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
882 
883  for( size_t j=0UL; j<N; ++j )
884  {
885  const SIMDType y1( set( y[j] ) );
886 
887  size_t i( 0UL );
888 
889  for( ; i<ipos; i+=SIMDSIZE ) {
890  A.store( i, j, x.load(i) * y1 );
891  }
892  for( ; remainder && i<M; ++i ) {
893  A(i,j) = x[i] * y[j];
894  }
895  }
896  }
898  //**********************************************************************************************
899 
900  //**Assignment to sparse matrices***************************************************************
912  template< typename MT // Type of the target sparse matrix
913  , bool SO > // Storage order of the target sparse matrix
914  friend inline void assign( SparseMatrix<MT,SO>& lhs, const DVecDVecOuterExpr& rhs )
915  {
917 
918  using TmpType = If_t< SO, OppositeType, ResultType >;
919 
926 
927  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
928  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
929 
930  const TmpType tmp( serial( rhs ) );
931  assign( ~lhs, tmp );
932  }
934  //**********************************************************************************************
935 
936  //**Addition assignment to row-major dense matrices*********************************************
951  template< typename MT > // Type of the target dense matrix
952  friend inline auto addAssign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
953  -> EnableIf_t< UseAssign_v<MT> >
954  {
956 
957  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
958  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
959 
960  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
961  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
962 
963  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
964  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
965  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
966  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
967 
968  DVecDVecOuterExpr::selectAddAssignKernel( ~lhs, x, y );
969  }
971  //**********************************************************************************************
972 
973  //**Default addition assignment to row-major dense matrices*************************************
987  template< typename MT // Type of the left-hand side target matrix
988  , typename VT3 // Type of the left-hand side vector operand
989  , typename VT4 > // Type of the right-hand side vector operand
990  static inline auto selectAddAssignKernel( MT& A, const VT3& x, const VT4& y )
991  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
992  {
993  const size_t M( A.rows() );
994  const size_t N( A.columns() );
995 
996  const size_t jpos( N & size_t(-2) );
997  BLAZE_INTERNAL_ASSERT( ( N - ( N % 2UL ) ) == jpos, "Invalid end calculation" );
998 
999  for( size_t i=0UL; i<M; ++i ) {
1000  for( size_t j=0UL; j<jpos; j+=2UL ) {
1001  A(i,j ) += x[i] * y[j ];
1002  A(i,j+1UL) += x[i] * y[j+1UL];
1003  }
1004  if( jpos < N ) {
1005  A(i,jpos) += x[i] * y[jpos];
1006  }
1007  }
1008  }
1010  //**********************************************************************************************
1011 
1012  //**Vectorized addition assignment to row-major dense matrices**********************************
1026  template< typename MT // Type of the left-hand side target matrix
1027  , typename VT3 // Type of the left-hand side vector operand
1028  , typename VT4 > // Type of the right-hand side vector operand
1029  static inline auto selectAddAssignKernel( MT& A, const VT3& x, const VT4& y )
1030  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
1031  {
1032  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT4> );
1033 
1034  const size_t M( A.rows() );
1035  const size_t N( A.columns() );
1036 
1037  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
1038  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
1039 
1040  for( size_t i=0UL; i<M; ++i )
1041  {
1042  const SIMDType x1( set( x[i] ) );
1043 
1044  size_t j( 0UL );
1045 
1046  for( ; j<jpos; j+=SIMDSIZE ) {
1047  A.store( i, j, A.load(i,j) + x1 * y.load(j) );
1048  }
1049  for( ; remainder && j<N; ++j ) {
1050  A(i,j) += x[i] * y[j];
1051  }
1052  }
1053  }
1055  //**********************************************************************************************
1056 
1057  //**Addition assignment to column-major dense matrices******************************************
1070  template< typename MT > // Type of the target dense matrix
1071  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const DVecDVecOuterExpr& rhs )
1072  {
1074 
1076 
1077  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1078  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1079 
1080  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1081  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1082 
1083  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1084  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1085  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1086  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1087 
1088  DVecDVecOuterExpr::selectAddAssignKernel( ~lhs, x, y );
1089  }
1091  //**********************************************************************************************
1092 
1093  //**Default addition assignment to column dense matrices****************************************
1107  template< typename MT // Type of the left-hand side target matrix
1108  , typename VT3 // Type of the left-hand side vector operand
1109  , typename VT4 > // Type of the right-hand side vector operand
1110  static inline auto selectAddAssignKernel( MT& A, const VT3& x, const VT4& y )
1111  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
1112  {
1113  const size_t M( A.rows() );
1114  const size_t N( A.columns() );
1115 
1116  const size_t ipos( M & size_t(-2) );
1117  BLAZE_INTERNAL_ASSERT( ( M - ( M % 2UL ) ) == ipos, "Invalid end calculation" );
1118 
1119  for( size_t j=0UL; j<N; ++j ) {
1120  for( size_t i=0UL; i<ipos; i+=2UL ) {
1121  A(i ,j) += x[i ] * y[j];
1122  A(i+1UL,j) += x[i+1UL] * y[j];
1123  }
1124  if( ipos < M ) {
1125  A(ipos,j) += x[ipos] * y[j];
1126  }
1127  }
1128  }
1130  //**********************************************************************************************
1131 
1132  //**Vectorized addition assignment to column-major dense matrices*******************************
1146  template< typename MT // Type of the left-hand side target matrix
1147  , typename VT3 // Type of the left-hand side vector operand
1148  , typename VT4 > // Type of the right-hand side vector operand
1149  static inline auto selectAddAssignKernel( MT& A, const VT3& x, const VT4& y )
1150  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
1151  {
1152  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT3> );
1153 
1154  const size_t M( A.rows() );
1155  const size_t N( A.columns() );
1156 
1157  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
1158  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
1159 
1160  for( size_t j=0UL; j<N; ++j )
1161  {
1162  const SIMDType y1( set( y[j] ) );
1163 
1164  size_t i( 0UL );
1165 
1166  for( ; i<ipos; i+=SIMDSIZE ) {
1167  A.store( i, j, A.load(i,j) + x.load(i) * y1 );
1168  }
1169  for( ; remainder && i<M; ++i ) {
1170  A(i,j) += x[i] * y[j];
1171  }
1172  }
1173  }
1175  //**********************************************************************************************
1176 
1177  //**Addition assignment to sparse matrices******************************************************
1178  // No special implementation for the addition assignment to sparse matrices.
1179  //**********************************************************************************************
1180 
1181  //**Subtraction assignment to row-major dense matrices******************************************
1196  template< typename MT > // Type of the target dense matrix
1197  friend inline auto subAssign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
1198  -> EnableIf_t< UseAssign_v<MT> >
1199  {
1201 
1202  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1203  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1204 
1205  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1206  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1207 
1208  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1209  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1210  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1211  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1212 
1213  DVecDVecOuterExpr::selectSubAssignKernel( ~lhs, x, y );
1214  }
1216  //**********************************************************************************************
1217 
1218  //**Default subtraction assignment to row-major dense matrices**********************************
1232  template< typename MT // Type of the left-hand side target matrix
1233  , typename VT3 // Type of the left-hand side vector operand
1234  , typename VT4 > // Type of the right-hand side vector operand
1235  static inline auto selectSubAssignKernel( MT& A, const VT3& x, const VT4& y )
1236  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
1237  {
1238  const size_t M( A.rows() );
1239  const size_t N( A.columns() );
1240 
1241  const size_t jpos( N & size_t(-2) );
1242  BLAZE_INTERNAL_ASSERT( ( N - ( N % 2UL ) ) == jpos, "Invalid end calculation" );
1243 
1244  for( size_t i=0UL; i<M; ++i ) {
1245  for( size_t j=0UL; j<jpos; j+=2UL ) {
1246  A(i,j ) -= x[i] * y[j ];
1247  A(i,j+1UL) -= x[i] * y[j+1UL];
1248  }
1249  if( jpos < N ) {
1250  A(i,jpos) -= x[i] * y[jpos];
1251  }
1252  }
1253  }
1255  //**********************************************************************************************
1256 
1257  //**Vectorized subtraction assignment to row-major dense matrices*******************************
1271  template< typename MT // Type of the left-hand side target matrix
1272  , typename VT3 // Type of the left-hand side vector operand
1273  , typename VT4 > // Type of the right-hand side vector operand
1274  static inline auto selectSubAssignKernel( MT& A, const VT3& x, const VT4& y )
1275  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
1276  {
1277  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT4> );
1278 
1279  const size_t M( A.rows() );
1280  const size_t N( A.columns() );
1281 
1282  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
1283  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
1284 
1285  for( size_t i=0UL; i<M; ++i )
1286  {
1287  const SIMDType x1( set( x[i] ) );
1288 
1289  size_t j( 0UL );
1290 
1291  for( ; j<jpos; j+=SIMDSIZE ) {
1292  A.store( i, j, A.load(i,j) - x1 * y.load(j) );
1293  }
1294  for( ; remainder && j<N; ++j ) {
1295  A(i,j) -= x[i] * y[j];
1296  }
1297  }
1298  }
1300  //**********************************************************************************************
1301 
1302  //**Subtraction assignment to column-major dense matrices***************************************
1315  template< typename MT > // Type of the target dense matrix
1316  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const DVecDVecOuterExpr& rhs )
1317  {
1319 
1321 
1322  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1323  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1324 
1325  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1326  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1327 
1328  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1329  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1330  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1331  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1332 
1333  DVecDVecOuterExpr::selectSubAssignKernel( ~lhs, x, y );
1334  }
1336  //**********************************************************************************************
1337 
1338  //**Default subtraction assignment to column dense matrices*************************************
1352  template< typename MT // Type of the left-hand side target matrix
1353  , typename VT3 // Type of the left-hand side vector operand
1354  , typename VT4 > // Type of the right-hand side vector operand
1355  static inline auto selectSubAssignKernel( MT& A, const VT3& x, const VT4& y )
1356  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
1357  {
1358  const size_t M( A.rows() );
1359  const size_t N( A.columns() );
1360 
1361  const size_t ipos( M & size_t(-2) );
1362  BLAZE_INTERNAL_ASSERT( ( M - ( M % 2UL ) ) == ipos, "Invalid end calculation" );
1363 
1364  for( size_t j=0UL; j<N; ++j ) {
1365  for( size_t i=0UL; i<ipos; i+=2UL ) {
1366  A(i ,j) -= x[i ] * y[j];
1367  A(i+1UL,j) -= x[i+1UL] * y[j];
1368  }
1369  if( ipos < M ) {
1370  A(ipos,j) -= x[ipos] * y[j];
1371  }
1372  }
1373  }
1375  //**********************************************************************************************
1376 
1377  //**Vectorized subtraction assignment to column-major dense matrices****************************
1391  template< typename MT // Type of the left-hand side target matrix
1392  , typename VT3 // Type of the left-hand side vector operand
1393  , typename VT4 > // Type of the right-hand side vector operand
1394  static inline auto selectSubAssignKernel( MT& A, const VT3& x, const VT4& y )
1395  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
1396  {
1397  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT3> );
1398 
1399  const size_t M( A.rows() );
1400  const size_t N( A.columns() );
1401 
1402  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
1403  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
1404 
1405  for( size_t j=0UL; j<N; ++j )
1406  {
1407  const SIMDType y1( set( y[j] ) );
1408 
1409  size_t i( 0UL );
1410 
1411  for( ; i<ipos; i+=SIMDSIZE ) {
1412  A.store( i, j, A.load(i,j) - x.load(i) * y1 );
1413  }
1414  for( ; remainder && i<M; ++i ) {
1415  A(i,j) -= x[i] * y[j];
1416  }
1417  }
1418  }
1420  //**********************************************************************************************
1421 
1422  //**Subtraction assignment to sparse matrices***************************************************
1423  // No special implementation for the subtraction assignment to sparse matrices.
1424  //**********************************************************************************************
1425 
1426  //**Schur product assignment to row-major dense matrices****************************************
1441  template< typename MT > // Type of the target dense matrix
1442  friend inline auto schurAssign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
1443  -> EnableIf_t< UseAssign_v<MT> >
1444  {
1446 
1447  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1448  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1449 
1450  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1451  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1452 
1453  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1454  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1455  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1456  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1457 
1458  DVecDVecOuterExpr::selectSchurAssignKernel( ~lhs, x, y );
1459  }
1461  //**********************************************************************************************
1462 
1463  //**Default Schur product assignment to row-major dense matrices********************************
1477  template< typename MT // Type of the left-hand side target matrix
1478  , typename VT3 // Type of the left-hand side vector operand
1479  , typename VT4 > // Type of the right-hand side vector operand
1480  static inline auto selectSchurAssignKernel( MT& A, const VT3& x, const VT4& y )
1481  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
1482  {
1483  const size_t M( A.rows() );
1484  const size_t N( A.columns() );
1485 
1486  const size_t jpos( N & size_t(-2) );
1487  BLAZE_INTERNAL_ASSERT( ( N - ( N % 2UL ) ) == jpos, "Invalid end calculation" );
1488 
1489  for( size_t i=0UL; i<M; ++i ) {
1490  for( size_t j=0UL; j<jpos; j+=2UL ) {
1491  A(i,j ) *= x[i] * y[j ];
1492  A(i,j+1UL) *= x[i] * y[j+1UL];
1493  }
1494  if( jpos < N ) {
1495  A(i,jpos) *= x[i] * y[jpos];
1496  }
1497  }
1498  }
1500  //**********************************************************************************************
1501 
1502  //**Vectorized Schur product assignment to row-major dense matrices*****************************
1516  template< typename MT // Type of the left-hand side target matrix
1517  , typename VT3 // Type of the left-hand side vector operand
1518  , typename VT4 > // Type of the right-hand side vector operand
1519  static inline auto selectSchurAssignKernel( MT& A, const VT3& x, const VT4& y )
1520  -> EnableIf_t< IsRowMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
1521  {
1522  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT4> );
1523 
1524  const size_t M( A.rows() );
1525  const size_t N( A.columns() );
1526 
1527  const size_t jpos( remainder ? ( N & size_t(-SIMDSIZE) ) : N );
1528  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
1529 
1530  for( size_t i=0UL; i<M; ++i )
1531  {
1532  const SIMDType x1( set( x[i] ) );
1533 
1534  size_t j( 0UL );
1535 
1536  for( ; j<jpos; j+=SIMDSIZE ) {
1537  A.store( i, j, A.load(i,j) * ( x1 * y.load(j) ) );
1538  }
1539  for( ; remainder && j<N; ++j ) {
1540  A(i,j) *= x[i] * y[j];
1541  }
1542  }
1543  }
1545  //**********************************************************************************************
1546 
1547  //**Schur product assignment to column-major dense matrices*************************************
1560  template< typename MT > // Type of the target dense matrix
1561  friend inline void schurAssign( DenseMatrix<MT,true>& lhs, const DVecDVecOuterExpr& rhs )
1562  {
1564 
1566 
1567  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1568  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1569 
1570  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
1571  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
1572 
1573  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1574  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1575  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1576  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1577 
1578  DVecDVecOuterExpr::selectSchurAssignKernel( ~lhs, x, y );
1579  }
1581  //**********************************************************************************************
1582 
1583  //**Default Schur product assignment to column dense matrices***********************************
1597  template< typename MT // Type of the left-hand side target matrix
1598  , typename VT3 // Type of the left-hand side vector operand
1599  , typename VT4 > // Type of the right-hand side vector operand
1600  static inline auto selectSchurAssignKernel( MT& A, const VT3& x, const VT4& y )
1601  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseDefaultKernel_v<MT,VT3,VT4> >
1602  {
1603  const size_t M( A.rows() );
1604  const size_t N( A.columns() );
1605 
1606  const size_t ipos( M & size_t(-2) );
1607  BLAZE_INTERNAL_ASSERT( ( M - ( M % 2UL ) ) == ipos, "Invalid end calculation" );
1608 
1609  for( size_t j=0UL; j<N; ++j ) {
1610  for( size_t i=0UL; i<ipos; i+=2UL ) {
1611  A(i ,j) *= x[i ] * y[j];
1612  A(i+1UL,j) *= x[i+1UL] * y[j];
1613  }
1614  if( ipos < M ) {
1615  A(ipos,j) *= x[ipos] * y[j];
1616  }
1617  }
1618  }
1620  //**********************************************************************************************
1621 
1622  //**Vectorized Schur product assignment to column-major dense matrices**************************
1636  template< typename MT // Type of the left-hand side target matrix
1637  , typename VT3 // Type of the left-hand side vector operand
1638  , typename VT4 > // Type of the right-hand side vector operand
1639  static inline auto selectSchurAssignKernel( MT& A, const VT3& x, const VT4& y )
1640  -> EnableIf_t< IsColumnMajorMatrix_v<MT> && UseVectorizedKernel_v<MT,VT3,VT4> >
1641  {
1642  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT3> );
1643 
1644  const size_t M( A.rows() );
1645  const size_t N( A.columns() );
1646 
1647  const size_t ipos( remainder ? ( M & size_t(-SIMDSIZE) ) : M );
1648  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
1649 
1650  for( size_t j=0UL; j<N; ++j )
1651  {
1652  const SIMDType y1( set( y[j] ) );
1653 
1654  size_t i( 0UL );
1655 
1656  for( ; i<ipos; i+=SIMDSIZE ) {
1657  A.store( i, j, A.load(i,j) * ( x.load(i) * y1 ) );
1658  }
1659  for( ; remainder && i<M; ++i ) {
1660  A(i,j) *= x[i] * y[j];
1661  }
1662  }
1663  }
1665  //**********************************************************************************************
1666 
1667  //**Schur product assignment to sparse matrices*************************************************
1668  // No special implementation for the Schur product assignment to sparse matrices.
1669  //**********************************************************************************************
1670 
1671  //**Multiplication assignment to dense matrices*************************************************
1672  // No special implementation for the multiplication assignment to dense matrices.
1673  //**********************************************************************************************
1674 
1675  //**Multiplication assignment to sparse matrices************************************************
1676  // No special implementation for the multiplication assignment to sparse matrices.
1677  //**********************************************************************************************
1678 
1679  //**SMP assignment to dense matrices************************************************************
1693  template< typename MT // Type of the target dense matrix
1694  , bool SO > // Storage order of the target dense matrix
1695  friend inline auto smpAssign( DenseMatrix<MT,SO>& lhs, const DVecDVecOuterExpr& rhs )
1696  -> EnableIf_t< UseSMPAssign_v<MT> >
1697  {
1699 
1700  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1701  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1702 
1703  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
1704  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
1705 
1706  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1707  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1708  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1709  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1710 
1711  smpAssign( ~lhs, x * y );
1712  }
1714  //**********************************************************************************************
1715 
1716  //**SMP assignment to sparse matrices***********************************************************
1730  template< typename MT // Type of the target sparse matrix
1731  , bool SO > // Storage order of the target sparse matrix
1732  friend inline auto smpAssign( SparseMatrix<MT,SO>& lhs, const DVecDVecOuterExpr& rhs )
1733  -> EnableIf_t< UseSMPAssign_v<MT> >
1734  {
1736 
1737  using TmpType = If_t< SO, OppositeType, ResultType >;
1738 
1745 
1746  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1747  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1748 
1749  const TmpType tmp( rhs );
1750  smpAssign( ~lhs, tmp );
1751  }
1753  //**********************************************************************************************
1754 
1755  //**SMP addition assignment to dense matrices***************************************************
1769  template< typename MT > // Type of the target dense matrix
1770  friend inline auto smpAddAssign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
1771  -> EnableIf_t< UseSMPAssign_v<MT> >
1772  {
1774 
1775  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1776  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1777 
1778  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
1779  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
1780 
1781  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1782  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1783  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1784  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1785 
1786  smpAddAssign( ~lhs, x * y );
1787  }
1789  //**********************************************************************************************
1790 
1791  //**SMP addition assignment to sparse matrices**************************************************
1792  // No special implementation for the SMP addition assignment to sparse matrices.
1793  //**********************************************************************************************
1794 
1795  //**SMP subtraction assignment to dense matrices************************************************
1810  template< typename MT > // Type of the target dense matrix
1811  friend inline auto smpSubAssign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
1812  -> EnableIf_t< UseSMPAssign_v<MT> >
1813  {
1815 
1816  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1817  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1818 
1819  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
1820  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
1821 
1822  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1823  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1824  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1825  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1826 
1827  smpSubAssign( ~lhs, x * y );
1828  }
1830  //**********************************************************************************************
1831 
1832  //**SMP subtraction assignment to sparse matrices***********************************************
1833  // No special implementation for the SMP subtraction assignment to sparse matrices.
1834  //**********************************************************************************************
1835 
1836  //**SMP Schur product assignment to dense matrices**********************************************
1851  template< typename MT > // Type of the target dense matrix
1852  friend inline auto smpSchurAssign( DenseMatrix<MT,false>& lhs, const DVecDVecOuterExpr& rhs )
1853  -> EnableIf_t< UseSMPAssign_v<MT> >
1854  {
1856 
1857  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1858  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1859 
1860  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
1861  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
1862 
1863  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
1864  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
1865  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
1866  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
1867 
1868  smpSchurAssign( ~lhs, x * y );
1869  }
1871  //**********************************************************************************************
1872 
1873  //**SMP Schur product assignment to sparse matrices*********************************************
1874  // No special implementation for the SMP Schur product assignment to sparse matrices.
1875  //**********************************************************************************************
1876 
1877  //**SMP multiplication assignment to dense matrices*********************************************
1878  // No special implementation for the SMP multiplication assignment to dense matrices.
1879  //**********************************************************************************************
1880 
1881  //**SMP multiplication assignment to sparse matrices********************************************
1882  // No special implementation for the SMP multiplication assignment to sparse matrices.
1883  //**********************************************************************************************
1884 
1885  //**Compile time checks*************************************************************************
1893  //**********************************************************************************************
1894 };
1895 //*************************************************************************************************
1896 
1897 
1898 
1899 
1900 //=================================================================================================
1901 //
1902 // GLOBAL BINARY ARITHMETIC OPERATORS
1903 //
1904 //=================================================================================================
1905 
1906 //*************************************************************************************************
1933 template< typename VT1 // Type of the left-hand side dense vector
1934  , typename VT2 > // Type of the right-hand side dense vector
1935 inline decltype(auto)
1936  operator*( const DenseVector<VT1,false>& lhs, const DenseVector<VT2,true>& rhs )
1937 {
1939 
1940  using ReturnType = const DVecDVecOuterExpr<VT1,VT2>;
1941  return ReturnType( ~lhs, ~rhs );
1942 }
1943 //*************************************************************************************************
1944 
1945 
1946 
1947 
1948 //=================================================================================================
1949 //
1950 // SIZE SPECIALIZATIONS
1951 //
1952 //=================================================================================================
1953 
1954 //*************************************************************************************************
1956 template< typename VT1, typename VT2 >
1957 struct Size< DVecDVecOuterExpr<VT1,VT2>, 0UL >
1958  : public Size<VT1,0UL>
1959 {};
1960 
1961 template< typename VT1, typename VT2 >
1962 struct Size< DVecDVecOuterExpr<VT1,VT2>, 1UL >
1963  : public Size<VT2,0UL>
1964 {};
1966 //*************************************************************************************************
1967 
1968 
1969 
1970 
1971 //=================================================================================================
1972 //
1973 // ISALIGNED SPECIALIZATIONS
1974 //
1975 //=================================================================================================
1976 
1977 //*************************************************************************************************
1979 template< typename VT1, typename VT2 >
1980 struct IsAligned< DVecDVecOuterExpr<VT1,VT2> >
1981  : public BoolConstant< IsAligned_v<VT1> && IsAligned_v<VT2> >
1982 {};
1984 //*************************************************************************************************
1985 
1986 
1987 
1988 
1989 //=================================================================================================
1990 //
1991 // ISPADDED SPECIALIZATIONS
1992 //
1993 //=================================================================================================
1994 
1995 //*************************************************************************************************
1997 template< typename VT1, typename VT2 >
1998 struct IsPadded< DVecDVecOuterExpr<VT1,VT2> >
1999  : public IsPadded<VT2>
2000 {};
2002 //*************************************************************************************************
2003 
2004 } // namespace blaze
2005 
2006 #endif
Pointer difference type of the Blaze library.
Header file for auxiliary alias declarations.
const ConstIterator operator--(int)
Post-decrement operator.
Definition: DVecDVecOuterExpr.h:326
static constexpr bool evaluateLeft
Compilation switch for the composite type of the left-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:122
Header file for basic type definitions.
bool operator!=(const ConstIterator &rhs) const
Inequality comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:368
typename If< Condition, T1, T2 >::Type If_t
Auxiliary alias declaration for the If class template.The If_t alias declaration provides a convenien...
Definition: If.h:109
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: DVecDVecOuterExpr.h:576
ConstIterator_t< VT1 > LeftIteratorType
ConstIterator type of the left-hand side dense matrix expression.
Definition: DVecDVecOuterExpr.h:247
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:235
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: DVecDVecOuterExpr.h:505
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:137
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: CompressedMatrix.h:3113
ConstIterator & operator++()
Pre-increment operator.
Definition: DVecDVecOuterExpr.h:294
friend const ConstIterator operator+(size_t inc, const ConstIterator &it)
Addition between an integral value and a ConstIterator.
Definition: DVecDVecOuterExpr.h:447
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:596
MultTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: DVecDVecOuterExpr.h:201
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:539
If_t< IsExpression_v< VT2 >, const VT2, const VT2 &> RightOperand
Composite type of the right-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:217
Header file for the RequiresEvaluation type trait.
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:112
ValueType value_type
Type of the underlying elements.
Definition: DVecDVecOuterExpr.h:241
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: DVecDVecOuterExpr.h:478
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
ConstIterator & operator--()
Pre-decrement operator.
Definition: DVecDVecOuterExpr.h:315
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: DVecDVecOuterExpr.h:586
Constraint on the transpose flag of vector types.
RightOperand rightOperand() const noexcept
Returns the right-hand side dense vector operand.
Definition: DVecDVecOuterExpr.h:606
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:618
ResultType_t< VT1 > RT1
Result type of the left-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:110
ReturnType operator*() const
Direct access to the element at the current iterator position.
Definition: DVecDVecOuterExpr.h:336
Header file for the IsTemporary type trait class.
ConstIterator(LeftIteratorType left, RightIteratorType right)
Constructor for the ConstIterator class.
Definition: DVecDVecOuterExpr.h:259
static constexpr bool simdEnabled
Compilation switch for the expression template evaluation strategy.
Definition: DVecDVecOuterExpr.h:474
Header file for the multiplication trait.
ResultType_t< VT2 > RT2
Result type of the right-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:111
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:346
If_t< useAssign, const ResultType, const DVecDVecOuterExpr &> CompositeType
Data type for composite expression templates.
Definition: DVecDVecOuterExpr.h:211
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
const ConstIterator operator++(int)
Post-increment operator.
Definition: DVecDVecOuterExpr.h:305
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: DVecDVecOuterExpr.h:204
#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:630
LeftIteratorType left_
Iterator to the current left-hand side element.
Definition: DVecDVecOuterExpr.h:466
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: DVecDVecOuterExpr.h:208
ConstIterator_t< VT2 > RightIteratorType
ConstIterator type of the right-hand side dense matrix expression.
Definition: DVecDVecOuterExpr.h:250
#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.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3086
Header file for all SIMD functionality.
RightOperand rhs_
Right-hand side dense vector of the multiplication expression.
Definition: DVecDVecOuterExpr.h:658
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DVecDVecOuterExpr.h:202
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:76
ConstIterator & operator-=(size_t dec)
Subtraction assignment operator.
Definition: DVecDVecOuterExpr.h:283
Header file for the IsAligned type trait.
bool operator==(const ConstIterator &rhs) const
Equality comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:357
CompositeType_t< VT2 > CT2
Composite type of the right-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:117
bool operator<(const ConstIterator &rhs) const
Less-than comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:379
static constexpr bool useAssign
Compilation switch for the serial evaluation strategy of the outer product expression.
Definition: DVecDVecOuterExpr.h:151
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:650
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:565
Constraint on the data type.
ReturnType_t< VT1 > RN1
Return type of the left-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:114
Header file for all forward declarations for expression class templates.
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:492
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:140
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:521
bool operator<=(const ConstIterator &rhs) const
Less-than comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:401
ConstIterator & operator+=(size_t inc)
Addition assignment operator.
Definition: DVecDVecOuterExpr.h:271
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, a compilation error is created.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
Header file for the HasSIMDMult type trait.
bool operator>=(const ConstIterator &rhs) const
Greater-than comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:412
DifferenceType operator-(const ConstIterator &rhs) const
Calculating the number of elements between two iterators.
Definition: DVecDVecOuterExpr.h:423
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:483
If_t< IsExpression_v< VT1 >, const VT1, const VT1 &> LeftOperand
Composite type of the left-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:214
Expression object for outer products between two dense vectors.The DVecDVecOuterExpr class represents...
Definition: DVecDVecOuterExpr.h:104
RightIteratorType right_
Iterator to the current right-hand side element.
Definition: DVecDVecOuterExpr.h:467
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
ptrdiff_t DifferenceType
Difference between two iterators.
Definition: DVecDVecOuterExpr.h:237
ConstIterator begin(size_t i) const
Returns an iterator to the first non-zero element of row i.
Definition: DVecDVecOuterExpr.h:553
CompositeType_t< VT1 > CT1
Composite type of the left-hand side dense vector expression.
Definition: DVecDVecOuterExpr.h:116
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 class template represents ...
Definition: IntegralConstant.h:101
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
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:115
typename T::ConstIterator ConstIterator_t
Alias declaration for nested ConstIterator type definitions.The ConstIterator_t alias declaration pro...
Definition: Aliases.h:110
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3081
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional vector type...
Definition: DenseVector.h:61
If_t< evaluateRight, const RT2, CT2 > RT
Type for the assignment of the right-hand side dense vector operand.
Definition: DVecDVecOuterExpr.h:223
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:203
bool operator>(const ConstIterator &rhs) const
Greater-than comparison between two ConstIterator objects.
Definition: DVecDVecOuterExpr.h:390
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:640
ElementType & ReferenceType
Reference return type.
Definition: DVecDVecOuterExpr.h:236
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:459
If_t< evaluateLeft, const RT1, CT1 > LT
Type for the assignment of the left-hand side dense vector operand.
Definition: DVecDVecOuterExpr.h:220
PointerType pointer
Pointer return type.
Definition: DVecDVecOuterExpr.h:242
#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:127
std::random_access_iterator_tag IteratorCategory
The iterator category.
Definition: DVecDVecOuterExpr.h:233
LeftOperand lhs_
Left-hand side dense vector of the multiplication expression.
Definition: DVecDVecOuterExpr.h:657
friend const ConstIterator operator+(const ConstIterator &it, size_t inc)
Addition between a ConstIterator and an integral value.
Definition: DVecDVecOuterExpr.h:435
IteratorCategory iterator_category
The iterator category.
Definition: DVecDVecOuterExpr.h:240
Iterator over the elements of the dense matrix.
Definition: DVecDVecOuterExpr.h:229
ReferenceType reference
Reference return type.
Definition: DVecDVecOuterExpr.h:243
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:113
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
SIMDTrait_t< ElementType > SIMDType
Resulting SIMD element type.
Definition: DVecDVecOuterExpr.h:205
ElementType ValueType
Type of the underlying elements.
Definition: DVecDVecOuterExpr.h:234
Constraint on the transpose flag of vector types.
Header file for the IsExpression type trait class.
Header file for the function trace functionality.