Dense.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_SUBVECTOR_DENSE_H_
36 #define _BLAZE_MATH_VIEWS_SUBVECTOR_DENSE_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <blaze/math/Aliases.h>
52 #include <blaze/math/Exception.h>
59 #include <blaze/math/shims/Clear.h>
61 #include <blaze/math/SIMD.h>
72 #include <blaze/system/CacheSize.h>
73 #include <blaze/system/Inline.h>
77 #include <blaze/util/Assert.h>
79 #include <blaze/util/DisableIf.h>
80 #include <blaze/util/EnableIf.h>
81 #include <blaze/util/mpl/If.h>
82 #include <blaze/util/mpl/Not.h>
83 #include <blaze/util/mpl/Or.h>
84 #include <blaze/util/Template.h>
85 #include <blaze/util/Types.h>
88 
89 
90 namespace blaze {
91 
92 //=================================================================================================
93 //
94 // CLASS TEMPLATE SPECIALIZATION FOR UNALIGNED DENSE SUBVECTORS
95 //
96 //=================================================================================================
97 
98 //*************************************************************************************************
106 template< typename VT // Type of the dense vector
107  , bool TF > // Transpose flag
108 class Subvector<VT,unaligned,TF,true>
109  : public View< DenseVector< Subvector<VT,unaligned,TF,true>, TF > >
110 {
111  private:
112  //**Type definitions****************************************************************************
114  using Operand = If_< IsExpression<VT>, VT, VT& >;
115  //**********************************************************************************************
116 
117  public:
118  //**Type definitions****************************************************************************
119  using This = Subvector<VT,unaligned,TF,true>;
120  using BaseType = DenseVector<This,TF>;
121  using ResultType = SubvectorTrait_<VT>;
122  using TransposeType = TransposeType_<ResultType>;
123  using ElementType = ElementType_<VT>;
124  using SIMDType = SIMDTrait_<ElementType>;
125  using ReturnType = ReturnType_<VT>;
126  using CompositeType = const Subvector&;
127 
129  using ConstReference = ConstReference_<VT>;
130 
132  using Reference = If_< IsConst<VT>, ConstReference, Reference_<VT> >;
133 
135  using ConstPointer = const ElementType*;
136 
138  using Pointer = If_< Or< IsConst<VT>, Not< HasMutableDataAccess<VT> > >, ConstPointer, ElementType* >;
139  //**********************************************************************************************
140 
141  //**SubvectorIterator class definition**********************************************************
144  template< typename IteratorType > // Type of the dense vector iterator
145  class SubvectorIterator
146  {
147  public:
148  //**Type definitions*************************************************************************
150  using IteratorCategory = typename std::iterator_traits<IteratorType>::iterator_category;
151 
153  using ValueType = typename std::iterator_traits<IteratorType>::value_type;
154 
156  using PointerType = typename std::iterator_traits<IteratorType>::pointer;
157 
159  using ReferenceType = typename std::iterator_traits<IteratorType>::reference;
160 
162  using DifferenceType = typename std::iterator_traits<IteratorType>::difference_type;
163 
164  // STL iterator requirements
165  using iterator_category = IteratorCategory;
166  using value_type = ValueType;
167  using pointer = PointerType;
168  using reference = ReferenceType;
169  using difference_type = DifferenceType;
170  //*******************************************************************************************
171 
172  //**Constructor******************************************************************************
175  inline SubvectorIterator()
176  : iterator_ ( ) // Iterator to the current subvector element
177  , isAligned_( false ) // Memory alignment flag
178  {}
179  //*******************************************************************************************
180 
181  //**Constructor******************************************************************************
187  inline SubvectorIterator( IteratorType iterator, bool isMemoryAligned )
188  : iterator_ ( iterator ) // Iterator to the current subvector element
189  , isAligned_( isMemoryAligned ) // Memory alignment flag
190  {}
191  //*******************************************************************************************
192 
193  //**Constructor******************************************************************************
198  template< typename IteratorType2 >
199  inline SubvectorIterator( const SubvectorIterator<IteratorType2>& it )
200  : iterator_ ( it.base() ) // Iterator to the current subvector element
201  , isAligned_( it.isAligned() ) // Memory alignment flag
202  {}
203  //*******************************************************************************************
204 
205  //**Addition assignment operator*************************************************************
211  inline SubvectorIterator& operator+=( size_t inc ) {
212  iterator_ += inc;
213  return *this;
214  }
215  //*******************************************************************************************
216 
217  //**Subtraction assignment operator**********************************************************
223  inline SubvectorIterator& operator-=( size_t dec ) {
224  iterator_ -= dec;
225  return *this;
226  }
227  //*******************************************************************************************
228 
229  //**Prefix increment operator****************************************************************
234  inline SubvectorIterator& operator++() {
235  ++iterator_;
236  return *this;
237  }
238  //*******************************************************************************************
239 
240  //**Postfix increment operator***************************************************************
245  inline const SubvectorIterator operator++( int ) {
246  return SubvectorIterator( iterator_++, isAligned_ );
247  }
248  //*******************************************************************************************
249 
250  //**Prefix decrement operator****************************************************************
255  inline SubvectorIterator& operator--() {
256  --iterator_;
257  return *this;
258  }
259  //*******************************************************************************************
260 
261  //**Postfix decrement operator***************************************************************
266  inline const SubvectorIterator operator--( int ) {
267  return SubvectorIterator( iterator_--, isAligned_ );
268  }
269  //*******************************************************************************************
270 
271  //**Element access operator******************************************************************
276  inline ReferenceType operator*() const {
277  return *iterator_;
278  }
279  //*******************************************************************************************
280 
281  //**Load function****************************************************************************
291  inline SIMDType load() const {
292  return loadu();
293  }
294  //*******************************************************************************************
295 
296  //**Loada function***************************************************************************
306  inline SIMDType loada() const {
307  return iterator_.loada();
308  }
309  //*******************************************************************************************
310 
311  //**Loadu function***************************************************************************
321  inline SIMDType loadu() const {
322  if( isAligned_ ) {
323  return iterator_.loada();
324  }
325  else {
326  return iterator_.loadu();
327  }
328  }
329  //*******************************************************************************************
330 
331  //**Store function***************************************************************************
342  inline void store( const SIMDType& value ) const {
343  storeu( value );
344  }
345  //*******************************************************************************************
346 
347  //**Storea function**************************************************************************
358  inline void storea( const SIMDType& value ) const {
359  iterator_.storea( value );
360  }
361  //*******************************************************************************************
362 
363  //**Storeu function**************************************************************************
374  inline void storeu( const SIMDType& value ) const {
375  if( isAligned_ ) {
376  iterator_.storea( value );
377  }
378  else {
379  iterator_.storeu( value );
380  }
381  }
382  //*******************************************************************************************
383 
384  //**Stream function**************************************************************************
395  inline void stream( const SIMDType& value ) const {
396  iterator_.stream( value );
397  }
398  //*******************************************************************************************
399 
400  //**Equality operator************************************************************************
406  inline bool operator==( const SubvectorIterator& rhs ) const {
407  return iterator_ == rhs.iterator_;
408  }
409  //*******************************************************************************************
410 
411  //**Inequality operator**********************************************************************
417  inline bool operator!=( const SubvectorIterator& rhs ) const {
418  return iterator_ != rhs.iterator_;
419  }
420  //*******************************************************************************************
421 
422  //**Less-than operator***********************************************************************
428  inline bool operator<( const SubvectorIterator& rhs ) const {
429  return iterator_ < rhs.iterator_;
430  }
431  //*******************************************************************************************
432 
433  //**Greater-than operator********************************************************************
439  inline bool operator>( const SubvectorIterator& rhs ) const {
440  return iterator_ > rhs.iterator_;
441  }
442  //*******************************************************************************************
443 
444  //**Less-or-equal-than operator**************************************************************
450  inline bool operator<=( const SubvectorIterator& rhs ) const {
451  return iterator_ <= rhs.iterator_;
452  }
453  //*******************************************************************************************
454 
455  //**Greater-or-equal-than operator***********************************************************
461  inline bool operator>=( const SubvectorIterator& rhs ) const {
462  return iterator_ >= rhs.iterator_;
463  }
464  //*******************************************************************************************
465 
466  //**Subtraction operator*********************************************************************
472  inline DifferenceType operator-( const SubvectorIterator& rhs ) const {
473  return iterator_ - rhs.iterator_;
474  }
475  //*******************************************************************************************
476 
477  //**Addition operator************************************************************************
484  friend inline const SubvectorIterator operator+( const SubvectorIterator& it, size_t inc ) {
485  return SubvectorIterator( it.iterator_ + inc, it.isAligned_ );
486  }
487  //*******************************************************************************************
488 
489  //**Addition operator************************************************************************
496  friend inline const SubvectorIterator operator+( size_t inc, const SubvectorIterator& it ) {
497  return SubvectorIterator( it.iterator_ + inc, it.isAligned_ );
498  }
499  //*******************************************************************************************
500 
501  //**Subtraction operator*********************************************************************
508  friend inline const SubvectorIterator operator-( const SubvectorIterator& it, size_t dec ) {
509  return SubvectorIterator( it.iterator_ - dec, it.isAligned_ );
510  }
511  //*******************************************************************************************
512 
513  //**Base function****************************************************************************
518  inline IteratorType base() const {
519  return iterator_;
520  }
521  //*******************************************************************************************
522 
523  //**IsAligned function***********************************************************************
528  inline bool isAligned() const {
529  return isAligned_;
530  }
531  //*******************************************************************************************
532 
533  private:
534  //**Member variables*************************************************************************
535  IteratorType iterator_;
536  bool isAligned_;
537  //*******************************************************************************************
538  };
539  //**********************************************************************************************
540 
541  //**Type definitions****************************************************************************
543  using ConstIterator = SubvectorIterator< ConstIterator_<VT> >;
544 
546  using Iterator = If_< IsConst<VT>, ConstIterator, SubvectorIterator< Iterator_<VT> > >;
547  //**********************************************************************************************
548 
549  //**Compilation flags***************************************************************************
551  enum : bool { simdEnabled = VT::simdEnabled };
552 
554  enum : bool { smpAssignable = VT::smpAssignable };
555  //**********************************************************************************************
556 
557  //**Constructors********************************************************************************
560  explicit inline Subvector( Operand vector, size_t index, size_t n );
561  // No explicitly declared copy constructor.
563  //**********************************************************************************************
564 
565  //**Destructor**********************************************************************************
566  // No explicitly declared destructor.
567  //**********************************************************************************************
568 
569  //**Data access functions***********************************************************************
572  inline Reference operator[]( size_t index );
573  inline ConstReference operator[]( size_t index ) const;
574  inline Reference at( size_t index );
575  inline ConstReference at( size_t index ) const;
576  inline Pointer data () noexcept;
577  inline ConstPointer data () const noexcept;
578  inline Iterator begin ();
579  inline ConstIterator begin () const;
580  inline ConstIterator cbegin() const;
581  inline Iterator end ();
582  inline ConstIterator end () const;
583  inline ConstIterator cend () const;
585  //**********************************************************************************************
586 
587  //**Assignment operators************************************************************************
590  inline Subvector& operator= ( const ElementType& rhs );
591  inline Subvector& operator= ( initializer_list<ElementType> list );
592  inline Subvector& operator= ( const Subvector& rhs );
593  template< typename VT2 > inline Subvector& operator= ( const Vector<VT2,TF>& rhs );
594  template< typename VT2 > inline Subvector& operator+=( const Vector<VT2,TF>& rhs );
595  template< typename VT2 > inline Subvector& operator-=( const Vector<VT2,TF>& rhs );
596  template< typename VT2 > inline Subvector& operator*=( const DenseVector<VT2,TF>& rhs );
597  template< typename VT2 > inline Subvector& operator*=( const SparseVector<VT2,TF>& rhs );
598  template< typename VT2 > inline Subvector& operator/=( const DenseVector<VT2,TF>& rhs );
599  template< typename VT2 > inline Subvector& operator%=( const Vector<VT2,TF>& rhs );
600 
601  template< typename Other >
602  inline EnableIf_< IsNumeric<Other>, Subvector >& operator*=( Other rhs );
603 
604  template< typename Other >
605  inline EnableIf_< IsNumeric<Other>, Subvector >& operator/=( Other rhs );
607  //**********************************************************************************************
608 
609  //**Utility functions***************************************************************************
612  inline Operand operand() const noexcept;
613  inline size_t offset() const noexcept;
614  inline size_t size() const noexcept;
615  inline size_t spacing() const noexcept;
616  inline size_t capacity() const noexcept;
617  inline size_t nonZeros() const;
618  inline void reset();
620  //**********************************************************************************************
621 
622  //**Numeric functions***************************************************************************
625  template< typename Other > inline Subvector& scale( const Other& scalar );
627  //**********************************************************************************************
628 
629  private:
630  //**********************************************************************************************
632  template< typename VT2 >
633  struct VectorizedAssign {
634  enum : bool { value = useOptimizedKernels &&
635  simdEnabled && VT2::simdEnabled &&
636  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value };
637  };
638  //**********************************************************************************************
639 
640  //**********************************************************************************************
642  template< typename VT2 >
643  struct VectorizedAddAssign {
644  enum : bool { value = useOptimizedKernels &&
645  simdEnabled && VT2::simdEnabled &&
646  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
647  HasSIMDAdd< ElementType, ElementType_<VT2> >::value };
648  };
649  //**********************************************************************************************
650 
651  //**********************************************************************************************
653  template< typename VT2 >
654  struct VectorizedSubAssign {
655  enum : bool { value = useOptimizedKernels &&
656  simdEnabled && VT2::simdEnabled &&
657  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
658  HasSIMDSub< ElementType, ElementType_<VT2> >::value };
659  };
660  //**********************************************************************************************
661 
662  //**********************************************************************************************
664  template< typename VT2 >
665  struct VectorizedMultAssign {
666  enum : bool { value = useOptimizedKernels &&
667  simdEnabled && VT2::simdEnabled &&
668  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
669  HasSIMDMult< ElementType, ElementType_<VT2> >::value };
670  };
671  //**********************************************************************************************
672 
673  //**********************************************************************************************
675  template< typename VT2 >
676  struct VectorizedDivAssign {
677  enum : bool { value = useOptimizedKernels &&
678  simdEnabled && VT2::simdEnabled &&
679  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
680  HasSIMDDiv< ElementType, ElementType_<VT2> >::value };
681  };
682  //**********************************************************************************************
683 
684  //**SIMD properties*****************************************************************************
686  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
687  //**********************************************************************************************
688 
689  public:
690  //**Expression template evaluation functions****************************************************
693  template< typename Other >
694  inline bool canAlias( const Other* alias ) const noexcept;
695 
696  template< typename VT2, bool AF2, bool TF2 >
697  inline bool canAlias( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept;
698 
699  template< typename Other >
700  inline bool isAliased( const Other* alias ) const noexcept;
701 
702  template< typename VT2, bool AF2, bool TF2 >
703  inline bool isAliased( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept;
704 
705  inline bool isAligned () const noexcept;
706  inline bool canSMPAssign() const noexcept;
707 
708  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
709  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
710  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
711 
712  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
713  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
714  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
715  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
716 
717  template< typename VT2 >
718  inline DisableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
719 
720  template< typename VT2 >
721  inline EnableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
722 
723  template< typename VT2 > inline void assign( const SparseVector<VT2,TF>& rhs );
724 
725  template< typename VT2 >
726  inline DisableIf_< VectorizedAddAssign<VT2> > addAssign( const DenseVector <VT2,TF>& rhs );
727 
728  template< typename VT2 >
729  inline EnableIf_< VectorizedAddAssign<VT2> > addAssign ( const DenseVector <VT2,TF>& rhs );
730 
731  template< typename VT2 > inline void addAssign( const SparseVector<VT2,TF>& rhs );
732 
733  template< typename VT2 >
734  inline DisableIf_< VectorizedSubAssign<VT2> > subAssign ( const DenseVector <VT2,TF>& rhs );
735 
736  template< typename VT2 >
737  inline EnableIf_< VectorizedSubAssign<VT2> > subAssign( const DenseVector <VT2,TF>& rhs );
738 
739  template< typename VT2 > inline void subAssign( const SparseVector<VT2,TF>& rhs );
740 
741  template< typename VT2 >
742  inline DisableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
743 
744  template< typename VT2 >
745  inline EnableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
746 
747  template< typename VT2 > inline void multAssign( const SparseVector<VT2,TF>& rhs );
748 
749  template< typename VT2 >
750  inline DisableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
751 
752  template< typename VT2 >
753  inline EnableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
755  //**********************************************************************************************
756 
757  private:
758  //**Member variables****************************************************************************
761  Operand vector_;
762  const size_t offset_;
763  const size_t size_;
764  const bool isAligned_;
765 
772  //**********************************************************************************************
773 
774  //**Friend declarations*************************************************************************
775  template< typename VT2, bool AF2, bool TF2, bool DF2 > friend class Subvector;
776  //**********************************************************************************************
777 
778  //**Compile time checks*************************************************************************
784  //**********************************************************************************************
785 };
787 //*************************************************************************************************
788 
789 
790 
791 
792 //=================================================================================================
793 //
794 // CONSTRUCTOR
795 //
796 //=================================================================================================
797 
798 //*************************************************************************************************
811 template< typename VT // Type of the dense vector
812  , bool TF > // Transpose flag
813 inline Subvector<VT,unaligned,TF,true>::Subvector( Operand vector, size_t index, size_t n )
814  : vector_ ( vector ) // The vector containing the subvector
815  , offset_ ( index ) // The offset of the subvector within the dense vector
816  , size_ ( n ) // The size of the subvector
817  , isAligned_( simdEnabled && vector.data() != nullptr && checkAlignment( data() ) )
818 {
819  if( index + n > vector.size() ) {
820  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
821  }
822 }
824 //*************************************************************************************************
825 
826 
827 
828 
829 //=================================================================================================
830 //
831 // DATA ACCESS FUNCTIONS
832 //
833 //=================================================================================================
834 
835 //*************************************************************************************************
845 template< typename VT // Type of the dense vector
846  , bool TF > // Transpose flag
848  Subvector<VT,unaligned,TF,true>::operator[]( size_t index )
849 {
850  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
851  return vector_[offset_+index];
852 }
854 //*************************************************************************************************
855 
856 
857 //*************************************************************************************************
867 template< typename VT // Type of the dense vector
868  , bool TF > // Transpose flag
870  Subvector<VT,unaligned,TF,true>::operator[]( size_t index ) const
871 {
872  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
873  return const_cast<const VT&>( vector_ )[offset_+index];
874 }
876 //*************************************************************************************************
877 
878 
879 //*************************************************************************************************
890 template< typename VT // Type of the dense vector
891  , bool TF > // Transpose flag
893  Subvector<VT,unaligned,TF,true>::at( size_t index )
894 {
895  if( index >= size() ) {
896  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
897  }
898  return (*this)[index];
899 }
901 //*************************************************************************************************
902 
903 
904 //*************************************************************************************************
915 template< typename VT // Type of the dense vector
916  , bool TF > // Transpose flag
918  Subvector<VT,unaligned,TF,true>::at( size_t index ) const
919 {
920  if( index >= size() ) {
921  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
922  }
923  return (*this)[index];
924 }
926 //*************************************************************************************************
927 
928 
929 //*************************************************************************************************
937 template< typename VT // Type of the dense vector
938  , bool TF > // Transpose flag
939 inline typename Subvector<VT,unaligned,TF,true>::Pointer
940  Subvector<VT,unaligned,TF,true>::data() noexcept
941 {
942  return vector_.data() + offset_;
943 }
945 //*************************************************************************************************
946 
947 
948 //*************************************************************************************************
956 template< typename VT // Type of the dense vector
957  , bool TF > // Transpose flag
958 inline typename Subvector<VT,unaligned,TF,true>::ConstPointer
959  Subvector<VT,unaligned,TF,true>::data() const noexcept
960 {
961  return vector_.data() + offset_;
962 }
964 //*************************************************************************************************
965 
966 
967 //*************************************************************************************************
975 template< typename VT // Type of the dense vector
976  , bool TF > // Transpose flag
979 {
980  return Iterator( vector_.begin() + offset_, isAligned_ );
981 }
983 //*************************************************************************************************
984 
985 
986 //*************************************************************************************************
994 template< typename VT // Type of the dense vector
995  , bool TF > // Transpose flag
998 {
999  return ConstIterator( vector_.cbegin() + offset_, isAligned_ );
1000 }
1002 //*************************************************************************************************
1003 
1004 
1005 //*************************************************************************************************
1013 template< typename VT // Type of the dense vector
1014  , bool TF > // Transpose flag
1017 {
1018  return ConstIterator( vector_.cbegin() + offset_, isAligned_ );
1019 }
1021 //*************************************************************************************************
1022 
1023 
1024 //*************************************************************************************************
1032 template< typename VT // Type of the dense vector
1033  , bool TF > // Transpose flag
1036 {
1037  return Iterator( vector_.begin() + offset_ + size_, isAligned_ );
1038 }
1040 //*************************************************************************************************
1041 
1042 
1043 //*************************************************************************************************
1051 template< typename VT // Type of the dense vector
1052  , bool TF > // Transpose flag
1055 {
1056  return ConstIterator( vector_.cbegin() + offset_ + size_, isAligned_ );
1057 }
1059 //*************************************************************************************************
1060 
1061 
1062 //*************************************************************************************************
1070 template< typename VT // Type of the dense vector
1071  , bool TF > // Transpose flag
1074 {
1075  return ConstIterator( vector_.cbegin() + offset_ + size_, isAligned_ );
1076 }
1078 //*************************************************************************************************
1079 
1080 
1081 
1082 
1083 //=================================================================================================
1084 //
1085 // ASSIGNMENT OPERATORS
1086 //
1087 //=================================================================================================
1088 
1089 //*************************************************************************************************
1096 template< typename VT // Type of the dense vector
1097  , bool TF > // Transpose flag
1098 inline Subvector<VT,unaligned,TF,true>&
1099  Subvector<VT,unaligned,TF,true>::operator=( const ElementType& rhs )
1100 {
1101  const size_t iend( offset_ + size_ );
1102 
1103  for( size_t i=offset_; i<iend; ++i )
1104  vector_[i] = rhs;
1105 
1106  return *this;
1107 }
1109 //*************************************************************************************************
1110 
1111 
1112 //*************************************************************************************************
1125 template< typename VT // Type of the dense vector
1126  , bool TF > // Transpose flag
1127 inline Subvector<VT,unaligned,TF,true>&
1128  Subvector<VT,unaligned,TF,true>::operator=( initializer_list<ElementType> list )
1129 {
1130  if( list.size() > size() ) {
1131  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to subvector" );
1132  }
1133 
1134  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
1135 
1136  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1137 
1138  return *this;
1139 }
1141 //*************************************************************************************************
1142 
1143 
1144 //*************************************************************************************************
1156 template< typename VT // Type of the dense vector
1157  , bool TF > // Transpose flag
1158 inline Subvector<VT,unaligned,TF,true>&
1159  Subvector<VT,unaligned,TF,true>::operator=( const Subvector& rhs )
1160 {
1163 
1164  if( &rhs == this || ( &vector_ == &rhs.vector_ && offset_ == rhs.offset_ ) )
1165  return *this;
1166 
1167  if( size() != rhs.size() ) {
1168  BLAZE_THROW_INVALID_ARGUMENT( "Subvector sizes do not match" );
1169  }
1170 
1171  if( !tryAssign( vector_, rhs, offset_ ) ) {
1172  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1173  }
1174 
1175  decltype(auto) left( derestrict( *this ) );
1176 
1177  if( rhs.canAlias( &vector_ ) ) {
1178  const ResultType tmp( rhs );
1179  smpAssign( left, tmp );
1180  }
1181  else {
1182  smpAssign( left, rhs );
1183  }
1184 
1185  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1186 
1187  return *this;
1188 }
1190 //*************************************************************************************************
1191 
1192 
1193 //*************************************************************************************************
1205 template< typename VT // Type of the dense vector
1206  , bool TF > // Transpose flag
1207 template< typename VT2 > // Type of the right-hand side vector
1208 inline Subvector<VT,unaligned,TF,true>&
1209  Subvector<VT,unaligned,TF,true>::operator=( const Vector<VT2,TF>& rhs )
1210 {
1213 
1214  if( size() != (~rhs).size() ) {
1215  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1216  }
1217 
1218  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
1219  Right right( ~rhs );
1220 
1221  if( !tryAssign( vector_, right, offset_ ) ) {
1222  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1223  }
1224 
1225  decltype(auto) left( derestrict( *this ) );
1226 
1227  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1228  const ResultType_<VT2> tmp( right );
1229  smpAssign( left, tmp );
1230  }
1231  else {
1232  if( IsSparseVector<VT2>::value )
1233  reset();
1234  smpAssign( left, right );
1235  }
1236 
1237  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1238 
1239  return *this;
1240 }
1242 //*************************************************************************************************
1243 
1244 
1245 //*************************************************************************************************
1257 template< typename VT // Type of the dense vector
1258  , bool TF > // Transpose flag
1259 template< typename VT2 > // Type of the right-hand side vector
1260 inline Subvector<VT,unaligned,TF,true>&
1261  Subvector<VT,unaligned,TF,true>::operator+=( const Vector<VT2,TF>& rhs )
1262 {
1265 
1266  if( size() != (~rhs).size() ) {
1267  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1268  }
1269 
1270  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
1271  Right right( ~rhs );
1272 
1273  if( !tryAddAssign( vector_, right, offset_ ) ) {
1274  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1275  }
1276 
1277  decltype(auto) left( derestrict( *this ) );
1278 
1279  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1280  const ResultType_<VT2> tmp( right );
1281  smpAddAssign( left, tmp );
1282  }
1283  else {
1284  smpAddAssign( left, right );
1285  }
1286 
1287  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1288 
1289  return *this;
1290 }
1292 //*************************************************************************************************
1293 
1294 
1295 //*************************************************************************************************
1307 template< typename VT // Type of the dense vector
1308  , bool TF > // Transpose flag
1309 template< typename VT2 > // Type of the right-hand side vector
1310 inline Subvector<VT,unaligned,TF,true>&
1311  Subvector<VT,unaligned,TF,true>::operator-=( const Vector<VT2,TF>& rhs )
1312 {
1315 
1316  if( size() != (~rhs).size() ) {
1317  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1318  }
1319 
1320  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
1321  Right right( ~rhs );
1322 
1323  if( !trySubAssign( vector_, right, offset_ ) ) {
1324  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1325  }
1326 
1327  decltype(auto) left( derestrict( *this ) );
1328 
1329  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1330  const ResultType_<VT2> tmp( right );
1331  smpSubAssign( left, tmp );
1332  }
1333  else {
1334  smpSubAssign( left, right );
1335  }
1336 
1337  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1338 
1339  return *this;
1340 }
1342 //*************************************************************************************************
1343 
1344 
1345 //*************************************************************************************************
1358 template< typename VT // Type of the dense vector
1359  , bool TF > // Transpose flag
1360 template< typename VT2 > // Type of the right-hand side dense vector
1361 inline Subvector<VT,unaligned,TF,true>&
1362  Subvector<VT,unaligned,TF,true>::operator*=( const DenseVector<VT2,TF>& rhs )
1363 {
1366 
1367  if( size() != (~rhs).size() ) {
1368  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1369  }
1370 
1371  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
1372  Right right( ~rhs );
1373 
1374  if( !tryMultAssign( vector_, right, offset_ ) ) {
1375  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1376  }
1377 
1378  decltype(auto) left( derestrict( *this ) );
1379 
1380  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1381  const ResultType_<VT2> tmp( right );
1382  smpMultAssign( left, tmp );
1383  }
1384  else {
1385  smpMultAssign( left, right );
1386  }
1387 
1388  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1389 
1390  return *this;
1391 }
1393 //*************************************************************************************************
1394 
1395 
1396 //*************************************************************************************************
1409 template< typename VT // Type of the dense vector
1410  , bool TF > // Transpose flag
1411 template< typename VT2 > // Type of the right-hand side sparse vector
1412 inline Subvector<VT,unaligned,TF,true>&
1413  Subvector<VT,unaligned,TF,true>::operator*=( const SparseVector<VT2,TF>& rhs )
1414 {
1417 
1418  if( size() != (~rhs).size() ) {
1419  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1420  }
1421 
1422  const ResultType tmp( *this * (~rhs) );
1423 
1424  if( !tryAssign( vector_, tmp, offset_ ) ) {
1425  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1426  }
1427 
1428  decltype(auto) left( derestrict( *this ) );
1429 
1430  smpAssign( left, tmp );
1431 
1432  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1433 
1434  return *this;
1435 }
1437 //*************************************************************************************************
1438 
1439 
1440 //*************************************************************************************************
1452 template< typename VT // Type of the dense vector
1453  , bool TF > // Transpose flag
1454 template< typename VT2 > // Type of the right-hand side dense vector
1455 inline Subvector<VT,unaligned,TF,true>&
1456  Subvector<VT,unaligned,TF,true>::operator/=( const DenseVector<VT2,TF>& rhs )
1457 {
1460 
1461  if( size() != (~rhs).size() ) {
1462  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1463  }
1464 
1465  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
1466  Right right( ~rhs );
1467 
1468  if( !tryDivAssign( vector_, right, offset_ ) ) {
1469  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1470  }
1471 
1472  decltype(auto) left( derestrict( *this ) );
1473 
1474  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1475  const ResultType_<VT2> tmp( right );
1476  smpDivAssign( left, tmp );
1477  }
1478  else {
1479  smpDivAssign( left, right );
1480  }
1481 
1482  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1483 
1484  return *this;
1485 }
1487 //*************************************************************************************************
1488 
1489 
1490 //*************************************************************************************************
1503 template< typename VT // Type of the dense vector
1504  , bool TF > // Transpose flag
1505 template< typename VT2 > // Type of the right-hand side vector
1506 inline Subvector<VT,unaligned,TF,true>&
1507  Subvector<VT,unaligned,TF,true>::operator%=( const Vector<VT2,TF>& rhs )
1508 {
1509  using blaze::assign;
1510 
1513 
1514  using CrossType = CrossTrait_< ResultType, ResultType_<VT2> >;
1515 
1519 
1520  if( size() != 3UL || (~rhs).size() != 3UL ) {
1521  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
1522  }
1523 
1524  const CrossType tmp( *this % (~rhs) );
1525 
1526  if( !tryAssign( vector_, tmp, offset_ ) ) {
1527  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1528  }
1529 
1530  decltype(auto) left( derestrict( *this ) );
1531 
1532  assign( left, tmp );
1533 
1534  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1535 
1536  return *this;
1537 }
1539 //*************************************************************************************************
1540 
1541 
1542 //*************************************************************************************************
1550 template< typename VT // Type of the dense vector
1551  , bool TF > // Transpose flag
1552 template< typename Other > // Data type of the right-hand side scalar
1553 inline EnableIf_< IsNumeric<Other>, Subvector<VT,unaligned,TF,true> >&
1554  Subvector<VT,unaligned,TF,true>::operator*=( Other rhs )
1555 {
1556  decltype(auto) left( derestrict( *this ) );
1557  smpAssign( left, (*this) * rhs );
1558 
1559  return *this;
1560 }
1562 //*************************************************************************************************
1563 
1564 
1565 //*************************************************************************************************
1575 template< typename VT // Type of the dense vector
1576  , bool TF > // Transpose flag
1577 template< typename Other > // Data type of the right-hand side scalar
1578 inline EnableIf_< IsNumeric<Other>, Subvector<VT,unaligned,TF,true> >&
1579  Subvector<VT,unaligned,TF,true>::operator/=( Other rhs )
1580 {
1581  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1582 
1583  decltype(auto) left( derestrict( *this ) );
1584  smpAssign( left, (*this) / rhs );
1585 
1586  return *this;
1587 }
1589 //*************************************************************************************************
1590 
1591 
1592 
1593 
1594 //=================================================================================================
1595 //
1596 // UTILITY FUNCTIONS
1597 //
1598 //=================================================================================================
1599 
1600 //*************************************************************************************************
1606 template< typename VT // Type of the dense vector
1607  , bool TF > // Transpose flag
1608 inline typename Subvector<VT,unaligned,TF,true>::Operand
1609  Subvector<VT,unaligned,TF,true>::operand() const noexcept
1610 {
1611  return vector_;
1612 }
1614 //*************************************************************************************************
1615 
1616 
1617 //*************************************************************************************************
1623 template< typename VT // Type of the dense vector
1624  , bool TF > // Transpose flag
1625 inline size_t Subvector<VT,unaligned,TF,true>::offset() const noexcept
1626 {
1627  return offset_;
1628 }
1630 //*************************************************************************************************
1631 
1632 
1633 //*************************************************************************************************
1639 template< typename VT // Type of the dense vector
1640  , bool TF > // Transpose flag
1641 inline size_t Subvector<VT,unaligned,TF,true>::size() const noexcept
1642 {
1643  return size_;
1644 }
1646 //*************************************************************************************************
1647 
1648 
1649 //*************************************************************************************************
1658 template< typename VT // Type of the dense vector
1659  , bool TF > // Transpose flag
1660 inline size_t Subvector<VT,unaligned,TF,true>::spacing() const noexcept
1661 {
1662  return vector_.spacing() - offset_;
1663 }
1665 //*************************************************************************************************
1666 
1667 
1668 //*************************************************************************************************
1674 template< typename VT // Type of the dense vector
1675  , bool TF > // Transpose flag
1676 inline size_t Subvector<VT,unaligned,TF,true>::capacity() const noexcept
1677 {
1678  return vector_.capacity() - offset_;
1679 }
1681 //*************************************************************************************************
1682 
1683 
1684 //*************************************************************************************************
1693 template< typename VT // Type of the dense vector
1694  , bool TF > // Transpose flag
1695 inline size_t Subvector<VT,unaligned,TF,true>::nonZeros() const
1696 {
1697  size_t nonzeros( 0 );
1698 
1699  const size_t iend( offset_ + size_ );
1700  for( size_t i=offset_; i<iend; ++i ) {
1701  if( !isDefault( vector_[i] ) )
1702  ++nonzeros;
1703  }
1704 
1705  return nonzeros;
1706 }
1708 //*************************************************************************************************
1709 
1710 
1711 //*************************************************************************************************
1717 template< typename VT // Type of the dense vector
1718  , bool TF > // Transpose flag
1720 {
1721  using blaze::clear;
1722 
1723  const size_t iend( offset_ + size_ );
1724  for( size_t i=offset_; i<iend; ++i )
1725  clear( vector_[i] );
1726 }
1728 //*************************************************************************************************
1729 
1730 
1731 
1732 
1733 //=================================================================================================
1734 //
1735 // NUMERIC FUNCTIONS
1736 //
1737 //=================================================================================================
1738 
1739 //*************************************************************************************************
1750 template< typename VT // Type of the dense vector
1751  , bool TF > // Transpose flag
1752 template< typename Other > // Data type of the scalar value
1753 inline Subvector<VT,unaligned,TF,true>&
1754  Subvector<VT,unaligned,TF,true>::scale( const Other& scalar )
1755 {
1756  const size_t iend( offset_ + size_ );
1757  for( size_t i=offset_; i<iend; ++i )
1758  vector_[i] *= scalar;
1759  return *this;
1760 }
1762 //*************************************************************************************************
1763 
1764 
1765 
1766 
1767 //=================================================================================================
1768 //
1769 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1770 //
1771 //=================================================================================================
1772 
1773 //*************************************************************************************************
1784 template< typename VT // Type of the dense vector
1785  , bool TF > // Transpose flag
1786 template< typename Other > // Data type of the foreign expression
1787 inline bool Subvector<VT,unaligned,TF,true>::canAlias( const Other* alias ) const noexcept
1788 {
1789  return vector_.isAliased( alias );
1790 }
1792 //*************************************************************************************************
1793 
1794 
1795 //*************************************************************************************************
1806 template< typename VT // Type of the dense vector
1807  , bool TF > // Transpose flag
1808 template< typename VT2 // Data type of the foreign dense subvector
1809  , bool AF2 // Alignment flag of the foreign dense subvector
1810  , bool TF2 > // Transpose flag of the foreign dense subvector
1811 inline bool Subvector<VT,unaligned,TF,true>::canAlias( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept
1812 {
1813  return ( vector_.isAliased( &alias->vector_ ) &&
1814  ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
1815 }
1817 //*************************************************************************************************
1818 
1819 
1820 //*************************************************************************************************
1831 template< typename VT // Type of the dense vector
1832  , bool TF > // Transpose flag
1833 template< typename Other > // Data type of the foreign expression
1834 inline bool Subvector<VT,unaligned,TF,true>::isAliased( const Other* alias ) const noexcept
1835 {
1836  return vector_.isAliased( alias );
1837 }
1839 //*************************************************************************************************
1840 
1841 
1842 //*************************************************************************************************
1853 template< typename VT // Type of the dense vector
1854  , bool TF > // Transpose flag
1855 template< typename VT2 // Data type of the foreign dense subvector
1856  , bool AF2 // Alignment flag of the foreign dense subvector
1857  , bool TF2 > // Transpose flag of the foreign dense subvector
1858 inline bool Subvector<VT,unaligned,TF,true>::isAliased( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept
1859 {
1860  return ( vector_.isAliased( &alias->vector_ ) &&
1861  ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
1862 }
1864 //*************************************************************************************************
1865 
1866 
1867 //*************************************************************************************************
1877 template< typename VT // Type of the dense vector
1878  , bool TF > // Transpose flag
1879 inline bool Subvector<VT,unaligned,TF,true>::isAligned() const noexcept
1880 {
1881  return isAligned_;
1882 }
1884 //*************************************************************************************************
1885 
1886 
1887 //*************************************************************************************************
1898 template< typename VT // Type of the dense vector
1899  , bool TF > // Transpose flag
1900 inline bool Subvector<VT,unaligned,TF,true>::canSMPAssign() const noexcept
1901 {
1902  return ( size() > SMP_DVECASSIGN_THRESHOLD );
1903 }
1905 //*************************************************************************************************
1906 
1907 
1908 //*************************************************************************************************
1922 template< typename VT // Type of the dense vector
1923  , bool TF > // Transpose flag
1924 BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true>::SIMDType
1925  Subvector<VT,unaligned,TF,true>::load( size_t index ) const noexcept
1926 {
1927  if( isAligned_ )
1928  return loada( index );
1929  else
1930  return loadu( index );
1931 }
1933 //*************************************************************************************************
1934 
1935 
1936 //*************************************************************************************************
1950 template< typename VT // Type of the dense vector
1951  , bool TF > // Transpose flag
1952 BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true>::SIMDType
1953  Subvector<VT,unaligned,TF,true>::loada( size_t index ) const noexcept
1954 {
1956 
1957  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
1958  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
1959  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
1960 
1961  return vector_.loada( offset_+index );
1962 }
1964 //*************************************************************************************************
1965 
1966 
1967 //*************************************************************************************************
1981 template< typename VT // Type of the dense vector
1982  , bool TF > // Transpose flag
1983 BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true>::SIMDType
1984  Subvector<VT,unaligned,TF,true>::loadu( size_t index ) const noexcept
1985 {
1987 
1988  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
1989  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
1990  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
1991 
1992  return vector_.loadu( offset_+index );
1993 }
1995 //*************************************************************************************************
1996 
1997 
1998 //*************************************************************************************************
2013 template< typename VT // Type of the dense vector
2014  , bool TF > // Transpose flag
2016  Subvector<VT,unaligned,TF,true>::store( size_t index, const SIMDType& value ) noexcept
2017 {
2018  if( isAligned_ )
2019  storea( index, value );
2020  else
2021  storeu( index, value );
2022 }
2024 //*************************************************************************************************
2025 
2026 
2027 //*************************************************************************************************
2042 template< typename VT // Type of the dense vector
2043  , bool TF > // Transpose flag
2045  Subvector<VT,unaligned,TF,true>::storea( size_t index, const SIMDType& value ) noexcept
2046 {
2048 
2049  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
2050  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
2051  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
2052 
2053  vector_.storea( offset_+index, value );
2054 }
2056 //*************************************************************************************************
2057 
2058 
2059 //*************************************************************************************************
2074 template< typename VT // Type of the dense vector
2075  , bool TF > // Transpose flag
2077  Subvector<VT,unaligned,TF,true>::storeu( size_t index, const SIMDType& value ) noexcept
2078 {
2080 
2081  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
2082  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
2083  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
2084 
2085  vector_.storeu( offset_+index, value );
2086 }
2088 //*************************************************************************************************
2089 
2090 
2091 //*************************************************************************************************
2106 template< typename VT // Type of the dense vector
2107  , bool TF > // Transpose flag
2109  Subvector<VT,unaligned,TF,true>::stream( size_t index, const SIMDType& value ) noexcept
2110 {
2112 
2113  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
2114  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
2115  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
2116 
2117  if( isAligned_ )
2118  vector_.stream( offset_+index, value );
2119  else
2120  vector_.storeu( offset_+index, value );
2121 }
2123 //*************************************************************************************************
2124 
2125 
2126 //*************************************************************************************************
2138 template< typename VT // Type of the dense vector
2139  , bool TF > // Transpose flag
2140 template< typename VT2 > // Type of the right-hand side dense vector
2141 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
2142  Subvector<VT,unaligned,TF,true>::assign( const DenseVector<VT2,TF>& rhs )
2143 {
2144  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2145 
2146  const size_t ipos( size() & size_t(-2) );
2147  for( size_t i=0UL; i<ipos; i+=2UL ) {
2148  vector_[offset_+i ] = (~rhs)[i ];
2149  vector_[offset_+i+1UL] = (~rhs)[i+1UL];
2150  }
2151  if( ipos < size() ) {
2152  vector_[offset_+ipos] = (~rhs)[ipos];
2153  }
2154 }
2156 //*************************************************************************************************
2157 
2158 
2159 //*************************************************************************************************
2171 template< typename VT // Type of the dense vector
2172  , bool TF > // Transpose flag
2173 template< typename VT2 > // Type of the right-hand side dense vector
2174 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
2175  Subvector<VT,unaligned,TF,true>::assign( const DenseVector<VT2,TF>& rhs )
2176 {
2178 
2179  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2180 
2181  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2182  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2183 
2184  size_t i( 0UL );
2185  Iterator left( begin() );
2186  ConstIterator_<VT2> right( (~rhs).begin() );
2187 
2188  if( useStreaming && isAligned_ &&
2189  ( size_ > ( cacheSize/( sizeof(ElementType) * 3UL ) ) ) &&
2190  !(~rhs).isAliased( &vector_ ) )
2191  {
2192  for( ; i<ipos; i+=SIMDSIZE ) {
2193  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2194  }
2195  for( ; i<size_; ++i ) {
2196  *left = *right;
2197  }
2198  }
2199  else
2200  {
2201  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2202  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2203  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2204  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2205  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2206  }
2207  for( ; i<ipos; i+=SIMDSIZE ) {
2208  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2209  }
2210  for( ; i<size_; ++i ) {
2211  *left = *right; ++left; ++right;
2212  }
2213  }
2214 }
2216 //*************************************************************************************************
2217 
2218 
2219 //*************************************************************************************************
2231 template< typename VT // Type of the dense vector
2232  , bool TF > // Transpose flag
2233 template< typename VT2 > // Type of the right-hand side sparse vector
2234 inline void Subvector<VT,unaligned,TF,true>::assign( const SparseVector<VT2,TF>& rhs )
2235 {
2236  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2237 
2238  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2239  vector_[offset_+element->index()] = element->value();
2240 }
2242 //*************************************************************************************************
2243 
2244 
2245 //*************************************************************************************************
2257 template< typename VT // Type of the dense vector
2258  , bool TF > // Transpose flag
2259 template< typename VT2 > // Type of the right-hand side dense vector
2260 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
2261  Subvector<VT,unaligned,TF,true>::addAssign( const DenseVector<VT2,TF>& rhs )
2262 {
2263  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2264 
2265  const size_t ipos( size() & size_t(-2) );
2266  for( size_t i=0UL; i<ipos; i+=2UL ) {
2267  vector_[offset_+i ] += (~rhs)[i ];
2268  vector_[offset_+i+1UL] += (~rhs)[i+1UL];
2269  }
2270  if( ipos < size() ) {
2271  vector_[offset_+ipos] += (~rhs)[ipos];
2272  }
2273 }
2275 //*************************************************************************************************
2276 
2277 
2278 //*************************************************************************************************
2290 template< typename VT // Type of the dense vector
2291  , bool TF > // Transpose flag
2292 template< typename VT2 > // Type of the right-hand side dense vector
2293 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
2294  Subvector<VT,unaligned,TF,true>::addAssign( const DenseVector<VT2,TF>& rhs )
2295 {
2297 
2298  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2299 
2300  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2301  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2302 
2303  size_t i( 0UL );
2304  Iterator left( begin() );
2305  ConstIterator_<VT2> right( (~rhs).begin() );
2306 
2307  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2308  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2309  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2310  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2311  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2312  }
2313  for( ; i<ipos; i+=SIMDSIZE ) {
2314  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2315  }
2316  for( ; i<size_; ++i ) {
2317  *left += *right; ++left; ++right;
2318  }
2319 }
2321 //*************************************************************************************************
2322 
2323 
2324 //*************************************************************************************************
2336 template< typename VT // Type of the dense vector
2337  , bool TF > // Transpose flag
2338 template< typename VT2 > // Type of the right-hand side sparse vector
2339 inline void Subvector<VT,unaligned,TF,true>::addAssign( const SparseVector<VT2,TF>& rhs )
2340 {
2341  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2342 
2343  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2344  vector_[offset_+element->index()] += element->value();
2345 }
2347 //*************************************************************************************************
2348 
2349 
2350 //*************************************************************************************************
2362 template< typename VT // Type of the dense vector
2363  , bool TF > // Transpose flag
2364 template< typename VT2 > // Type of the right-hand side dense vector
2365 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
2366  Subvector<VT,unaligned,TF,true>::subAssign( const DenseVector<VT2,TF>& rhs )
2367 {
2368  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2369 
2370  const size_t ipos( size() & size_t(-2) );
2371  for( size_t i=0UL; i<ipos; i+=2UL ) {
2372  vector_[offset_+i ] -= (~rhs)[i ];
2373  vector_[offset_+i+1UL] -= (~rhs)[i+1UL];
2374  }
2375  if( ipos < size() ) {
2376  vector_[offset_+ipos] -= (~rhs)[ipos];
2377  }
2378 }
2380 //*************************************************************************************************
2381 
2382 
2383 //*************************************************************************************************
2395 template< typename VT // Type of the dense vector
2396  , bool TF > // Transpose flag
2397 template< typename VT2 > // Type of the right-hand side dense vector
2398 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
2399  Subvector<VT,unaligned,TF,true>::subAssign( const DenseVector<VT2,TF>& rhs )
2400 {
2402 
2403  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2404 
2405  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2406  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2407 
2408  size_t i( 0UL );
2409  Iterator left( begin() );
2410  ConstIterator_<VT2> right( (~rhs).begin() );
2411 
2412  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2413  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2414  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2415  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2416  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2417  }
2418  for( ; i<ipos; i+=SIMDSIZE ) {
2419  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2420  }
2421  for( ; i<size_; ++i ) {
2422  *left -= *right; ++left; ++right;
2423  }
2424 }
2426 //*************************************************************************************************
2427 
2428 
2429 //*************************************************************************************************
2441 template< typename VT // Type of the dense vector
2442  , bool TF > // Transpose flag
2443 template< typename VT2 > // Type of the right-hand side sparse vector
2444 inline void Subvector<VT,unaligned,TF,true>::subAssign( const SparseVector<VT2,TF>& rhs )
2445 {
2446  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2447 
2448  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2449  vector_[offset_+element->index()] -= element->value();
2450 }
2452 //*************************************************************************************************
2453 
2454 
2455 //*************************************************************************************************
2467 template< typename VT // Type of the dense vector
2468  , bool TF > // Transpose flag
2469 template< typename VT2 > // Type of the right-hand side dense vector
2470 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
2471  Subvector<VT,unaligned,TF,true>::multAssign( const DenseVector<VT2,TF>& rhs )
2472 {
2473  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2474 
2475  const size_t ipos( size() & size_t(-2) );
2476  for( size_t i=0UL; i<ipos; i+=2UL ) {
2477  vector_[offset_+i ] *= (~rhs)[i ];
2478  vector_[offset_+i+1UL] *= (~rhs)[i+1UL];
2479  }
2480  if( ipos < size() ) {
2481  vector_[offset_+ipos] *= (~rhs)[ipos];
2482  }
2483 }
2485 //*************************************************************************************************
2486 
2487 
2488 //*************************************************************************************************
2500 template< typename VT // Type of the dense vector
2501  , bool TF > // Transpose flag
2502 template< typename VT2 > // Type of the right-hand side dense vector
2503 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
2504  Subvector<VT,unaligned,TF,true>::multAssign( const DenseVector<VT2,TF>& rhs )
2505 {
2507 
2508  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2509 
2510  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2511  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2512 
2513  size_t i( 0UL );
2514  Iterator left( begin() );
2515  ConstIterator_<VT2> right( (~rhs).begin() );
2516 
2517  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2518  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2519  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2520  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2521  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2522  }
2523  for( ; i<ipos; i+=SIMDSIZE ) {
2524  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2525  }
2526  for( ; i<size_; ++i ) {
2527  *left *= *right; ++left; ++right;
2528  }
2529 }
2531 //*************************************************************************************************
2532 
2533 
2534 //*************************************************************************************************
2546 template< typename VT // Type of the dense vector
2547  , bool TF > // Transpose flag
2548 template< typename VT2 > // Type of the right-hand side sparse vector
2549 inline void Subvector<VT,unaligned,TF,true>::multAssign( const SparseVector<VT2,TF>& rhs )
2550 {
2551  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2552 
2553  const ResultType tmp( serial( *this ) );
2554 
2555  reset();
2556 
2557  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2558  vector_[offset_+element->index()] = tmp[element->index()] * element->value();
2559 }
2561 //*************************************************************************************************
2562 
2563 
2564 //*************************************************************************************************
2576 template< typename VT // Type of the dense vector
2577  , bool TF > // Transpose flag
2578 template< typename VT2 > // Type of the right-hand side dense vector
2579 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
2580  Subvector<VT,unaligned,TF,true>::divAssign( const DenseVector<VT2,TF>& rhs )
2581 {
2582  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2583 
2584  const size_t ipos( size() & size_t(-2) );
2585  for( size_t i=0UL; i<ipos; i+=2UL ) {
2586  vector_[offset_+i ] /= (~rhs)[i ];
2587  vector_[offset_+i+1UL] /= (~rhs)[i+1UL];
2588  }
2589  if( ipos < size() ) {
2590  vector_[offset_+ipos] /= (~rhs)[ipos];
2591  }
2592 }
2594 //*************************************************************************************************
2595 
2596 
2597 //*************************************************************************************************
2609 template< typename VT // Type of the dense vector
2610  , bool TF > // Transpose flag
2611 template< typename VT2 > // Type of the right-hand side dense vector
2612 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
2613  Subvector<VT,unaligned,TF,true>::divAssign( const DenseVector<VT2,TF>& rhs )
2614 {
2616 
2617  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2618 
2619  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2620  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2621 
2622  size_t i( 0UL );
2623  Iterator left( begin() );
2624  ConstIterator_<VT2> right( (~rhs).begin() );
2625 
2626  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2627  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2628  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2629  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2630  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2631  }
2632  for( ; i<ipos; i+=SIMDSIZE ) {
2633  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2634  }
2635  for( ; i<size_; ++i ) {
2636  *left /= *right; ++left; ++right;
2637  }
2638 }
2640 //*************************************************************************************************
2641 
2642 
2643 
2644 
2645 
2646 
2647 
2648 
2649 //=================================================================================================
2650 //
2651 // CLASS TEMPLATE SPECIALIZATION FOR ALIGNED DENSE SUBVECTORS
2652 //
2653 //=================================================================================================
2654 
2655 //*************************************************************************************************
2663 template< typename VT // Type of the dense vector
2664  , bool TF > // Transpose flag
2665 class Subvector<VT,aligned,TF,true>
2666  : public View< DenseVector< Subvector<VT,aligned,TF,true>, TF > >
2667 {
2668  private:
2669  //**Type definitions****************************************************************************
2671  using Operand = If_< IsExpression<VT>, VT, VT& >;
2672  //**********************************************************************************************
2673 
2674  public:
2675  //**Type definitions****************************************************************************
2676  using This = Subvector<VT,aligned,TF,true>;
2677  using BaseType = DenseVector<This,TF>;
2678  using ResultType = SubvectorTrait_<VT>;
2679  using TransposeType = TransposeType_<ResultType>;
2680  using ElementType = ElementType_<VT>;
2681  using SIMDType = SIMDTrait_<ElementType>;
2682  using ReturnType = ReturnType_<VT>;
2683  using CompositeType = const Subvector&;
2684 
2686  using ConstReference = ConstReference_<VT>;
2687 
2689  using Reference = If_< IsConst<VT>, ConstReference, Reference_<VT> >;
2690 
2692  using ConstPointer = const ElementType*;
2693 
2695  using Pointer = If_< Or< IsConst<VT>, Not< HasMutableDataAccess<VT> > >, ConstPointer, ElementType* >;
2696 
2698  using ConstIterator = ConstIterator_<VT>;
2699 
2701  using Iterator = If_< IsConst<VT>, ConstIterator, Iterator_<VT> >;
2702  //**********************************************************************************************
2703 
2704  //**Compilation flags***************************************************************************
2706  enum : bool { simdEnabled = VT::simdEnabled };
2707 
2709  enum : bool { smpAssignable = VT::smpAssignable };
2710  //**********************************************************************************************
2711 
2712  //**Constructors********************************************************************************
2715  explicit inline Subvector( Operand vector, size_t index, size_t n );
2716  // No explicitly declared copy constructor.
2718  //**********************************************************************************************
2719 
2720  //**Destructor**********************************************************************************
2721  // No explicitly declared destructor.
2722  //**********************************************************************************************
2723 
2724  //**Data access functions***********************************************************************
2727  inline Reference operator[]( size_t index );
2728  inline ConstReference operator[]( size_t index ) const;
2729  inline Reference at( size_t index );
2730  inline ConstReference at( size_t index ) const;
2731  inline Pointer data () noexcept;
2732  inline ConstPointer data () const noexcept;
2733  inline Iterator begin ();
2734  inline ConstIterator begin () const;
2735  inline ConstIterator cbegin() const;
2736  inline Iterator end ();
2737  inline ConstIterator end () const;
2738  inline ConstIterator cend () const;
2740  //**********************************************************************************************
2741 
2742  //**Assignment operators************************************************************************
2745  inline Subvector& operator= ( const ElementType& rhs );
2746  inline Subvector& operator= ( initializer_list<ElementType> list );
2747  inline Subvector& operator= ( const Subvector& rhs );
2748  template< typename VT2 > inline Subvector& operator= ( const Vector<VT2,TF>& rhs );
2749  template< typename VT2 > inline Subvector& operator+=( const Vector<VT2,TF>& rhs );
2750  template< typename VT2 > inline Subvector& operator-=( const Vector<VT2,TF>& rhs );
2751  template< typename VT2 > inline Subvector& operator*=( const DenseVector<VT2,TF>& rhs );
2752  template< typename VT2 > inline Subvector& operator*=( const SparseVector<VT2,TF>& rhs );
2753  template< typename VT2 > inline Subvector& operator/=( const DenseVector<VT2,TF>& rhs );
2754  template< typename VT2 > inline Subvector& operator%=( const Vector<VT2,TF>& rhs );
2755 
2756  template< typename Other >
2757  inline EnableIf_< IsNumeric<Other>, Subvector >& operator*=( Other rhs );
2758 
2759  template< typename Other >
2760  inline EnableIf_< IsNumeric<Other>, Subvector >& operator/=( Other rhs );
2762  //**********************************************************************************************
2763 
2764  //**Utility functions***************************************************************************
2767  inline Operand operand() const noexcept;
2768  inline size_t offset() const noexcept;
2769  inline size_t size() const noexcept;
2770  inline size_t spacing() const noexcept;
2771  inline size_t capacity() const noexcept;
2772  inline size_t nonZeros() const;
2773  inline void reset();
2775  //**********************************************************************************************
2776 
2777  //**Numeric functions***************************************************************************
2780  template< typename Other > inline Subvector& scale( const Other& scalar );
2782  //**********************************************************************************************
2783 
2784  private:
2785  //**********************************************************************************************
2787  template< typename VT2 >
2788  struct VectorizedAssign {
2789  enum : bool { value = useOptimizedKernels &&
2790  simdEnabled && VT2::simdEnabled &&
2791  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value };
2792  };
2793  //**********************************************************************************************
2794 
2795  //**********************************************************************************************
2797  template< typename VT2 >
2798  struct VectorizedAddAssign {
2799  enum : bool { value = useOptimizedKernels &&
2800  simdEnabled && VT2::simdEnabled &&
2801  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2802  HasSIMDAdd< ElementType, ElementType_<VT2> >::value };
2803  };
2804  //**********************************************************************************************
2805 
2806  //**********************************************************************************************
2808  template< typename VT2 >
2809  struct VectorizedSubAssign {
2810  enum : bool { value = useOptimizedKernels &&
2811  simdEnabled && VT2::simdEnabled &&
2812  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2813  HasSIMDSub< ElementType, ElementType_<VT2> >::value };
2814  };
2815  //**********************************************************************************************
2816 
2817  //**********************************************************************************************
2819  template< typename VT2 >
2820  struct VectorizedMultAssign {
2821  enum : bool { value = useOptimizedKernels &&
2822  simdEnabled && VT2::simdEnabled &&
2823  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2824  HasSIMDMult< ElementType, ElementType_<VT2> >::value };
2825  };
2826  //**********************************************************************************************
2827 
2828  //**********************************************************************************************
2830  template< typename VT2 >
2831  struct VectorizedDivAssign {
2832  enum : bool { value = useOptimizedKernels &&
2833  simdEnabled && VT2::simdEnabled &&
2834  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2835  HasSIMDDiv< ElementType, ElementType_<VT2> >::value };
2836  };
2837  //**********************************************************************************************
2838 
2839  //**SIMD properties*****************************************************************************
2841  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
2842  //**********************************************************************************************
2843 
2844  public:
2845  //**Expression template evaluation functions****************************************************
2848  template< typename Other >
2849  inline bool canAlias( const Other* alias ) const noexcept;
2850 
2851  template< typename VT2, bool AF2, bool TF2 >
2852  inline bool canAlias( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept;
2853 
2854  template< typename Other >
2855  inline bool isAliased( const Other* alias ) const noexcept;
2856 
2857  template< typename VT2, bool AF2, bool TF2 >
2858  inline bool isAliased( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept;
2859 
2860  inline bool isAligned () const noexcept;
2861  inline bool canSMPAssign() const noexcept;
2862 
2863  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
2864  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
2865  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
2866 
2867  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
2868  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
2869  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
2870  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
2871 
2872  template< typename VT2 >
2873  inline DisableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
2874 
2875  template< typename VT2 >
2876  inline EnableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
2877 
2878  template< typename VT2 > inline void assign( const SparseVector<VT2,TF>& rhs );
2879 
2880  template< typename VT2 >
2881  inline DisableIf_< VectorizedAddAssign<VT2> > addAssign( const DenseVector <VT2,TF>& rhs );
2882 
2883  template< typename VT2 >
2884  inline EnableIf_< VectorizedAddAssign<VT2> > addAssign ( const DenseVector <VT2,TF>& rhs );
2885 
2886  template< typename VT2 > inline void addAssign( const SparseVector<VT2,TF>& rhs );
2887 
2888  template< typename VT2 >
2889  inline DisableIf_< VectorizedSubAssign<VT2> > subAssign ( const DenseVector <VT2,TF>& rhs );
2890 
2891  template< typename VT2 >
2892  inline EnableIf_< VectorizedSubAssign<VT2> > subAssign( const DenseVector <VT2,TF>& rhs );
2893 
2894  template< typename VT2 > inline void subAssign( const SparseVector<VT2,TF>& rhs );
2895 
2896  template< typename VT2 >
2897  inline DisableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
2898 
2899  template< typename VT2 >
2900  inline EnableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
2901 
2902  template< typename VT2 > inline void multAssign( const SparseVector<VT2,TF>& rhs );
2903 
2904  template< typename VT2 >
2905  inline DisableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
2906 
2907  template< typename VT2 >
2908  inline EnableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
2910  //**********************************************************************************************
2911 
2912  private:
2913  //**Member variables****************************************************************************
2916  Operand vector_;
2917  const size_t offset_;
2918  const size_t size_;
2919 
2920  //**********************************************************************************************
2921 
2922  //**Friend declarations*************************************************************************
2923  template< typename VT2, bool AF2, bool TF2, bool DF2 > friend class Subvector;
2924  //**********************************************************************************************
2925 
2926  //**Compile time checks*************************************************************************
2932  //**********************************************************************************************
2933 };
2935 //*************************************************************************************************
2936 
2937 
2938 
2939 
2940 //=================================================================================================
2941 //
2942 // CONSTRUCTOR
2943 //
2944 //=================================================================================================
2945 
2946 //*************************************************************************************************
2959 template< typename VT // Type of the dense vector
2960  , bool TF > // Transpose flag
2961 inline Subvector<VT,aligned,TF,true>::Subvector( Operand vector, size_t index, size_t n )
2962  : vector_( vector ) // The vector containing the subvector
2963  , offset_( index ) // The offset of the subvector within the dense vector
2964  , size_ ( n ) // The size of the subvector
2965 {
2966  if( index + n > vector.size() ) {
2967  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
2968  }
2969 
2970  if( simdEnabled && vector_.data() != nullptr && !checkAlignment( data() ) ) {
2971  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector alignment" );
2972  }
2973 }
2975 //*************************************************************************************************
2976 
2977 
2978 
2979 
2980 //=================================================================================================
2981 //
2982 // DATA ACCESS FUNCTIONS
2983 //
2984 //=================================================================================================
2985 
2986 //*************************************************************************************************
2993 template< typename VT // Type of the dense vector
2994  , bool TF > // Transpose flag
2996  Subvector<VT,aligned,TF,true>::operator[]( size_t index )
2997 {
2998  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
2999  return vector_[offset_+index];
3000 }
3002 //*************************************************************************************************
3003 
3004 
3005 //*************************************************************************************************
3012 template< typename VT // Type of the dense vector
3013  , bool TF > // Transpose flag
3015  Subvector<VT,aligned,TF,true>::operator[]( size_t index ) const
3016 {
3017  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
3018  return const_cast<const VT&>( vector_ )[offset_+index];
3019 }
3021 //*************************************************************************************************
3022 
3023 
3024 //*************************************************************************************************
3035 template< typename VT // Type of the dense vector
3036  , bool TF > // Transpose flag
3038  Subvector<VT,aligned,TF,true>::at( size_t index )
3039 {
3040  if( index >= size() ) {
3041  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
3042  }
3043  return (*this)[index];
3044 }
3046 //*************************************************************************************************
3047 
3048 
3049 //*************************************************************************************************
3060 template< typename VT // Type of the dense vector
3061  , bool TF > // Transpose flag
3063  Subvector<VT,aligned,TF,true>::at( size_t index ) const
3064 {
3065  if( index >= size() ) {
3066  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
3067  }
3068  return (*this)[index];
3069 }
3071 //*************************************************************************************************
3072 
3073 
3074 //*************************************************************************************************
3082 template< typename VT // Type of the dense vector
3083  , bool TF > // Transpose flag
3084 inline typename Subvector<VT,aligned,TF,true>::Pointer Subvector<VT,aligned,TF,true>::data() noexcept
3085 {
3086  return vector_.data() + offset_;
3087 }
3089 //*************************************************************************************************
3090 
3091 
3092 //*************************************************************************************************
3100 template< typename VT // Type of the dense vector
3101  , bool TF > // Transpose flag
3102 inline typename Subvector<VT,aligned,TF,true>::ConstPointer
3103  Subvector<VT,aligned,TF,true>::data() const noexcept
3104 {
3105  return vector_.data() + offset_;
3106 }
3108 //*************************************************************************************************
3109 
3110 
3111 //*************************************************************************************************
3119 template< typename VT // Type of the dense vector
3120  , bool TF > // Transpose flag
3122 {
3123  return ( vector_.begin() + offset_ );
3124 }
3126 //*************************************************************************************************
3127 
3128 
3129 //*************************************************************************************************
3137 template< typename VT // Type of the dense vector
3138  , bool TF > // Transpose flag
3141 {
3142  return ( vector_.cbegin() + offset_ );
3143 }
3145 //*************************************************************************************************
3146 
3147 
3148 //*************************************************************************************************
3156 template< typename VT // Type of the dense vector
3157  , bool TF > // Transpose flag
3160 {
3161  return ( vector_.cbegin() + offset_ );
3162 }
3164 //*************************************************************************************************
3165 
3166 
3167 //*************************************************************************************************
3175 template< typename VT // Type of the dense vector
3176  , bool TF > // Transpose flag
3178 {
3179  return ( vector_.begin() + offset_ + size_ );
3180 }
3182 //*************************************************************************************************
3183 
3184 
3185 //*************************************************************************************************
3193 template< typename VT // Type of the dense vector
3194  , bool TF > // Transpose flag
3197 {
3198  return ( vector_.cbegin() + offset_ + size_ );
3199 }
3201 //*************************************************************************************************
3202 
3203 
3204 //*************************************************************************************************
3212 template< typename VT // Type of the dense vector
3213  , bool TF > // Transpose flag
3216 {
3217  return ( vector_.cbegin() + offset_ + size_ );
3218 }
3220 //*************************************************************************************************
3221 
3222 
3223 
3224 
3225 //=================================================================================================
3226 //
3227 // ASSIGNMENT OPERATORS
3228 //
3229 //=================================================================================================
3230 
3231 //*************************************************************************************************
3238 template< typename VT // Type of the dense vector
3239  , bool TF > // Transpose flag
3240 inline Subvector<VT,aligned,TF,true>&
3241  Subvector<VT,aligned,TF,true>::operator=( const ElementType& rhs )
3242 {
3243  const size_t iend( offset_ + size_ );
3244 
3245  for( size_t i=offset_; i<iend; ++i )
3246  vector_[i] = rhs;
3247 
3248  return *this;
3249 }
3251 //*************************************************************************************************
3252 
3253 
3254 //*************************************************************************************************
3267 template< typename VT // Type of the dense vector
3268  , bool TF > // Transpose flag
3269 inline Subvector<VT,aligned,TF,true>&
3270  Subvector<VT,aligned,TF,true>::operator=( initializer_list<ElementType> list )
3271 {
3272  if( list.size() > size() ) {
3273  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to subvector" );
3274  }
3275 
3276  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
3277 
3278  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3279 
3280  return *this;
3281 }
3283 //*************************************************************************************************
3284 
3285 
3286 //*************************************************************************************************
3298 template< typename VT // Type of the dense vector
3299  , bool TF > // Transpose flag
3300 inline Subvector<VT,aligned,TF,true>&
3301  Subvector<VT,aligned,TF,true>::operator=( const Subvector& rhs )
3302 {
3305 
3306  if( &rhs == this || ( &vector_ == &rhs.vector_ && offset_ == rhs.offset_ ) )
3307  return *this;
3308 
3309  if( size() != rhs.size() ) {
3310  BLAZE_THROW_INVALID_ARGUMENT( "Subvector sizes do not match" );
3311  }
3312 
3313  if( !tryAssign( vector_, rhs, offset_ ) ) {
3314  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3315  }
3316 
3317  decltype(auto) left( derestrict( *this ) );
3318 
3319  if( rhs.canAlias( &vector_ ) ) {
3320  const ResultType tmp( ~rhs );
3321  smpAssign( left, tmp );
3322  }
3323  else {
3324  smpAssign( left, rhs );
3325  }
3326 
3327  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3328 
3329  return *this;
3330 }
3332 //*************************************************************************************************
3333 
3334 
3335 //*************************************************************************************************
3347 template< typename VT // Type of the dense vector
3348  , bool TF > // Transpose flag
3349 template< typename VT2 > // Type of the right-hand side vector
3350 inline Subvector<VT,aligned,TF,true>&
3351  Subvector<VT,aligned,TF,true>::operator=( const Vector<VT2,TF>& rhs )
3352 {
3355 
3356  if( size() != (~rhs).size() ) {
3357  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3358  }
3359 
3360  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
3361  Right right( ~rhs );
3362 
3363  if( !tryAssign( vector_, right, offset_ ) ) {
3364  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3365  }
3366 
3367  decltype(auto) left( derestrict( *this ) );
3368 
3369  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3370  const ResultType_<VT2> tmp( right );
3371  smpAssign( left, tmp );
3372  }
3373  else {
3374  if( IsSparseVector<VT2>::value )
3375  reset();
3376  smpAssign( left, right );
3377  }
3378 
3379  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3380 
3381  return *this;
3382 }
3384 //*************************************************************************************************
3385 
3386 
3387 //*************************************************************************************************
3399 template< typename VT // Type of the dense vector
3400  , bool TF > // Transpose flag
3401 template< typename VT2 > // Type of the right-hand side vector
3402 inline Subvector<VT,aligned,TF,true>&
3403  Subvector<VT,aligned,TF,true>::operator+=( const Vector<VT2,TF>& rhs )
3404 {
3407 
3408  if( size() != (~rhs).size() ) {
3409  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3410  }
3411 
3412  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
3413  Right right( ~rhs );
3414 
3415  if( !tryAddAssign( vector_, right, offset_ ) ) {
3416  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3417  }
3418 
3419  decltype(auto) left( derestrict( *this ) );
3420 
3421  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3422  const ResultType_<VT2> tmp( right );
3423  smpAddAssign( left, tmp );
3424  }
3425  else {
3426  smpAddAssign( left, right );
3427  }
3428 
3429  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3430 
3431  return *this;
3432 }
3434 //*************************************************************************************************
3435 
3436 
3437 //*************************************************************************************************
3449 template< typename VT // Type of the dense vector
3450  , bool TF > // Transpose flag
3451 template< typename VT2 > // Type of the right-hand side vector
3452 inline Subvector<VT,aligned,TF,true>&
3453  Subvector<VT,aligned,TF,true>::operator-=( const Vector<VT2,TF>& rhs )
3454 {
3457 
3458  if( size() != (~rhs).size() ) {
3459  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3460  }
3461 
3462  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
3463  Right right( ~rhs );
3464 
3465  if( !trySubAssign( vector_, right, offset_ ) ) {
3466  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3467  }
3468 
3469  decltype(auto) left( derestrict( *this ) );
3470 
3471  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3472  const ResultType_<VT2> tmp( right );
3473  smpSubAssign( left, tmp );
3474  }
3475  else {
3476  smpSubAssign( left, right );
3477  }
3478 
3479  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3480 
3481  return *this;
3482 }
3484 //*************************************************************************************************
3485 
3486 
3487 //*************************************************************************************************
3500 template< typename VT // Type of the dense vector
3501  , bool TF > // Transpose flag
3502 template< typename VT2 > // Type of the right-hand side dense vector
3503 inline Subvector<VT,aligned,TF,true>&
3504  Subvector<VT,aligned,TF,true>::operator*=( const DenseVector<VT2,TF>& rhs )
3505 {
3508 
3509  if( size() != (~rhs).size() ) {
3510  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3511  }
3512 
3513  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
3514  Right right( ~rhs );
3515 
3516  if( !tryMultAssign( vector_, right, offset_ ) ) {
3517  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3518  }
3519 
3520  decltype(auto) left( derestrict( *this ) );
3521 
3522  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3523  const ResultType_<VT2> tmp( right );
3524  smpMultAssign( left, tmp );
3525  }
3526  else {
3527  smpMultAssign( left, right );
3528  }
3529 
3530  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3531 
3532  return *this;
3533 }
3535 //*************************************************************************************************
3536 
3537 
3538 //*************************************************************************************************
3551 template< typename VT // Type of the dense vector
3552  , bool TF > // Transpose flag
3553 template< typename VT2 > // Type of the right-hand side sparse vector
3554 inline Subvector<VT,aligned,TF,true>&
3555  Subvector<VT,aligned,TF,true>::operator*=( const SparseVector<VT2,TF>& rhs )
3556 {
3559 
3560  if( size() != (~rhs).size() ) {
3561  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3562  }
3563 
3564  const ResultType tmp( *this * (~rhs) );
3565 
3566  if( !tryAssign( vector_, tmp, offset_ ) ) {
3567  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3568  }
3569 
3570  decltype(auto) left( derestrict( *this ) );
3571 
3572  smpAssign( left, tmp );
3573 
3574  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3575 
3576  return *this;
3577 }
3579 //*************************************************************************************************
3580 
3581 
3582 //*************************************************************************************************
3594 template< typename VT // Type of the dense vector
3595  , bool TF > // Transpose flag
3596 template< typename VT2 > // Type of the right-hand side dense vector
3597 inline Subvector<VT,aligned,TF,true>&
3598  Subvector<VT,aligned,TF,true>::operator/=( const DenseVector<VT2,TF>& rhs )
3599 {
3602 
3603  if( size() != (~rhs).size() ) {
3604  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3605  }
3606 
3607  using Right = If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& >;
3608  Right right( ~rhs );
3609 
3610  if( !tryDivAssign( vector_, right, offset_ ) ) {
3611  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3612  }
3613 
3614  decltype(auto) left( derestrict( *this ) );
3615 
3616  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3617  const ResultType_<VT2> tmp( right );
3618  smpDivAssign( left, tmp );
3619  }
3620  else {
3621  smpDivAssign( left, right );
3622  }
3623 
3624  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3625 
3626  return *this;
3627 }
3629 //*************************************************************************************************
3630 
3631 
3632 //*************************************************************************************************
3645 template< typename VT // Type of the dense vector
3646  , bool TF > // Transpose flag
3647 template< typename VT2 > // Type of the right-hand side vector
3648 inline Subvector<VT,aligned,TF,true>&
3649  Subvector<VT,aligned,TF,true>::operator%=( const Vector<VT2,TF>& rhs )
3650 {
3651  using blaze::assign;
3652 
3655 
3656  using CrossType = CrossTrait_< ResultType, ResultType_<VT2> >;
3657 
3661 
3662  if( size() != 3UL || (~rhs).size() != 3UL ) {
3663  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
3664  }
3665 
3666  const CrossType tmp( *this % (~rhs) );
3667 
3668  if( !tryAssign( vector_, tmp, offset_ ) ) {
3669  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3670  }
3671 
3672  decltype(auto) left( derestrict( *this ) );
3673 
3674  assign( left, tmp );
3675 
3676  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3677 
3678  return *this;
3679 }
3681 //*************************************************************************************************
3682 
3683 
3684 //*************************************************************************************************
3692 template< typename VT // Type of the dense vector
3693  , bool TF > // Transpose flag
3694 template< typename Other > // Data type of the right-hand side scalar
3695 inline EnableIf_< IsNumeric<Other>, Subvector<VT,aligned,TF,true> >&
3696  Subvector<VT,aligned,TF,true>::operator*=( Other rhs )
3697 {
3698  decltype(auto) left( derestrict( *this ) );
3699  smpAssign( left, (*this) * rhs );
3700 
3701  return *this;
3702 }
3704 //*************************************************************************************************
3705 
3706 
3707 //*************************************************************************************************
3717 template< typename VT // Type of the dense vector
3718  , bool TF > // Transpose flag
3719 template< typename Other > // Data type of the right-hand side scalar
3720 inline EnableIf_< IsNumeric<Other>, Subvector<VT,aligned,TF,true> >&
3721  Subvector<VT,aligned,TF,true>::operator/=( Other rhs )
3722 {
3723  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3724 
3725  decltype(auto) left( derestrict( *this ) );
3726  smpAssign( left, (*this) / rhs );
3727 
3728  return *this;
3729 }
3731 //*************************************************************************************************
3732 
3733 
3734 
3735 
3736 //=================================================================================================
3737 //
3738 // UTILITY FUNCTIONS
3739 //
3740 //=================================================================================================
3741 
3742 //*************************************************************************************************
3748 template< typename VT // Type of the dense vector
3749  , bool TF > // Transpose flag
3750 inline typename Subvector<VT,aligned,TF,true>::Operand
3751  Subvector<VT,aligned,TF,true>::operand() const noexcept
3752 {
3753  return vector_;
3754 }
3756 //*************************************************************************************************
3757 
3758 
3759 //*************************************************************************************************
3765 template< typename VT // Type of the dense vector
3766  , bool TF > // Transpose flag
3767 inline size_t Subvector<VT,aligned,TF,true>::offset() const noexcept
3768 {
3769  return offset_;
3770 }
3772 //*************************************************************************************************
3773 
3774 
3775 //*************************************************************************************************
3781 template< typename VT // Type of the dense vector
3782  , bool TF > // Transpose flag
3783 inline size_t Subvector<VT,aligned,TF,true>::size() const noexcept
3784 {
3785  return size_;
3786 }
3788 //*************************************************************************************************
3789 
3790 
3791 //*************************************************************************************************
3800 template< typename VT // Type of the dense vector
3801  , bool TF > // Transpose flag
3802 inline size_t Subvector<VT,aligned,TF,true>::spacing() const noexcept
3803 {
3804  return vector_.spacing() - offset_;
3805 }
3807 //*************************************************************************************************
3808 
3809 
3810 //*************************************************************************************************
3816 template< typename VT // Type of the dense vector
3817  , bool TF > // Transpose flag
3818 inline size_t Subvector<VT,aligned,TF,true>::capacity() const noexcept
3819 {
3820  return vector_.capacity() - offset_;
3821 }
3823 //*************************************************************************************************
3824 
3825 
3826 //*************************************************************************************************
3835 template< typename VT // Type of the dense vector
3836  , bool TF > // Transpose flag
3837 inline size_t Subvector<VT,aligned,TF,true>::nonZeros() const
3838 {
3839  size_t nonzeros( 0 );
3840 
3841  const size_t iend( offset_ + size_ );
3842  for( size_t i=offset_; i<iend; ++i ) {
3843  if( !isDefault( vector_[i] ) )
3844  ++nonzeros;
3845  }
3846 
3847  return nonzeros;
3848 }
3850 //*************************************************************************************************
3851 
3852 
3853 //*************************************************************************************************
3859 template< typename VT // Type of the dense vector
3860  , bool TF > // Transpose flag
3862 {
3863  using blaze::clear;
3864 
3865  const size_t iend( offset_ + size_ );
3866  for( size_t i=offset_; i<iend; ++i )
3867  clear( vector_[i] );
3868 }
3870 //*************************************************************************************************
3871 
3872 
3873 
3874 
3875 //=================================================================================================
3876 //
3877 // NUMERIC FUNCTIONS
3878 //
3879 //=================================================================================================
3880 
3881 //*************************************************************************************************
3892 template< typename VT // Type of the dense vector
3893  , bool TF > // Transpose flag
3894 template< typename Other > // Data type of the scalar value
3895 inline Subvector<VT,aligned,TF,true>& Subvector<VT,aligned,TF,true>::scale( const Other& scalar )
3896 {
3897  const size_t iend( offset_ + size_ );
3898  for( size_t i=offset_; i<iend; ++i )
3899  vector_[i] *= scalar;
3900  return *this;
3901 }
3903 //*************************************************************************************************
3904 
3905 
3906 
3907 
3908 //=================================================================================================
3909 //
3910 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3911 //
3912 //=================================================================================================
3913 
3914 //*************************************************************************************************
3925 template< typename VT // Type of the dense vector
3926  , bool TF > // Transpose flag
3927 template< typename Other > // Data type of the foreign expression
3928 inline bool Subvector<VT,aligned,TF,true>::canAlias( const Other* alias ) const noexcept
3929 {
3930  return vector_.isAliased( alias );
3931 }
3933 //*************************************************************************************************
3934 
3935 
3936 //*************************************************************************************************
3947 template< typename VT // Type of the dense vector
3948  , bool TF > // Transpose flag
3949 template< typename VT2 // Data type of the foreign dense subvector
3950  , bool AF2 // Alignment flag of the foreign dense subvector
3951  , bool TF2 > // Transpose flag of the foreign dense subvector
3952 inline bool Subvector<VT,aligned,TF,true>::canAlias( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept
3953 {
3954  return ( vector_.isAliased( &alias->vector_ ) &&
3955  ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
3956 }
3958 //*************************************************************************************************
3959 
3960 
3961 //*************************************************************************************************
3972 template< typename VT // Type of the dense vector
3973  , bool TF > // Transpose flag
3974 template< typename Other > // Data type of the foreign expression
3975 inline bool Subvector<VT,aligned,TF,true>::isAliased( const Other* alias ) const noexcept
3976 {
3977  return vector_.isAliased( alias );
3978 }
3980 //*************************************************************************************************
3981 
3982 
3983 //*************************************************************************************************
3994 template< typename VT // Type of the dense vector
3995  , bool TF > // Transpose flag
3996 template< typename VT2 // Data type of the foreign dense subvector
3997  , bool AF2 // Alignment flag of the foreign dense subvector
3998  , bool TF2 > // Transpose flag of the foreign dense subvector
3999 inline bool Subvector<VT,aligned,TF,true>::isAliased( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept
4000 {
4001  return ( vector_.isAliased( &alias->vector_ ) &&
4002  ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
4003 }
4005 //*************************************************************************************************
4006 
4007 
4008 //*************************************************************************************************
4018 template< typename VT // Type of the dense vector
4019  , bool TF > // Transpose flag
4020 inline bool Subvector<VT,aligned,TF,true>::isAligned() const noexcept
4021 {
4022  return true;
4023 }
4025 //*************************************************************************************************
4026 
4027 
4028 //*************************************************************************************************
4039 template< typename VT // Type of the dense vector
4040  , bool TF > // Transpose flag
4041 inline bool Subvector<VT,aligned,TF,true>::canSMPAssign() const noexcept
4042 {
4043  return ( size() > SMP_DVECASSIGN_THRESHOLD );
4044 }
4046 //*************************************************************************************************
4047 
4048 
4049 //*************************************************************************************************
4063 template< typename VT // Type of the dense vector
4064  , bool TF > // Transpose flag
4065 BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true>::SIMDType
4066  Subvector<VT,aligned,TF,true>::load( size_t index ) const noexcept
4067 {
4068  return loada( index );
4069 }
4071 //*************************************************************************************************
4072 
4073 
4074 //*************************************************************************************************
4088 template< typename VT // Type of the dense vector
4089  , bool TF > // Transpose flag
4090 BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true>::SIMDType
4091  Subvector<VT,aligned,TF,true>::loada( size_t index ) const noexcept
4092 {
4094 
4095  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4096  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4097  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4098 
4099  return vector_.loada( offset_+index );
4100 }
4102 //*************************************************************************************************
4103 
4104 
4105 //*************************************************************************************************
4119 template< typename VT // Type of the dense vector
4120  , bool TF > // Transpose flag
4121 BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true>::SIMDType
4122  Subvector<VT,aligned,TF,true>::loadu( size_t index ) const noexcept
4123 {
4125 
4126  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4127  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4128  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4129 
4130  return vector_.loadu( offset_+index );
4131 }
4133 //*************************************************************************************************
4134 
4135 
4136 //*************************************************************************************************
4151 template< typename VT // Type of the dense vector
4152  , bool TF > // Transpose flag
4154  Subvector<VT,aligned,TF,true>::store( size_t index, const SIMDType& value ) noexcept
4155 {
4156  storea( index, value );
4157 }
4159 //*************************************************************************************************
4160 
4161 
4162 //*************************************************************************************************
4177 template< typename VT // Type of the dense vector
4178  , bool TF > // Transpose flag
4180  Subvector<VT,aligned,TF,true>::storea( size_t index, const SIMDType& value ) noexcept
4181 {
4183 
4184  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4185  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4186  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4187 
4188  vector_.storea( offset_+index, value );
4189 }
4191 //*************************************************************************************************
4192 
4193 
4194 //*************************************************************************************************
4209 template< typename VT // Type of the dense vector
4210  , bool TF > // Transpose flag
4212  Subvector<VT,aligned,TF,true>::storeu( size_t index, const SIMDType& value ) noexcept
4213 {
4215 
4216  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4217  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4218  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4219 
4220  vector_.storeu( offset_+index, value );
4221 }
4223 //*************************************************************************************************
4224 
4225 
4226 //*************************************************************************************************
4241 template< typename VT // Type of the dense vector
4242  , bool TF > // Transpose flag
4244  Subvector<VT,aligned,TF,true>::stream( size_t index, const SIMDType& value ) noexcept
4245 {
4247 
4248  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4249  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4250  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4251 
4252  vector_.stream( offset_+index, value );
4253 }
4255 //*************************************************************************************************
4256 
4257 
4258 //*************************************************************************************************
4270 template< typename VT // Type of the dense vector
4271  , bool TF > // Transpose flag
4272 template< typename VT2 > // Type of the right-hand side dense vector
4273 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
4274  Subvector<VT,aligned,TF,true>::assign( const DenseVector<VT2,TF>& rhs )
4275 {
4276  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4277 
4278  const size_t ipos( size() & size_t(-2) );
4279  for( size_t i=0UL; i<ipos; i+=2UL ) {
4280  vector_[offset_+i ] = (~rhs)[i ];
4281  vector_[offset_+i+1UL] = (~rhs)[i+1UL];
4282  }
4283  if( ipos < size() ) {
4284  vector_[offset_+ipos] = (~rhs)[ipos];
4285  }
4286 }
4288 //*************************************************************************************************
4289 
4290 
4291 //*************************************************************************************************
4303 template< typename VT // Type of the dense vector
4304  , bool TF > // Transpose flag
4305 template< typename VT2 > // Type of the right-hand side dense vector
4306 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
4307  Subvector<VT,aligned,TF,true>::assign( const DenseVector<VT2,TF>& rhs )
4308 {
4310 
4311  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4312 
4313  const size_t ipos( size_ & size_t(-SIMDSIZE) );
4314  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4315 
4316  size_t i( 0UL );
4317  Iterator left( begin() );
4318  ConstIterator_<VT2> right( (~rhs).begin() );
4319 
4320  if( useStreaming && size_ > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( &vector_ ) )
4321  {
4322  for( ; i<ipos; i+=SIMDSIZE ) {
4323  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4324  }
4325  for( ; i<size_; ++i ) {
4326  *left = *right; ++left; ++right;
4327  }
4328  }
4329  else
4330  {
4331  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4332  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4333  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4334  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4335  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4336  }
4337  for( ; i<ipos; i+=SIMDSIZE ) {
4338  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4339  }
4340  for( ; i<size_; ++i ) {
4341  *left = *right; ++left; ++right;
4342  }
4343  }
4344 }
4346 //*************************************************************************************************
4347 
4348 
4349 //*************************************************************************************************
4361 template< typename VT // Type of the dense vector
4362  , bool TF > // Transpose flag
4363 template< typename VT2 > // Type of the right-hand side sparse vector
4364 inline void Subvector<VT,aligned,TF,true>::assign( const SparseVector<VT2,TF>& rhs )
4365 {
4366  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4367 
4368  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4369  vector_[offset_+element->index()] = element->value();
4370 }
4372 //*************************************************************************************************
4373 
4374 
4375 //*************************************************************************************************
4387 template< typename VT // Type of the dense vector
4388  , bool TF > // Transpose flag
4389 template< typename VT2 > // Type of the right-hand side dense vector
4390 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
4391  Subvector<VT,aligned,TF,true>::addAssign( const DenseVector<VT2,TF>& rhs )
4392 {
4393  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4394 
4395  const size_t ipos( size() & size_t(-2) );
4396  for( size_t i=0UL; i<ipos; i+=2UL ) {
4397  vector_[offset_+i ] += (~rhs)[i ];
4398  vector_[offset_+i+1UL] += (~rhs)[i+1UL];
4399  }
4400  if( ipos < size() ) {
4401  vector_[offset_+ipos] += (~rhs)[ipos];
4402  }
4403 }
4405 //*************************************************************************************************
4406 
4407 
4408 //*************************************************************************************************
4420 template< typename VT // Type of the dense vector
4421  , bool TF > // Transpose flag
4422 template< typename VT2 > // Type of the right-hand side dense vector
4423 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
4424  Subvector<VT,aligned,TF,true>::addAssign( const DenseVector<VT2,TF>& rhs )
4425 {
4427 
4428  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4429 
4430  const size_t ipos( size_ & size_t(-SIMDSIZE) );
4431  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4432 
4433  size_t i( 0UL );
4434  Iterator left( begin() );
4435  ConstIterator_<VT2> right( (~rhs).begin() );
4436 
4437  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4438  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4439  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4440  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4441  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4442  }
4443  for( ; i<ipos; i+=SIMDSIZE ) {
4444  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4445  }
4446  for( ; i<size_; ++i ) {
4447  *left += *right; ++left; ++right;
4448  }
4449 }
4451 //*************************************************************************************************
4452 
4453 
4454 //*************************************************************************************************
4466 template< typename VT // Type of the dense vector
4467  , bool TF > // Transpose flag
4468 template< typename VT2 > // Type of the right-hand side sparse vector
4469 inline void Subvector<VT,aligned,TF,true>::addAssign( const SparseVector<VT2,TF>& rhs )
4470 {
4471  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4472 
4473  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4474  vector_[offset_+element->index()] += element->value();
4475 }
4477 //*************************************************************************************************
4478 
4479 
4480 //*************************************************************************************************
4492 template< typename VT // Type of the dense vector
4493  , bool TF > // Transpose flag
4494 template< typename VT2 > // Type of the right-hand side dense vector
4495 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
4496  Subvector<VT,aligned,TF,true>::subAssign( const DenseVector<VT2,TF>& rhs )
4497 {
4498  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4499 
4500  const size_t ipos( size() & size_t(-2) );
4501  for( size_t i=0UL; i<ipos; i+=2UL ) {
4502  vector_[offset_+i ] -= (~rhs)[i ];
4503  vector_[offset_+i+1UL] -= (~rhs)[i+1UL];
4504  }
4505  if( ipos < size() ) {
4506  vector_[offset_+ipos] -= (~rhs)[ipos];
4507  }
4508 }
4510 //*************************************************************************************************
4511 
4512 
4513 //*************************************************************************************************
4525 template< typename VT // Type of the dense vector
4526  , bool TF > // Transpose flag
4527 template< typename VT2 > // Type of the right-hand side dense vector
4528 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
4529  Subvector<VT,aligned,TF,true>::subAssign( const DenseVector<VT2,TF>& rhs )
4530 {
4532 
4533  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4534 
4535  const size_t ipos( size_ & size_t(-SIMDSIZE) );
4536  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4537 
4538  size_t i( 0UL );
4539  Iterator left( begin() );
4540  ConstIterator_<VT2> right( (~rhs).begin() );
4541 
4542  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4543  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4544  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4545  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4546  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4547  }
4548  for( ; i<ipos; i+=SIMDSIZE ) {
4549  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4550  }
4551  for( ; i<size_; ++i ) {
4552  *left -= *right; ++left; ++right;
4553  }
4554 }
4556 //*************************************************************************************************
4557 
4558 
4559 //*************************************************************************************************
4571 template< typename VT // Type of the dense vector
4572  , bool TF > // Transpose flag
4573 template< typename VT2 > // Type of the right-hand side sparse vector
4574 inline void Subvector<VT,aligned,TF,true>::subAssign( const SparseVector<VT2,TF>& rhs )
4575 {
4576  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4577 
4578  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4579  vector_[offset_+element->index()] -= element->value();
4580 }
4582 //*************************************************************************************************
4583 
4584 
4585 //*************************************************************************************************
4597 template< typename VT // Type of the dense vector
4598  , bool TF > // Transpose flag
4599 template< typename VT2 > // Type of the right-hand side dense vector
4600 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
4601  Subvector<VT,aligned,TF,true>::multAssign( const DenseVector<VT2,TF>& rhs )
4602 {
4603  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4604 
4605  const size_t ipos( size() & size_t(-2) );
4606  for( size_t i=0UL; i<ipos; i+=2UL ) {
4607  vector_[offset_+i ] *= (~rhs)[i ];
4608  vector_[offset_+i+1UL] *= (~rhs)[i+1UL];
4609  }
4610  if( ipos < size() ) {
4611  vector_[offset_+ipos] *= (~rhs)[ipos];
4612  }
4613 }
4615 //*************************************************************************************************
4616 
4617 
4618 //*************************************************************************************************
4630 template< typename VT // Type of the dense vector
4631  , bool TF > // Transpose flag
4632 template< typename VT2 > // Type of the right-hand side dense vector
4633 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
4634  Subvector<VT,aligned,TF,true>::multAssign( const DenseVector<VT2,TF>& rhs )
4635 {
4637 
4638  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4639 
4640  const size_t ipos( size_ & size_t(-SIMDSIZE) );
4641  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4642 
4643  size_t i( 0UL );
4644  Iterator left( begin() );
4645  ConstIterator_<VT2> right( (~rhs).begin() );
4646 
4647  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4648  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4649  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4650  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4651  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4652  }
4653  for( ; i<ipos; i+=SIMDSIZE ) {
4654  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4655  }
4656  for( ; i<size_; ++i ) {
4657  *left *= *right; ++left; ++right;
4658  }
4659 }
4661 //*************************************************************************************************
4662 
4663 
4664 //*************************************************************************************************
4676 template< typename VT // Type of the dense vector
4677  , bool TF > // Transpose flag
4678 template< typename VT2 > // Type of the right-hand side sparse vector
4679 inline void Subvector<VT,aligned,TF,true>::multAssign( const SparseVector<VT2,TF>& rhs )
4680 {
4681  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4682 
4683  const ResultType tmp( serial( *this ) );
4684 
4685  reset();
4686 
4687  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4688  vector_[offset_+element->index()] = tmp[element->index()] * element->value();
4689 }
4691 //*************************************************************************************************
4692 
4693 
4694 //*************************************************************************************************
4706 template< typename VT // Type of the dense vector
4707  , bool TF > // Transpose flag
4708 template< typename VT2 > // Type of the right-hand side dense vector
4709 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
4710  Subvector<VT,aligned,TF,true>::divAssign( const DenseVector<VT2,TF>& rhs )
4711 {
4712  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4713 
4714  const size_t ipos( size() & size_t(-2) );
4715  for( size_t i=0UL; i<ipos; i+=2UL ) {
4716  vector_[offset_+i ] /= (~rhs)[i ];
4717  vector_[offset_+i+1UL] /= (~rhs)[i+1UL];
4718  }
4719  if( ipos < size() ) {
4720  vector_[offset_+ipos] /= (~rhs)[ipos];
4721  }
4722 }
4724 //*************************************************************************************************
4725 
4726 
4727 //*************************************************************************************************
4739 template< typename VT // Type of the dense vector
4740  , bool TF > // Transpose flag
4741 template< typename VT2 > // Type of the right-hand side dense vector
4742 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
4743  Subvector<VT,aligned,TF,true>::divAssign( const DenseVector<VT2,TF>& rhs )
4744 {
4746 
4747  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4748 
4749  const size_t ipos( size_ & size_t(-SIMDSIZE) );
4750  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4751 
4752  size_t i( 0UL );
4753  Iterator left( begin() );
4754  ConstIterator_<VT2> right( (~rhs).begin() );
4755 
4756  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4757  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4758  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4759  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4760  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4761  }
4762  for( ; i<ipos; i+=SIMDSIZE ) {
4763  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4764  }
4765  for( ; i<size_; ++i ) {
4766  *left /= *right; ++left; ++right;
4767  }
4768 }
4770 //*************************************************************************************************
4771 
4772 
4773 
4774 
4775 
4776 
4777 
4778 
4779 //=================================================================================================
4780 //
4781 // CLASS TEMPLATE SPECIALIZATION FOR DVECDVECCROSSEXPR
4782 //
4783 //=================================================================================================
4784 
4785 //*************************************************************************************************
4793 template< typename VT1 // Type of the left-hand side dense vector
4794  , typename VT2 // Type of the right-hand side dense vector
4795  , bool TF > // Transpose flag
4796 class Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
4797  : public View< DenseVector< Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF > >
4798 {
4799  private:
4800  //**Type definitions****************************************************************************
4801  using CPE = DVecDVecCrossExpr<VT1,VT2,TF>;
4802  using RT = ResultType_<CPE>;
4803  //**********************************************************************************************
4804 
4805  public:
4806  //**Type definitions****************************************************************************
4807  using This = Subvector<CPE,unaligned,TF,true>;
4808  using BaseType = DenseVector<This,TF>;
4809  using ResultType = SubvectorTrait_<RT>;
4810  using TransposeType = TransposeType_<ResultType>;
4811  using ElementType = ElementType_<CPE>;
4812  using ReturnType = ReturnType_<CPE>;
4813  using CompositeType = const ResultType;
4814  //**********************************************************************************************
4815 
4816  //**Compilation flags***************************************************************************
4818  enum : bool { simdEnabled = false };
4819 
4821  enum : bool { smpAssignable = false };
4822  //**********************************************************************************************
4823 
4824  //**Constructor*********************************************************************************
4831  explicit inline Subvector( const CPE& vector, size_t index, size_t n ) noexcept
4832  : vector_( vector ) // The dense vector/dense vector cross product expression
4833  , offset_( index ) // The offset of the subvector within the cross product expression
4834  , size_ ( n ) // The size of the subvector
4835  {}
4836  //**********************************************************************************************
4837 
4838  //**Subscript operator**************************************************************************
4844  inline ReturnType operator[]( size_t index ) const {
4845  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
4846  return vector_[offset_+index];
4847  }
4848  //**********************************************************************************************
4849 
4850  //**At function*********************************************************************************
4857  inline ReturnType at( size_t index ) const {
4858  if( index >= size() ) {
4859  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
4860  }
4861  return (*this)[index];
4862  }
4863  //**********************************************************************************************
4864 
4865  //**Operand access******************************************************************************
4870  inline CPE operand() const noexcept {
4871  return vector_;
4872  }
4873  //**********************************************************************************************
4874 
4875  //**Offset function*****************************************************************************
4880  inline size_t offset() const noexcept {
4881  return offset_;
4882  }
4883  //**********************************************************************************************
4884 
4885  //**Size function*******************************************************************************
4890  inline size_t size() const noexcept {
4891  return size_;
4892  }
4893  //**********************************************************************************************
4894 
4895  //**********************************************************************************************
4901  template< typename T >
4902  inline bool canAlias( const T* alias ) const noexcept {
4903  return vector_.canAlias( alias );
4904  }
4905  //**********************************************************************************************
4906 
4907  //**********************************************************************************************
4913  template< typename T >
4914  inline bool isAliased( const T* alias ) const noexcept {
4915  return vector_.isAliased( alias );
4916  }
4917  //**********************************************************************************************
4918 
4919  private:
4920  //**Member variables****************************************************************************
4923  CPE vector_;
4924  const size_t offset_;
4925  const size_t size_;
4926 
4927  //**********************************************************************************************
4928 };
4930 //*************************************************************************************************
4931 
4932 
4933 
4934 
4935 
4936 
4937 
4938 
4939 //=================================================================================================
4940 //
4941 // CLASS TEMPLATE SPECIALIZATION FOR DVECSVECCROSSEXPR
4942 //
4943 //=================================================================================================
4944 
4945 //*************************************************************************************************
4953 template< typename VT1 // Type of the left-hand side dense vector
4954  , typename VT2 // Type of the right-hand side sparse vector
4955  , bool TF > // Transpose flag
4956 class Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
4957  : public View< DenseVector< Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF > >
4958 {
4959  private:
4960  //**Type definitions****************************************************************************
4961  using CPE = DVecSVecCrossExpr<VT1,VT2,TF>;
4962  using RT = ResultType_<CPE>;
4963  //**********************************************************************************************
4964 
4965  public:
4966  //**Type definitions****************************************************************************
4967  using This = Subvector<CPE,unaligned,TF,true>;
4968  using BaseType = DenseVector<This,TF>;
4969  using ResultType = SubvectorTrait_<RT>;
4970  using TransposeType = TransposeType_<ResultType>;
4971  using ElementType = ElementType_<CPE>;
4972  using ReturnType = ReturnType_<CPE>;
4973  using CompositeType = const ResultType;
4974  //**********************************************************************************************
4975 
4976  //**Compilation flags***************************************************************************
4978  enum : bool { simdEnabled = false };
4979 
4981  enum : bool { smpAssignable = false };
4982  //**********************************************************************************************
4983 
4984  //**Constructor*********************************************************************************
4991  explicit inline Subvector( const CPE& vector, size_t index, size_t n ) noexcept
4992  : vector_( vector ) // The dense vector/sparse vector cross product expression
4993  , offset_( index ) // The offset of the subvector within the cross product expression
4994  , size_ ( n ) // The size of the subvector
4995  {}
4996  //**********************************************************************************************
4997 
4998  //**Subscript operator**************************************************************************
5004  inline ReturnType operator[]( size_t index ) const {
5005  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
5006  return vector_[offset_+index];
5007  }
5008  //**********************************************************************************************
5009 
5010  //**At function*********************************************************************************
5017  inline ReturnType at( size_t index ) const {
5018  if( index >= size() ) {
5019  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
5020  }
5021  return (*this)[index];
5022  }
5023  //**********************************************************************************************
5024 
5025  //**Operand access******************************************************************************
5030  inline CPE operand() const noexcept {
5031  return vector_;
5032  }
5033  //**********************************************************************************************
5034 
5035  //**Offset function*****************************************************************************
5040  inline size_t offset() const noexcept {
5041  return offset_;
5042  }
5043  //**********************************************************************************************
5044 
5045  //**Size function*******************************************************************************
5050  inline size_t size() const noexcept {
5051  return size_;
5052  }
5053  //**********************************************************************************************
5054 
5055  //**********************************************************************************************
5061  template< typename T >
5062  inline bool canAlias( const T* alias ) const noexcept {
5063  return vector_.canAlias( alias );
5064  }
5065  //**********************************************************************************************
5066 
5067  //**********************************************************************************************
5073  template< typename T >
5074  inline bool isAliased( const T* alias ) const noexcept {
5075  return vector_.isAliased( alias );
5076  }
5077  //**********************************************************************************************
5078 
5079  private:
5080  //**Member variables****************************************************************************
5083  CPE vector_;
5084  const size_t offset_;
5085  const size_t size_;
5086 
5087  //**********************************************************************************************
5088 };
5090 //*************************************************************************************************
5091 
5092 
5093 
5094 
5095 
5096 
5097 
5098 
5099 //=================================================================================================
5100 //
5101 // CLASS TEMPLATE SPECIALIZATION FOR SVECDVECCROSSEXPR
5102 //
5103 //=================================================================================================
5104 
5105 //*************************************************************************************************
5113 template< typename VT1 // Type of the left-hand side sparse vector
5114  , typename VT2 // Type of the right-hand side dense vector
5115  , bool TF > // Transpose flag
5116 class Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
5117  : public View< DenseVector< Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF > >
5118 {
5119  private:
5120  //**Type definitions****************************************************************************
5121  using CPE = SVecDVecCrossExpr<VT1,VT2,TF>;
5122  using RT = ResultType_<CPE>;
5123  //**********************************************************************************************
5124 
5125  public:
5126  //**Type definitions****************************************************************************
5127  using This = Subvector<CPE,unaligned,TF,true>;
5128  using BaseType = DenseVector<This,TF>;
5129  using ResultType = SubvectorTrait_<RT>;
5130  using TransposeType = TransposeType_<ResultType>;
5131  using ElementType = ElementType_<CPE>;
5132  using ReturnType = ReturnType_<CPE>;
5133  using CompositeType = const ResultType;
5134  //**********************************************************************************************
5135 
5136  //**Compilation flags***************************************************************************
5138  enum : bool { simdEnabled = false };
5139 
5141  enum : bool { smpAssignable = false };
5142  //**********************************************************************************************
5143 
5144  //**Constructor*********************************************************************************
5151  explicit inline Subvector( const CPE& vector, size_t index, size_t n ) noexcept
5152  : vector_( vector ) // The sparse vector/dense vector cross product expression
5153  , offset_( index ) // The offset of the subvector within the cross product expression
5154  , size_ ( n ) // The size of the subvector
5155  {}
5156  //**********************************************************************************************
5157 
5158  //**Subscript operator**************************************************************************
5164  inline ReturnType operator[]( size_t index ) const {
5165  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
5166  return vector_[offset_+index];
5167  }
5168  //**********************************************************************************************
5169 
5170  //**At function*********************************************************************************
5177  inline ReturnType at( size_t index ) const {
5178  if( index >= size() ) {
5179  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
5180  }
5181  return (*this)[index];
5182  }
5183  //**********************************************************************************************
5184 
5185  //**Operand access******************************************************************************
5190  inline CPE operand() const noexcept {
5191  return vector_;
5192  }
5193  //**********************************************************************************************
5194 
5195  //**Offset function*****************************************************************************
5200  inline size_t offset() const noexcept {
5201  return offset_;
5202  }
5203  //**********************************************************************************************
5204 
5205  //**Size function*******************************************************************************
5210  inline size_t size() const noexcept {
5211  return size_;
5212  }
5213  //**********************************************************************************************
5214 
5215  //**********************************************************************************************
5221  template< typename T >
5222  inline bool canAlias( const T* alias ) const noexcept {
5223  return vector_.canAlias( alias );
5224  }
5225  //**********************************************************************************************
5226 
5227  //**********************************************************************************************
5233  template< typename T >
5234  inline bool isAliased( const T* alias ) const noexcept {
5235  return vector_.isAliased( alias );
5236  }
5237  //**********************************************************************************************
5238 
5239  private:
5240  //**Member variables****************************************************************************
5243  CPE vector_;
5244  const size_t offset_;
5245  const size_t size_;
5246 
5247  //**********************************************************************************************
5248 };
5250 //*************************************************************************************************
5251 
5252 
5253 
5254 
5255 
5256 
5257 
5258 
5259 //=================================================================================================
5260 //
5261 // CLASS TEMPLATE SPECIALIZATION FOR SVECSVECCROSSEXPR
5262 //
5263 //=================================================================================================
5264 
5265 //*************************************************************************************************
5273 template< typename VT1 // Type of the left-hand side sparse vector
5274  , typename VT2 // Type of the right-hand side sparse vector
5275  , bool TF > // Transpose flag
5276 class Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
5277  : public View< DenseVector< Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF > >
5278 {
5279  private:
5280  //**Type definitions****************************************************************************
5281  using CPE = SVecSVecCrossExpr<VT1,VT2,TF>;
5282  using RT = ResultType_<CPE>;
5283  //**********************************************************************************************
5284 
5285  public:
5286  //**Type definitions****************************************************************************
5287  using This = Subvector<CPE,unaligned,TF,true>;
5288  using BaseType = DenseVector<This,TF>;
5289  using ResultType = SubvectorTrait_<RT>;
5290  using TransposeType = TransposeType_<ResultType>;
5291  using ElementType = ElementType_<CPE>;
5292  using ReturnType = ReturnType_<CPE>;
5293  using CompositeType = const ResultType;
5294  //**********************************************************************************************
5295 
5296  //**Compilation flags***************************************************************************
5298  enum : bool { simdEnabled = false };
5299 
5301  enum : bool { smpAssignable = false };
5302  //**********************************************************************************************
5303 
5304  //**Constructor*********************************************************************************
5311  explicit inline Subvector( const CPE& vector, size_t index, size_t n ) noexcept
5312  : vector_( vector ) // The sparse vector/sparse vector cross product expression
5313  , offset_( index ) // The offset of the subvector within the cross product expression
5314  , size_ ( n ) // The size of the subvector
5315  {}
5316  //**********************************************************************************************
5317 
5318  //**Subscript operator**************************************************************************
5324  inline ReturnType operator[]( size_t index ) const {
5325  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
5326  return vector_[offset_+index];
5327  }
5328  //**********************************************************************************************
5329 
5330  //**At function*********************************************************************************
5337  inline ReturnType at( size_t index ) const {
5338  if( index >= size() ) {
5339  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
5340  }
5341  return (*this)[index];
5342  }
5343  //**********************************************************************************************
5344 
5345  //**Operand access******************************************************************************
5350  inline CPE operand() const noexcept {
5351  return vector_;
5352  }
5353  //**********************************************************************************************
5354 
5355  //**Offset function*****************************************************************************
5360  inline size_t offset() const noexcept {
5361  return offset_;
5362  }
5363  //**********************************************************************************************
5364 
5365  //**Size function*******************************************************************************
5370  inline size_t size() const noexcept {
5371  return size_;
5372  }
5373  //**********************************************************************************************
5374 
5375  //**********************************************************************************************
5381  template< typename T >
5382  inline bool canAlias( const T* alias ) const noexcept {
5383  return vector_.canAlias( alias );
5384  }
5385  //**********************************************************************************************
5386 
5387  //**********************************************************************************************
5393  template< typename T >
5394  inline bool isAliased( const T* alias ) const {
5395  return vector_.isAliased( alias );
5396  }
5397  //**********************************************************************************************
5398 
5399  private:
5400  //**Member variables****************************************************************************
5403  CPE vector_;
5404  const size_t offset_;
5405  const size_t size_;
5406 
5407  //**********************************************************************************************
5408 };
5410 //*************************************************************************************************
5411 
5412 } // namespace blaze
5413 
5414 #endif
constexpr bool aligned
Alignment flag for aligned vectors and matrices.Via this flag it is possible to specify subvectors...
Definition: AlignmentFlag.h:85
Constraint on the data type.
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the alignment flag values.
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:356
Header file for basic type definitions.
Header file for the View base class.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:79
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:164
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:265
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i...
Definition: Computation.h:81
constexpr bool operator<(const NegativeAccuracy< A > &lhs, const T &rhs)
Less-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:329
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3078
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:198
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3076
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:560
const DenseIterator< Type, AF > operator+(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Addition between a DenseIterator and an integral value.
Definition: DenseIterator.h:699
EnableIf_< IsDenseVector< VT1 > > smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP multiplication assignment of a vector to a dense vector...
Definition: DenseVector.h:193
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3080
Header file for the DenseVector base class.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3085
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:394
Header file for the Computation base class.
const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:731
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3086
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i...
Definition: TransExpr.h:81
System settings for performance optimizations.
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1393
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:77
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:133
BLAZE_ALWAYS_INLINE MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:308
BLAZE_ALWAYS_INLINE MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:242
BLAZE_ALWAYS_INLINE size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:110
Header file for the std::initializer_list aliases.
Constraint on the data type.
Header file for the DisableIf class template.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3084
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Header file for nested template disabiguation.
Header file for the If class template.
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3077
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:102
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3081
Header file for the Or class template.
#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 HasSIMDAdd type trait.
constexpr bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:367
constexpr bool operator>=(const NegativeAccuracy< A > &, const T &rhs)
Greater-or-equal-than comparison between a NegativeAccuracy object and a floating point value...
Definition: Accuracy.h:443
Header file for the implementation of the Subvector base template.
Header file for the Not class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3087
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:250
Header file for all SIMD functionality.
Constraint on the data type.
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:80
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not a vectorizable data type...
Definition: Vectorizable.h:61
Constraint on the data type.
Header file for the exception macros of the math module.
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:264
decltype(auto) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:8893
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:290
Constraint on the data type.
Header file for all forward declarations for expression class templates.
constexpr bool unaligned
Alignment flag for unaligned vectors and matrices.Via this flag it is possible to specify subvectors...
Definition: AlignmentFlag.h:64
Header file for the EnableIf class template.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:580
Header file for the CrossExpr base class.
Header file for the IsNumeric type trait.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:75
Header file for the IsSIMDCombinable type trait.
Header file for the IsSparseVector type trait.
Header file for the HasSIMDMult type trait.
Header file for the IsConst type trait.
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
Header file for run time assertion macros.
Header file for the cross product trait.
EnableIf_< IsDenseVector< VT1 > > smpDivAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP division assignment of a vector to a dense vector.
Definition: DenseVector.h:222
Header file for the cache size of the target architecture.
Header file for the isDefault shim.
Header file for the HasSIMDSub type trait.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:819
constexpr bool operator<=(const NegativeAccuracy< A > &, const T &rhs)
Less-or-equal-than comparison between a NegativeAccuracy object and a floating point value...
Definition: Accuracy.h:405
#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
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:76
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3082
#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
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBVECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is a subvector type (i.e. a dense or sparse subvector), a compilation error is created.
Definition: Subvector.h:81
Header file for the HasSIMDDiv type trait.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3083
Header file for the alignment check function.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:252
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:600
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
Header file for the IsRestricted type trait.
System settings for the inline keywords.
#define BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG(T, TF)
Constraint on the data type.In case the given data type T is not a dense or sparse vector type and in...
Definition: TransposeFlag.h:63
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#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
Header file for the IsExpression type trait class.