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 DenseVector< Subvector<VT,unaligned,TF,true>, TF >
110  , private View
111 {
112  private:
113  //**Type definitions****************************************************************************
115  typedef If_< IsExpression<VT>, VT, VT& > Operand;
116  //**********************************************************************************************
117 
118  public:
119  //**Type definitions****************************************************************************
120  typedef Subvector<VT,unaligned,TF,true> This;
121  typedef DenseVector<This,TF> BaseType;
122  typedef SubvectorTrait_<VT> ResultType;
123  typedef TransposeType_<ResultType> TransposeType;
124  typedef ElementType_<VT> ElementType;
125  typedef SIMDTrait_<ElementType> SIMDType;
126  typedef ReturnType_<VT> ReturnType;
127  typedef const Subvector& CompositeType;
128 
130  typedef ConstReference_<VT> ConstReference;
131 
133  typedef If_< IsConst<VT>, ConstReference, Reference_<VT> > Reference;
134 
136  typedef const ElementType* ConstPointer;
137 
139  typedef If_< Or< IsConst<VT>, Not< HasMutableDataAccess<VT> > >, ConstPointer, ElementType* > Pointer;
140  //**********************************************************************************************
141 
142  //**SubvectorIterator class definition**********************************************************
145  template< typename IteratorType > // Type of the dense vector iterator
146  class SubvectorIterator
147  {
148  public:
149  //**Type definitions*************************************************************************
151  typedef typename std::iterator_traits<IteratorType>::iterator_category IteratorCategory;
152 
154  typedef typename std::iterator_traits<IteratorType>::value_type ValueType;
155 
157  typedef typename std::iterator_traits<IteratorType>::pointer PointerType;
158 
160  typedef typename std::iterator_traits<IteratorType>::reference ReferenceType;
161 
163  typedef typename std::iterator_traits<IteratorType>::difference_type DifferenceType;
164 
165  // STL iterator requirements
166  typedef IteratorCategory iterator_category;
167  typedef ValueType value_type;
168  typedef PointerType pointer;
169  typedef ReferenceType reference;
170  typedef DifferenceType difference_type;
171  //*******************************************************************************************
172 
173  //**Constructor******************************************************************************
176  inline SubvectorIterator()
177  : iterator_ ( ) // Iterator to the current subvector element
178  , isAligned_( false ) // Memory alignment flag
179  {}
180  //*******************************************************************************************
181 
182  //**Constructor******************************************************************************
188  inline SubvectorIterator( IteratorType iterator, bool isMemoryAligned )
189  : iterator_ ( iterator ) // Iterator to the current subvector element
190  , isAligned_( isMemoryAligned ) // Memory alignment flag
191  {}
192  //*******************************************************************************************
193 
194  //**Constructor******************************************************************************
199  template< typename IteratorType2 >
200  inline SubvectorIterator( const SubvectorIterator<IteratorType2>& it )
201  : iterator_ ( it.base() ) // Iterator to the current subvector element
202  , isAligned_( it.isAligned() ) // Memory alignment flag
203  {}
204  //*******************************************************************************************
205 
206  //**Addition assignment operator*************************************************************
212  inline SubvectorIterator& operator+=( size_t inc ) {
213  iterator_ += inc;
214  return *this;
215  }
216  //*******************************************************************************************
217 
218  //**Subtraction assignment operator**********************************************************
224  inline SubvectorIterator& operator-=( size_t dec ) {
225  iterator_ -= dec;
226  return *this;
227  }
228  //*******************************************************************************************
229 
230  //**Prefix increment operator****************************************************************
235  inline SubvectorIterator& operator++() {
236  ++iterator_;
237  return *this;
238  }
239  //*******************************************************************************************
240 
241  //**Postfix increment operator***************************************************************
246  inline const SubvectorIterator operator++( int ) {
247  return SubvectorIterator( iterator_++, isAligned_ );
248  }
249  //*******************************************************************************************
250 
251  //**Prefix decrement operator****************************************************************
256  inline SubvectorIterator& operator--() {
257  --iterator_;
258  return *this;
259  }
260  //*******************************************************************************************
261 
262  //**Postfix decrement operator***************************************************************
267  inline const SubvectorIterator operator--( int ) {
268  return SubvectorIterator( iterator_--, isAligned_ );
269  }
270  //*******************************************************************************************
271 
272  //**Element access operator******************************************************************
277  inline ReferenceType operator*() const {
278  return *iterator_;
279  }
280  //*******************************************************************************************
281 
282  //**Load function****************************************************************************
292  inline SIMDType load() const {
293  return loadu();
294  }
295  //*******************************************************************************************
296 
297  //**Loada function***************************************************************************
307  inline SIMDType loada() const {
308  return iterator_.loada();
309  }
310  //*******************************************************************************************
311 
312  //**Loadu function***************************************************************************
322  inline SIMDType loadu() const {
323  if( isAligned_ ) {
324  return iterator_.loada();
325  }
326  else {
327  return iterator_.loadu();
328  }
329  }
330  //*******************************************************************************************
331 
332  //**Store function***************************************************************************
343  inline void store( const SIMDType& value ) const {
344  storeu( value );
345  }
346  //*******************************************************************************************
347 
348  //**Storea function**************************************************************************
359  inline void storea( const SIMDType& value ) const {
360  iterator_.storea( value );
361  }
362  //*******************************************************************************************
363 
364  //**Storeu function**************************************************************************
375  inline void storeu( const SIMDType& value ) const {
376  if( isAligned_ ) {
377  iterator_.storea( value );
378  }
379  else {
380  iterator_.storeu( value );
381  }
382  }
383  //*******************************************************************************************
384 
385  //**Stream function**************************************************************************
396  inline void stream( const SIMDType& value ) const {
397  iterator_.stream( value );
398  }
399  //*******************************************************************************************
400 
401  //**Equality operator************************************************************************
407  inline bool operator==( const SubvectorIterator& rhs ) const {
408  return iterator_ == rhs.iterator_;
409  }
410  //*******************************************************************************************
411 
412  //**Inequality operator**********************************************************************
418  inline bool operator!=( const SubvectorIterator& rhs ) const {
419  return iterator_ != rhs.iterator_;
420  }
421  //*******************************************************************************************
422 
423  //**Less-than operator***********************************************************************
429  inline bool operator<( const SubvectorIterator& rhs ) const {
430  return iterator_ < rhs.iterator_;
431  }
432  //*******************************************************************************************
433 
434  //**Greater-than operator********************************************************************
440  inline bool operator>( const SubvectorIterator& rhs ) const {
441  return iterator_ > rhs.iterator_;
442  }
443  //*******************************************************************************************
444 
445  //**Less-or-equal-than operator**************************************************************
451  inline bool operator<=( const SubvectorIterator& rhs ) const {
452  return iterator_ <= rhs.iterator_;
453  }
454  //*******************************************************************************************
455 
456  //**Greater-or-equal-than operator***********************************************************
462  inline bool operator>=( const SubvectorIterator& rhs ) const {
463  return iterator_ >= rhs.iterator_;
464  }
465  //*******************************************************************************************
466 
467  //**Subtraction operator*********************************************************************
473  inline DifferenceType operator-( const SubvectorIterator& rhs ) const {
474  return iterator_ - rhs.iterator_;
475  }
476  //*******************************************************************************************
477 
478  //**Addition operator************************************************************************
485  friend inline const SubvectorIterator operator+( const SubvectorIterator& it, size_t inc ) {
486  return SubvectorIterator( it.iterator_ + inc, it.isAligned_ );
487  }
488  //*******************************************************************************************
489 
490  //**Addition operator************************************************************************
497  friend inline const SubvectorIterator operator+( size_t inc, const SubvectorIterator& it ) {
498  return SubvectorIterator( it.iterator_ + inc, it.isAligned_ );
499  }
500  //*******************************************************************************************
501 
502  //**Subtraction operator*********************************************************************
509  friend inline const SubvectorIterator operator-( const SubvectorIterator& it, size_t dec ) {
510  return SubvectorIterator( it.iterator_ - dec, it.isAligned_ );
511  }
512  //*******************************************************************************************
513 
514  //**Base function****************************************************************************
519  inline IteratorType base() const {
520  return iterator_;
521  }
522  //*******************************************************************************************
523 
524  //**IsAligned function***********************************************************************
529  inline bool isAligned() const {
530  return isAligned_;
531  }
532  //*******************************************************************************************
533 
534  private:
535  //**Member variables*************************************************************************
536  IteratorType iterator_;
537  bool isAligned_;
538  //*******************************************************************************************
539  };
540  //**********************************************************************************************
541 
542  //**Type definitions****************************************************************************
544  typedef SubvectorIterator< ConstIterator_<VT> > ConstIterator;
545 
547  typedef If_< IsConst<VT>, ConstIterator, SubvectorIterator< Iterator_<VT> > > Iterator;
548  //**********************************************************************************************
549 
550  //**Compilation flags***************************************************************************
552  enum : bool { simdEnabled = VT::simdEnabled };
553 
555  enum : bool { smpAssignable = VT::smpAssignable };
556  //**********************************************************************************************
557 
558  //**Constructors********************************************************************************
561  explicit inline Subvector( Operand vector, size_t index, size_t n );
562  // No explicitly declared copy constructor.
564  //**********************************************************************************************
565 
566  //**Destructor**********************************************************************************
567  // No explicitly declared destructor.
568  //**********************************************************************************************
569 
570  //**Data access functions***********************************************************************
573  inline Reference operator[]( size_t index );
574  inline ConstReference operator[]( size_t index ) const;
575  inline Reference at( size_t index );
576  inline ConstReference at( size_t index ) const;
577  inline Pointer data () noexcept;
578  inline ConstPointer data () const noexcept;
579  inline Iterator begin ();
580  inline ConstIterator begin () const;
581  inline ConstIterator cbegin() const;
582  inline Iterator end ();
583  inline ConstIterator end () const;
584  inline ConstIterator cend () const;
586  //**********************************************************************************************
587 
588  //**Assignment operators************************************************************************
591  inline Subvector& operator= ( const ElementType& rhs );
592  inline Subvector& operator= ( initializer_list<ElementType> list );
593  inline Subvector& operator= ( const Subvector& 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 Vector<VT2,TF>& rhs );
597  template< typename VT2 > inline Subvector& operator*=( const DenseVector<VT2,TF>& rhs );
598  template< typename VT2 > inline Subvector& operator*=( const SparseVector<VT2,TF>& rhs );
599  template< typename VT2 > inline Subvector& operator/=( const DenseVector<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 size_t size() const noexcept;
613  inline size_t capacity() const noexcept;
614  inline size_t nonZeros() const;
615  inline void reset();
617  //**********************************************************************************************
618 
619  //**Numeric functions***************************************************************************
622  template< typename Other > inline Subvector& scale( const Other& scalar );
624  //**********************************************************************************************
625 
626  private:
627  //**********************************************************************************************
629  template< typename VT2 >
630  struct VectorizedAssign {
631  enum : bool { value = useOptimizedKernels &&
632  simdEnabled && VT2::simdEnabled &&
633  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value };
634  };
635  //**********************************************************************************************
636 
637  //**********************************************************************************************
639  template< typename VT2 >
640  struct VectorizedAddAssign {
641  enum : bool { value = useOptimizedKernels &&
642  simdEnabled && VT2::simdEnabled &&
643  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
644  HasSIMDAdd< ElementType, ElementType_<VT2> >::value };
645  };
646  //**********************************************************************************************
647 
648  //**********************************************************************************************
650  template< typename VT2 >
651  struct VectorizedSubAssign {
652  enum : bool { value = useOptimizedKernels &&
653  simdEnabled && VT2::simdEnabled &&
654  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
655  HasSIMDSub< ElementType, ElementType_<VT2> >::value };
656  };
657  //**********************************************************************************************
658 
659  //**********************************************************************************************
661  template< typename VT2 >
662  struct VectorizedMultAssign {
663  enum : bool { value = useOptimizedKernels &&
664  simdEnabled && VT2::simdEnabled &&
665  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
666  HasSIMDMult< ElementType, ElementType_<VT2> >::value };
667  };
668  //**********************************************************************************************
669 
670  //**********************************************************************************************
672  template< typename VT2 >
673  struct VectorizedDivAssign {
674  enum : bool { value = useOptimizedKernels &&
675  simdEnabled && VT2::simdEnabled &&
676  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
677  HasSIMDDiv< ElementType, ElementType_<VT2> >::value };
678  };
679  //**********************************************************************************************
680 
681  //**SIMD properties*****************************************************************************
683  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
684  //**********************************************************************************************
685 
686  public:
687  //**Expression template evaluation functions****************************************************
690  template< typename Other >
691  inline bool canAlias( const Other* alias ) const noexcept;
692 
693  template< typename VT2, bool AF2, bool TF2 >
694  inline bool canAlias( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept;
695 
696  template< typename Other >
697  inline bool isAliased( const Other* alias ) const noexcept;
698 
699  template< typename VT2, bool AF2, bool TF2 >
700  inline bool isAliased( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept;
701 
702  inline bool isAligned () const noexcept;
703  inline bool canSMPAssign() const noexcept;
704 
705  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
706  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
707  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
708 
709  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
710  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
711  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
712  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
713 
714  template< typename VT2 >
715  inline DisableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
716 
717  template< typename VT2 >
718  inline EnableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
719 
720  template< typename VT2 > inline void assign( const SparseVector<VT2,TF>& rhs );
721 
722  template< typename VT2 >
723  inline DisableIf_< VectorizedAddAssign<VT2> > addAssign( const DenseVector <VT2,TF>& rhs );
724 
725  template< typename VT2 >
726  inline EnableIf_< VectorizedAddAssign<VT2> > addAssign ( const DenseVector <VT2,TF>& rhs );
727 
728  template< typename VT2 > inline void addAssign( const SparseVector<VT2,TF>& rhs );
729 
730  template< typename VT2 >
731  inline DisableIf_< VectorizedSubAssign<VT2> > subAssign ( const DenseVector <VT2,TF>& rhs );
732 
733  template< typename VT2 >
734  inline EnableIf_< VectorizedSubAssign<VT2> > subAssign( const DenseVector <VT2,TF>& rhs );
735 
736  template< typename VT2 > inline void subAssign( const SparseVector<VT2,TF>& rhs );
737 
738  template< typename VT2 >
739  inline DisableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
740 
741  template< typename VT2 >
742  inline EnableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
743 
744  template< typename VT2 > inline void multAssign( const SparseVector<VT2,TF>& rhs );
745 
746  template< typename VT2 >
747  inline DisableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
748 
749  template< typename VT2 >
750  inline EnableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
752  //**********************************************************************************************
753 
754  private:
755  //**Member variables****************************************************************************
758  Operand vector_;
759  const size_t offset_;
760  const size_t size_;
761  const bool isAligned_;
762 
769  //**********************************************************************************************
770 
771  //**Friend declarations*************************************************************************
772  template< typename VT2, bool AF2, bool TF2, bool DF2 > friend class Subvector;
773 
774  template< bool AF1, typename VT2, bool AF2, bool TF2, bool DF2 >
775  friend const Subvector<VT2,AF1,TF2,DF2>
776  subvector( const Subvector<VT2,AF2,TF2,DF2>& sv, size_t index, size_t size );
777 
778  template< typename VT2, bool AF2, bool TF2, bool DF2 >
779  friend bool isIntact( const Subvector<VT2,AF2,TF2,DF2>& sv ) noexcept;
780 
781  template< typename VT2, bool AF2, bool TF2, bool DF2 >
782  friend bool isSame( const Subvector<VT2,AF2,TF2,DF2>& a, const Vector<VT2,TF2>& b ) noexcept;
783 
784  template< typename VT2, bool AF2, bool TF2, bool DF2 >
785  friend bool isSame( const Vector<VT2,TF2>& a, const Subvector<VT2,AF2,TF2,DF2>& b ) noexcept;
786 
787  template< typename VT2, bool AF2, bool TF2, bool DF2 >
788  friend bool isSame( const Subvector<VT2,AF2,TF2,DF2>& a, const Subvector<VT2,AF2,TF2,DF2>& b ) noexcept;
789 
790  template< typename VT2, bool AF2, bool TF2, bool DF2, typename VT3 >
791  friend bool tryAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
792 
793  template< typename VT2, bool AF2, bool TF2, bool DF2, typename VT3 >
794  friend bool tryAddAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
795 
796  template< typename VT2, bool AF2, bool TF2, bool DF2, typename VT3 >
797  friend bool trySubAssign( const Subvector<VT2,AF2,DF2,TF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
798 
799  template< typename VT2, bool AF2, bool TF2, bool DF2, typename VT3 >
800  friend bool tryMultAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
801 
802  template< typename VT2, bool AF2, bool TF2, bool DF2 >
803  friend DerestrictTrait_< Subvector<VT2,AF2,TF2,DF2> > derestrict( Subvector<VT2,AF2,TF2,DF2>& sv );
804  //**********************************************************************************************
805 
806  //**Compile time checks*************************************************************************
812  //**********************************************************************************************
813 };
815 //*************************************************************************************************
816 
817 
818 
819 
820 //=================================================================================================
821 //
822 // CONSTRUCTOR
823 //
824 //=================================================================================================
825 
826 //*************************************************************************************************
839 template< typename VT // Type of the dense vector
840  , bool TF > // Transpose flag
841 inline Subvector<VT,unaligned,TF,true>::Subvector( Operand vector, size_t index, size_t n )
842  : vector_ ( vector ) // The vector containing the subvector
843  , offset_ ( index ) // The offset of the subvector within the dense vector
844  , size_ ( n ) // The size of the subvector
845  , isAligned_( simdEnabled && vector.data() != nullptr && checkAlignment( data() ) )
846 {
847  if( index + n > vector.size() ) {
848  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
849  }
850 }
852 //*************************************************************************************************
853 
854 
855 
856 
857 //=================================================================================================
858 //
859 // DATA ACCESS FUNCTIONS
860 //
861 //=================================================================================================
862 
863 //*************************************************************************************************
873 template< typename VT // Type of the dense vector
874  , bool TF > // Transpose flag
876  Subvector<VT,unaligned,TF,true>::operator[]( size_t index )
877 {
878  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
879  return vector_[offset_+index];
880 }
882 //*************************************************************************************************
883 
884 
885 //*************************************************************************************************
895 template< typename VT // Type of the dense vector
896  , bool TF > // Transpose flag
898  Subvector<VT,unaligned,TF,true>::operator[]( size_t index ) const
899 {
900  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
901  return const_cast<const VT&>( vector_ )[offset_+index];
902 }
904 //*************************************************************************************************
905 
906 
907 //*************************************************************************************************
918 template< typename VT // Type of the dense vector
919  , bool TF > // Transpose flag
921  Subvector<VT,unaligned,TF,true>::at( size_t index )
922 {
923  if( index >= size() ) {
924  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
925  }
926  return (*this)[index];
927 }
929 //*************************************************************************************************
930 
931 
932 //*************************************************************************************************
943 template< typename VT // Type of the dense vector
944  , bool TF > // Transpose flag
946  Subvector<VT,unaligned,TF,true>::at( size_t index ) const
947 {
948  if( index >= size() ) {
949  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
950  }
951  return (*this)[index];
952 }
954 //*************************************************************************************************
955 
956 
957 //*************************************************************************************************
965 template< typename VT // Type of the dense vector
966  , bool TF > // Transpose flag
967 inline typename Subvector<VT,unaligned,TF,true>::Pointer
968  Subvector<VT,unaligned,TF,true>::data() noexcept
969 {
970  return vector_.data() + offset_;
971 }
973 //*************************************************************************************************
974 
975 
976 //*************************************************************************************************
984 template< typename VT // Type of the dense vector
985  , bool TF > // Transpose flag
986 inline typename Subvector<VT,unaligned,TF,true>::ConstPointer
987  Subvector<VT,unaligned,TF,true>::data() const noexcept
988 {
989  return vector_.data() + offset_;
990 }
992 //*************************************************************************************************
993 
994 
995 //*************************************************************************************************
1003 template< typename VT // Type of the dense vector
1004  , bool TF > // Transpose flag
1007 {
1008  return Iterator( vector_.begin() + offset_, isAligned_ );
1009 }
1011 //*************************************************************************************************
1012 
1013 
1014 //*************************************************************************************************
1022 template< typename VT // Type of the dense vector
1023  , bool TF > // Transpose flag
1026 {
1027  return ConstIterator( vector_.cbegin() + offset_, isAligned_ );
1028 }
1030 //*************************************************************************************************
1031 
1032 
1033 //*************************************************************************************************
1041 template< typename VT // Type of the dense vector
1042  , bool TF > // Transpose flag
1045 {
1046  return ConstIterator( vector_.cbegin() + offset_, isAligned_ );
1047 }
1049 //*************************************************************************************************
1050 
1051 
1052 //*************************************************************************************************
1060 template< typename VT // Type of the dense vector
1061  , bool TF > // Transpose flag
1064 {
1065  return Iterator( vector_.begin() + offset_ + size_, isAligned_ );
1066 }
1068 //*************************************************************************************************
1069 
1070 
1071 //*************************************************************************************************
1079 template< typename VT // Type of the dense vector
1080  , bool TF > // Transpose flag
1083 {
1084  return ConstIterator( vector_.cbegin() + offset_ + size_, isAligned_ );
1085 }
1087 //*************************************************************************************************
1088 
1089 
1090 //*************************************************************************************************
1098 template< typename VT // Type of the dense vector
1099  , bool TF > // Transpose flag
1102 {
1103  return ConstIterator( vector_.cbegin() + offset_ + size_, isAligned_ );
1104 }
1106 //*************************************************************************************************
1107 
1108 
1109 
1110 
1111 //=================================================================================================
1112 //
1113 // ASSIGNMENT OPERATORS
1114 //
1115 //=================================================================================================
1116 
1117 //*************************************************************************************************
1124 template< typename VT // Type of the dense vector
1125  , bool TF > // Transpose flag
1126 inline Subvector<VT,unaligned,TF,true>&
1127  Subvector<VT,unaligned,TF,true>::operator=( const ElementType& rhs )
1128 {
1129  const size_t iend( offset_ + size_ );
1130 
1131  for( size_t i=offset_; i<iend; ++i )
1132  vector_[i] = rhs;
1133 
1134  return *this;
1135 }
1137 //*************************************************************************************************
1138 
1139 
1140 //*************************************************************************************************
1153 template< typename VT // Type of the dense vector
1154  , bool TF > // Transpose flag
1155 inline Subvector<VT,unaligned,TF,true>&
1156  Subvector<VT,unaligned,TF,true>::operator=( initializer_list<ElementType> list )
1157 {
1158  if( list.size() > size() ) {
1159  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to subvector" );
1160  }
1161 
1162  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
1163 
1164  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1165 
1166  return *this;
1167 }
1169 //*************************************************************************************************
1170 
1171 
1172 //*************************************************************************************************
1184 template< typename VT // Type of the dense vector
1185  , bool TF > // Transpose flag
1186 inline Subvector<VT,unaligned,TF,true>&
1187  Subvector<VT,unaligned,TF,true>::operator=( const Subvector& rhs )
1188 {
1191 
1192  if( &rhs == this || ( &vector_ == &rhs.vector_ && offset_ == rhs.offset_ ) )
1193  return *this;
1194 
1195  if( size() != rhs.size() ) {
1196  BLAZE_THROW_INVALID_ARGUMENT( "Subvector sizes do not match" );
1197  }
1198 
1199  if( !tryAssign( vector_, rhs, offset_ ) ) {
1200  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1201  }
1202 
1203  DerestrictTrait_<This> left( derestrict( *this ) );
1204 
1205  if( rhs.canAlias( &vector_ ) ) {
1206  const ResultType tmp( rhs );
1207  smpAssign( left, tmp );
1208  }
1209  else {
1210  smpAssign( left, rhs );
1211  }
1212 
1213  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1214 
1215  return *this;
1216 }
1218 //*************************************************************************************************
1219 
1220 
1221 //*************************************************************************************************
1233 template< typename VT // Type of the dense vector
1234  , bool TF > // Transpose flag
1235 template< typename VT2 > // Type of the right-hand side vector
1236 inline Subvector<VT,unaligned,TF,true>&
1237  Subvector<VT,unaligned,TF,true>::operator=( const Vector<VT2,TF>& rhs )
1238 {
1241 
1242  if( size() != (~rhs).size() ) {
1243  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1244  }
1245 
1246  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
1247  Right right( ~rhs );
1248 
1249  if( !tryAssign( vector_, right, offset_ ) ) {
1250  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1251  }
1252 
1253  DerestrictTrait_<This> left( derestrict( *this ) );
1254 
1255  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1256  const ResultType_<VT2> tmp( right );
1257  smpAssign( left, tmp );
1258  }
1259  else {
1260  if( IsSparseVector<VT2>::value )
1261  reset();
1262  smpAssign( left, right );
1263  }
1264 
1265  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1266 
1267  return *this;
1268 }
1270 //*************************************************************************************************
1271 
1272 
1273 //*************************************************************************************************
1285 template< typename VT // Type of the dense vector
1286  , bool TF > // Transpose flag
1287 template< typename VT2 > // Type of the right-hand side vector
1288 inline Subvector<VT,unaligned,TF,true>&
1289  Subvector<VT,unaligned,TF,true>::operator+=( const Vector<VT2,TF>& rhs )
1290 {
1293 
1294  if( size() != (~rhs).size() ) {
1295  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1296  }
1297 
1298  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
1299  Right right( ~rhs );
1300 
1301  if( !tryAddAssign( vector_, right, offset_ ) ) {
1302  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1303  }
1304 
1305  DerestrictTrait_<This> left( derestrict( *this ) );
1306 
1307  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1308  const ResultType_<VT2> tmp( right );
1309  smpAddAssign( left, tmp );
1310  }
1311  else {
1312  smpAddAssign( left, right );
1313  }
1314 
1315  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1316 
1317  return *this;
1318 }
1320 //*************************************************************************************************
1321 
1322 
1323 //*************************************************************************************************
1335 template< typename VT // Type of the dense vector
1336  , bool TF > // Transpose flag
1337 template< typename VT2 > // Type of the right-hand side vector
1338 inline Subvector<VT,unaligned,TF,true>&
1339  Subvector<VT,unaligned,TF,true>::operator-=( const Vector<VT2,TF>& rhs )
1340 {
1343 
1344  if( size() != (~rhs).size() ) {
1345  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1346  }
1347 
1348  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
1349  Right right( ~rhs );
1350 
1351  if( !trySubAssign( vector_, right, offset_ ) ) {
1352  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1353  }
1354 
1355  DerestrictTrait_<This> left( derestrict( *this ) );
1356 
1357  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1358  const ResultType_<VT2> tmp( right );
1359  smpSubAssign( left, tmp );
1360  }
1361  else {
1362  smpSubAssign( left, right );
1363  }
1364 
1365  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1366 
1367  return *this;
1368 }
1370 //*************************************************************************************************
1371 
1372 
1373 //*************************************************************************************************
1386 template< typename VT // Type of the dense vector
1387  , bool TF > // Transpose flag
1388 template< typename VT2 > // Type of the right-hand side dense vector
1389 inline Subvector<VT,unaligned,TF,true>&
1390  Subvector<VT,unaligned,TF,true>::operator*=( const DenseVector<VT2,TF>& rhs )
1391 {
1394 
1395  if( size() != (~rhs).size() ) {
1396  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1397  }
1398 
1399  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
1400  Right right( ~rhs );
1401 
1402  if( !tryMultAssign( vector_, right, offset_ ) ) {
1403  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1404  }
1405 
1406  DerestrictTrait_<This> left( derestrict( *this ) );
1407 
1408  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1409  const ResultType_<VT2> tmp( right );
1410  smpMultAssign( left, tmp );
1411  }
1412  else {
1413  smpMultAssign( left, right );
1414  }
1415 
1416  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1417 
1418  return *this;
1419 }
1421 //*************************************************************************************************
1422 
1423 
1424 //*************************************************************************************************
1437 template< typename VT // Type of the dense vector
1438  , bool TF > // Transpose flag
1439 template< typename VT2 > // Type of the right-hand side sparse vector
1440 inline Subvector<VT,unaligned,TF,true>&
1441  Subvector<VT,unaligned,TF,true>::operator*=( const SparseVector<VT2,TF>& rhs )
1442 {
1445 
1446  if( size() != (~rhs).size() ) {
1447  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1448  }
1449 
1450  const ResultType tmp( *this * (~rhs) );
1451 
1452  if( !tryAssign( vector_, tmp, offset_ ) ) {
1453  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1454  }
1455 
1456  DerestrictTrait_<This> left( derestrict( *this ) );
1457 
1458  smpAssign( left, tmp );
1459 
1460  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1461 
1462  return *this;
1463 }
1465 //*************************************************************************************************
1466 
1467 
1468 //*************************************************************************************************
1480 template< typename VT // Type of the dense vector
1481  , bool TF > // Transpose flag
1482 template< typename VT2 > // Type of the right-hand side dense vector
1483 inline Subvector<VT,unaligned,TF,true>&
1484  Subvector<VT,unaligned,TF,true>::operator/=( const DenseVector<VT2,TF>& rhs )
1485 {
1488 
1489  if( size() != (~rhs).size() ) {
1490  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1491  }
1492 
1493  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
1494  Right right( ~rhs );
1495 
1496  if( !tryDivAssign( vector_, right, offset_ ) ) {
1497  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1498  }
1499 
1500  DerestrictTrait_<This> left( derestrict( *this ) );
1501 
1502  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1503  const ResultType_<VT2> tmp( right );
1504  smpDivAssign( left, tmp );
1505  }
1506  else {
1507  smpDivAssign( left, right );
1508  }
1509 
1510  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1511 
1512  return *this;
1513 }
1515 //*************************************************************************************************
1516 
1517 
1518 //*************************************************************************************************
1526 template< typename VT // Type of the dense vector
1527  , bool TF > // Transpose flag
1528 template< typename Other > // Data type of the right-hand side scalar
1529 inline EnableIf_< IsNumeric<Other>, Subvector<VT,unaligned,TF,true> >&
1531 {
1532  DerestrictTrait_<This> left( derestrict( *this ) );
1533  smpAssign( left, (*this) * rhs );
1534 
1535  return *this;
1536 }
1538 //*************************************************************************************************
1539 
1540 
1541 //*************************************************************************************************
1551 template< typename VT // Type of the dense vector
1552  , bool TF > // Transpose flag
1553 template< typename Other > // Data type of the right-hand side scalar
1554 inline EnableIf_< IsNumeric<Other>, Subvector<VT,unaligned,TF,true> >&
1556 {
1557  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1558 
1559  DerestrictTrait_<This> left( derestrict( *this ) );
1560  smpAssign( left, (*this) / rhs );
1561 
1562  return *this;
1563 }
1565 //*************************************************************************************************
1566 
1567 
1568 
1569 
1570 //=================================================================================================
1571 //
1572 // UTILITY FUNCTIONS
1573 //
1574 //=================================================================================================
1575 
1576 //*************************************************************************************************
1582 template< typename VT // Type of the dense vector
1583  , bool TF > // Transpose flag
1584 inline size_t Subvector<VT,unaligned,TF,true>::size() const noexcept
1585 {
1586  return size_;
1587 }
1589 //*************************************************************************************************
1590 
1591 
1592 //*************************************************************************************************
1598 template< typename VT // Type of the dense vector
1599  , bool TF > // Transpose flag
1600 inline size_t Subvector<VT,unaligned,TF,true>::capacity() const noexcept
1601 {
1602  return vector_.capacity() - offset_;
1603 }
1605 //*************************************************************************************************
1606 
1607 
1608 //*************************************************************************************************
1617 template< typename VT // Type of the dense vector
1618  , bool TF > // Transpose flag
1619 inline size_t Subvector<VT,unaligned,TF,true>::nonZeros() const
1620 {
1621  size_t nonzeros( 0 );
1622 
1623  const size_t iend( offset_ + size_ );
1624  for( size_t i=offset_; i<iend; ++i ) {
1625  if( !isDefault( vector_[i] ) )
1626  ++nonzeros;
1627  }
1628 
1629  return nonzeros;
1630 }
1632 //*************************************************************************************************
1633 
1634 
1635 //*************************************************************************************************
1641 template< typename VT // Type of the dense vector
1642  , bool TF > // Transpose flag
1644 {
1645  using blaze::clear;
1646 
1647  const size_t iend( offset_ + size_ );
1648  for( size_t i=offset_; i<iend; ++i )
1649  clear( vector_[i] );
1650 }
1652 //*************************************************************************************************
1653 
1654 
1655 
1656 
1657 //=================================================================================================
1658 //
1659 // NUMERIC FUNCTIONS
1660 //
1661 //=================================================================================================
1662 
1663 //*************************************************************************************************
1670 template< typename VT // Type of the dense vector
1671  , bool TF > // Transpose flag
1672 template< typename Other > // Data type of the scalar value
1673 inline Subvector<VT,unaligned,TF,true>&
1674  Subvector<VT,unaligned,TF,true>::scale( const Other& scalar )
1675 {
1676  const size_t iend( offset_ + size_ );
1677  for( size_t i=offset_; i<iend; ++i )
1678  vector_[i] *= scalar;
1679  return *this;
1680 }
1682 //*************************************************************************************************
1683 
1684 
1685 
1686 
1687 //=================================================================================================
1688 //
1689 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1690 //
1691 //=================================================================================================
1692 
1693 //*************************************************************************************************
1704 template< typename VT // Type of the dense vector
1705  , bool TF > // Transpose flag
1706 template< typename Other > // Data type of the foreign expression
1707 inline bool Subvector<VT,unaligned,TF,true>::canAlias( const Other* alias ) const noexcept
1708 {
1709  return vector_.isAliased( alias );
1710 }
1712 //*************************************************************************************************
1713 
1714 
1715 //*************************************************************************************************
1726 template< typename VT // Type of the dense vector
1727  , bool TF > // Transpose flag
1728 template< typename VT2 // Data type of the foreign dense subvector
1729  , bool AF2 // Alignment flag of the foreign dense subvector
1730  , bool TF2 > // Transpose flag of the foreign dense subvector
1731 inline bool Subvector<VT,unaligned,TF,true>::canAlias( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept
1732 {
1733  return ( vector_.isAliased( &alias->vector_ ) &&
1734  ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
1735 }
1737 //*************************************************************************************************
1738 
1739 
1740 //*************************************************************************************************
1751 template< typename VT // Type of the dense vector
1752  , bool TF > // Transpose flag
1753 template< typename Other > // Data type of the foreign expression
1754 inline bool Subvector<VT,unaligned,TF,true>::isAliased( const Other* alias ) const noexcept
1755 {
1756  return vector_.isAliased( alias );
1757 }
1759 //*************************************************************************************************
1760 
1761 
1762 //*************************************************************************************************
1773 template< typename VT // Type of the dense vector
1774  , bool TF > // Transpose flag
1775 template< typename VT2 // Data type of the foreign dense subvector
1776  , bool AF2 // Alignment flag of the foreign dense subvector
1777  , bool TF2 > // Transpose flag of the foreign dense subvector
1778 inline bool Subvector<VT,unaligned,TF,true>::isAliased( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept
1779 {
1780  return ( vector_.isAliased( &alias->vector_ ) &&
1781  ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
1782 }
1784 //*************************************************************************************************
1785 
1786 
1787 //*************************************************************************************************
1797 template< typename VT // Type of the dense vector
1798  , bool TF > // Transpose flag
1799 inline bool Subvector<VT,unaligned,TF,true>::isAligned() const noexcept
1800 {
1801  return isAligned_;
1802 }
1804 //*************************************************************************************************
1805 
1806 
1807 //*************************************************************************************************
1818 template< typename VT // Type of the dense vector
1819  , bool TF > // Transpose flag
1820 inline bool Subvector<VT,unaligned,TF,true>::canSMPAssign() const noexcept
1821 {
1822  return ( size() > SMP_DVECASSIGN_THRESHOLD );
1823 }
1825 //*************************************************************************************************
1826 
1827 
1828 //*************************************************************************************************
1842 template< typename VT // Type of the dense vector
1843  , bool TF > // Transpose flag
1844 BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true>::SIMDType
1845  Subvector<VT,unaligned,TF,true>::load( size_t index ) const noexcept
1846 {
1847  if( isAligned_ )
1848  return loada( index );
1849  else
1850  return loadu( index );
1851 }
1853 //*************************************************************************************************
1854 
1855 
1856 //*************************************************************************************************
1870 template< typename VT // Type of the dense vector
1871  , bool TF > // Transpose flag
1872 BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true>::SIMDType
1873  Subvector<VT,unaligned,TF,true>::loada( size_t index ) const noexcept
1874 {
1876 
1877  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
1878  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
1879  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
1880 
1881  return vector_.loada( offset_+index );
1882 }
1884 //*************************************************************************************************
1885 
1886 
1887 //*************************************************************************************************
1901 template< typename VT // Type of the dense vector
1902  , bool TF > // Transpose flag
1903 BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true>::SIMDType
1904  Subvector<VT,unaligned,TF,true>::loadu( size_t index ) const noexcept
1905 {
1907 
1908  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
1909  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
1910  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
1911 
1912  return vector_.loadu( offset_+index );
1913 }
1915 //*************************************************************************************************
1916 
1917 
1918 //*************************************************************************************************
1933 template< typename VT // Type of the dense vector
1934  , bool TF > // Transpose flag
1936  Subvector<VT,unaligned,TF,true>::store( size_t index, const SIMDType& value ) noexcept
1937 {
1938  if( isAligned_ )
1939  storea( index, value );
1940  else
1941  storeu( index, value );
1942 }
1944 //*************************************************************************************************
1945 
1946 
1947 //*************************************************************************************************
1962 template< typename VT // Type of the dense vector
1963  , bool TF > // Transpose flag
1965  Subvector<VT,unaligned,TF,true>::storea( size_t index, const SIMDType& value ) noexcept
1966 {
1968 
1969  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
1970  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
1971  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
1972 
1973  vector_.storea( offset_+index, value );
1974 }
1976 //*************************************************************************************************
1977 
1978 
1979 //*************************************************************************************************
1994 template< typename VT // Type of the dense vector
1995  , bool TF > // Transpose flag
1997  Subvector<VT,unaligned,TF,true>::storeu( size_t index, const SIMDType& value ) noexcept
1998 {
2000 
2001  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
2002  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
2003  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
2004 
2005  vector_.storeu( offset_+index, value );
2006 }
2008 //*************************************************************************************************
2009 
2010 
2011 //*************************************************************************************************
2026 template< typename VT // Type of the dense vector
2027  , bool TF > // Transpose flag
2029  Subvector<VT,unaligned,TF,true>::stream( size_t index, const SIMDType& value ) noexcept
2030 {
2032 
2033  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
2034  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
2035  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
2036 
2037  if( isAligned_ )
2038  vector_.stream( offset_+index, value );
2039  else
2040  vector_.storeu( offset_+index, value );
2041 }
2043 //*************************************************************************************************
2044 
2045 
2046 //*************************************************************************************************
2058 template< typename VT // Type of the dense vector
2059  , bool TF > // Transpose flag
2060 template< typename VT2 > // Type of the right-hand side dense vector
2061 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
2062  Subvector<VT,unaligned,TF,true>::assign( const DenseVector<VT2,TF>& rhs )
2063 {
2064  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2065 
2066  const size_t ipos( size() & size_t(-2) );
2067  for( size_t i=0UL; i<ipos; i+=2UL ) {
2068  vector_[offset_+i ] = (~rhs)[i ];
2069  vector_[offset_+i+1UL] = (~rhs)[i+1UL];
2070  }
2071  if( ipos < size() ) {
2072  vector_[offset_+ipos] = (~rhs)[ipos];
2073  }
2074 }
2076 //*************************************************************************************************
2077 
2078 
2079 //*************************************************************************************************
2091 template< typename VT // Type of the dense vector
2092  , bool TF > // Transpose flag
2093 template< typename VT2 > // Type of the right-hand side dense vector
2094 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
2095  Subvector<VT,unaligned,TF,true>::assign( const DenseVector<VT2,TF>& rhs )
2096 {
2098 
2099  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2100 
2101  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2102  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2103 
2104  size_t i( 0UL );
2105  Iterator left( begin() );
2106  ConstIterator_<VT2> right( (~rhs).begin() );
2107 
2108  if( useStreaming && isAligned_ &&
2109  ( size_ > ( cacheSize/( sizeof(ElementType) * 3UL ) ) ) &&
2110  !(~rhs).isAliased( &vector_ ) )
2111  {
2112  for( ; i<ipos; i+=SIMDSIZE ) {
2113  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2114  }
2115  for( ; i<size_; ++i ) {
2116  *left = *right;
2117  }
2118  }
2119  else
2120  {
2121  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2122  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2123  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2124  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2125  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2126  }
2127  for( ; i<ipos; i+=SIMDSIZE ) {
2128  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2129  }
2130  for( ; i<size_; ++i ) {
2131  *left = *right; ++left; ++right;
2132  }
2133  }
2134 }
2136 //*************************************************************************************************
2137 
2138 
2139 //*************************************************************************************************
2151 template< typename VT // Type of the dense vector
2152  , bool TF > // Transpose flag
2153 template< typename VT2 > // Type of the right-hand side sparse vector
2154 inline void Subvector<VT,unaligned,TF,true>::assign( const SparseVector<VT2,TF>& rhs )
2155 {
2156  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2157 
2158  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2159  vector_[offset_+element->index()] = element->value();
2160 }
2162 //*************************************************************************************************
2163 
2164 
2165 //*************************************************************************************************
2177 template< typename VT // Type of the dense vector
2178  , bool TF > // Transpose flag
2179 template< typename VT2 > // Type of the right-hand side dense vector
2180 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
2181  Subvector<VT,unaligned,TF,true>::addAssign( const DenseVector<VT2,TF>& rhs )
2182 {
2183  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2184 
2185  const size_t ipos( size() & size_t(-2) );
2186  for( size_t i=0UL; i<ipos; i+=2UL ) {
2187  vector_[offset_+i ] += (~rhs)[i ];
2188  vector_[offset_+i+1UL] += (~rhs)[i+1UL];
2189  }
2190  if( ipos < size() ) {
2191  vector_[offset_+ipos] += (~rhs)[ipos];
2192  }
2193 }
2195 //*************************************************************************************************
2196 
2197 
2198 //*************************************************************************************************
2210 template< typename VT // Type of the dense vector
2211  , bool TF > // Transpose flag
2212 template< typename VT2 > // Type of the right-hand side dense vector
2213 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
2214  Subvector<VT,unaligned,TF,true>::addAssign( const DenseVector<VT2,TF>& rhs )
2215 {
2217 
2218  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2219 
2220  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2221  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2222 
2223  size_t i( 0UL );
2224  Iterator left( begin() );
2225  ConstIterator_<VT2> right( (~rhs).begin() );
2226 
2227  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2228  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2229  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2230  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2231  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2232  }
2233  for( ; i<ipos; i+=SIMDSIZE ) {
2234  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2235  }
2236  for( ; i<size_; ++i ) {
2237  *left += *right; ++left; ++right;
2238  }
2239 }
2241 //*************************************************************************************************
2242 
2243 
2244 //*************************************************************************************************
2256 template< typename VT // Type of the dense vector
2257  , bool TF > // Transpose flag
2258 template< typename VT2 > // Type of the right-hand side sparse vector
2259 inline void Subvector<VT,unaligned,TF,true>::addAssign( const SparseVector<VT2,TF>& rhs )
2260 {
2261  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2262 
2263  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2264  vector_[offset_+element->index()] += element->value();
2265 }
2267 //*************************************************************************************************
2268 
2269 
2270 //*************************************************************************************************
2282 template< typename VT // Type of the dense vector
2283  , bool TF > // Transpose flag
2284 template< typename VT2 > // Type of the right-hand side dense vector
2285 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
2286  Subvector<VT,unaligned,TF,true>::subAssign( const DenseVector<VT2,TF>& rhs )
2287 {
2288  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2289 
2290  const size_t ipos( size() & size_t(-2) );
2291  for( size_t i=0UL; i<ipos; i+=2UL ) {
2292  vector_[offset_+i ] -= (~rhs)[i ];
2293  vector_[offset_+i+1UL] -= (~rhs)[i+1UL];
2294  }
2295  if( ipos < size() ) {
2296  vector_[offset_+ipos] -= (~rhs)[ipos];
2297  }
2298 }
2300 //*************************************************************************************************
2301 
2302 
2303 //*************************************************************************************************
2315 template< typename VT // Type of the dense vector
2316  , bool TF > // Transpose flag
2317 template< typename VT2 > // Type of the right-hand side dense vector
2318 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
2319  Subvector<VT,unaligned,TF,true>::subAssign( const DenseVector<VT2,TF>& rhs )
2320 {
2322 
2323  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2324 
2325  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2326  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2327 
2328  size_t i( 0UL );
2329  Iterator left( begin() );
2330  ConstIterator_<VT2> right( (~rhs).begin() );
2331 
2332  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2333  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2334  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2335  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2336  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2337  }
2338  for( ; i<ipos; i+=SIMDSIZE ) {
2339  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2340  }
2341  for( ; i<size_; ++i ) {
2342  *left -= *right; ++left; ++right;
2343  }
2344 }
2346 //*************************************************************************************************
2347 
2348 
2349 //*************************************************************************************************
2361 template< typename VT // Type of the dense vector
2362  , bool TF > // Transpose flag
2363 template< typename VT2 > // Type of the right-hand side sparse vector
2364 inline void Subvector<VT,unaligned,TF,true>::subAssign( const SparseVector<VT2,TF>& rhs )
2365 {
2366  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2367 
2368  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2369  vector_[offset_+element->index()] -= element->value();
2370 }
2372 //*************************************************************************************************
2373 
2374 
2375 //*************************************************************************************************
2387 template< typename VT // Type of the dense vector
2388  , bool TF > // Transpose flag
2389 template< typename VT2 > // Type of the right-hand side dense vector
2390 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
2391  Subvector<VT,unaligned,TF,true>::multAssign( const DenseVector<VT2,TF>& rhs )
2392 {
2393  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2394 
2395  const size_t ipos( size() & size_t(-2) );
2396  for( size_t i=0UL; i<ipos; i+=2UL ) {
2397  vector_[offset_+i ] *= (~rhs)[i ];
2398  vector_[offset_+i+1UL] *= (~rhs)[i+1UL];
2399  }
2400  if( ipos < size() ) {
2401  vector_[offset_+ipos] *= (~rhs)[ipos];
2402  }
2403 }
2405 //*************************************************************************************************
2406 
2407 
2408 //*************************************************************************************************
2420 template< typename VT // Type of the dense vector
2421  , bool TF > // Transpose flag
2422 template< typename VT2 > // Type of the right-hand side dense vector
2423 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
2424  Subvector<VT,unaligned,TF,true>::multAssign( const DenseVector<VT2,TF>& rhs )
2425 {
2427 
2428  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2429 
2430  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2431  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2432 
2433  size_t i( 0UL );
2434  Iterator left( begin() );
2435  ConstIterator_<VT2> right( (~rhs).begin() );
2436 
2437  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2438  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2439  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2440  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2441  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2442  }
2443  for( ; i<ipos; i+=SIMDSIZE ) {
2444  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2445  }
2446  for( ; i<size_; ++i ) {
2447  *left *= *right; ++left; ++right;
2448  }
2449 }
2451 //*************************************************************************************************
2452 
2453 
2454 //*************************************************************************************************
2466 template< typename VT // Type of the dense vector
2467  , bool TF > // Transpose flag
2468 template< typename VT2 > // Type of the right-hand side sparse vector
2469 inline void Subvector<VT,unaligned,TF,true>::multAssign( const SparseVector<VT2,TF>& rhs )
2470 {
2471  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2472 
2473  const ResultType tmp( serial( *this ) );
2474 
2475  reset();
2476 
2477  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2478  vector_[offset_+element->index()] = tmp[element->index()] * element->value();
2479 }
2481 //*************************************************************************************************
2482 
2483 
2484 //*************************************************************************************************
2496 template< typename VT // Type of the dense vector
2497  , bool TF > // Transpose flag
2498 template< typename VT2 > // Type of the right-hand side dense vector
2499 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
2500  Subvector<VT,unaligned,TF,true>::divAssign( const DenseVector<VT2,TF>& rhs )
2501 {
2502  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2503 
2504  const size_t ipos( size() & size_t(-2) );
2505  for( size_t i=0UL; i<ipos; i+=2UL ) {
2506  vector_[offset_+i ] /= (~rhs)[i ];
2507  vector_[offset_+i+1UL] /= (~rhs)[i+1UL];
2508  }
2509  if( ipos < size() ) {
2510  vector_[offset_+ipos] /= (~rhs)[ipos];
2511  }
2512 }
2514 //*************************************************************************************************
2515 
2516 
2517 //*************************************************************************************************
2529 template< typename VT // Type of the dense vector
2530  , bool TF > // Transpose flag
2531 template< typename VT2 > // Type of the right-hand side dense vector
2532 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
2533  Subvector<VT,unaligned,TF,true>::divAssign( const DenseVector<VT2,TF>& rhs )
2534 {
2536 
2537  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2538 
2539  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2540  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2541 
2542  size_t i( 0UL );
2543  Iterator left( begin() );
2544  ConstIterator_<VT2> right( (~rhs).begin() );
2545 
2546  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2547  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2548  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2549  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2550  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2551  }
2552  for( ; i<ipos; i+=SIMDSIZE ) {
2553  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2554  }
2555  for( ; i<size_; ++i ) {
2556  *left /= *right; ++left; ++right;
2557  }
2558 }
2560 //*************************************************************************************************
2561 
2562 
2563 
2564 
2565 
2566 
2567 
2568 
2569 //=================================================================================================
2570 //
2571 // CLASS TEMPLATE SPECIALIZATION FOR ALIGNED DENSE SUBVECTORS
2572 //
2573 //=================================================================================================
2574 
2575 //*************************************************************************************************
2583 template< typename VT // Type of the dense vector
2584  , bool TF > // Transpose flag
2585 class Subvector<VT,aligned,TF,true>
2586  : public DenseVector< Subvector<VT,aligned,TF,true>, TF >
2587  , private View
2588 {
2589  private:
2590  //**Type definitions****************************************************************************
2592  typedef If_< IsExpression<VT>, VT, VT& > Operand;
2593  //**********************************************************************************************
2594 
2595  public:
2596  //**Type definitions****************************************************************************
2597  typedef Subvector<VT,aligned,TF,true> This;
2598  typedef DenseVector<This,TF> BaseType;
2599  typedef SubvectorTrait_<VT> ResultType;
2600  typedef TransposeType_<ResultType> TransposeType;
2601  typedef ElementType_<VT> ElementType;
2602  typedef SIMDTrait_<ElementType> SIMDType;
2603  typedef ReturnType_<VT> ReturnType;
2604  typedef const Subvector& CompositeType;
2605 
2607  typedef ConstReference_<VT> ConstReference;
2608 
2610  typedef If_< IsConst<VT>, ConstReference, Reference_<VT> > Reference;
2611 
2613  typedef const ElementType* ConstPointer;
2614 
2616  typedef If_< Or< IsConst<VT>, Not< HasMutableDataAccess<VT> > >, ConstPointer, ElementType* > Pointer;
2617 
2619  typedef ConstIterator_<VT> ConstIterator;
2620 
2622  typedef If_< IsConst<VT>, ConstIterator, Iterator_<VT> > Iterator;
2623  //**********************************************************************************************
2624 
2625  //**Compilation flags***************************************************************************
2627  enum : bool { simdEnabled = VT::simdEnabled };
2628 
2630  enum : bool { smpAssignable = VT::smpAssignable };
2631  //**********************************************************************************************
2632 
2633  //**Constructors********************************************************************************
2636  explicit inline Subvector( Operand vector, size_t index, size_t n );
2637  // No explicitly declared copy constructor.
2639  //**********************************************************************************************
2640 
2641  //**Destructor**********************************************************************************
2642  // No explicitly declared destructor.
2643  //**********************************************************************************************
2644 
2645  //**Data access functions***********************************************************************
2648  inline Reference operator[]( size_t index );
2649  inline ConstReference operator[]( size_t index ) const;
2650  inline Reference at( size_t index );
2651  inline ConstReference at( size_t index ) const;
2652  inline Pointer data () noexcept;
2653  inline ConstPointer data () const noexcept;
2654  inline Iterator begin ();
2655  inline ConstIterator begin () const;
2656  inline ConstIterator cbegin() const;
2657  inline Iterator end ();
2658  inline ConstIterator end () const;
2659  inline ConstIterator cend () const;
2661  //**********************************************************************************************
2662 
2663  //**Assignment operators************************************************************************
2666  inline Subvector& operator= ( const ElementType& rhs );
2667  inline Subvector& operator= ( initializer_list<ElementType> list );
2668  inline Subvector& operator= ( const Subvector& rhs );
2669  template< typename VT2 > inline Subvector& operator= ( const Vector<VT2,TF>& rhs );
2670  template< typename VT2 > inline Subvector& operator+=( const Vector<VT2,TF>& rhs );
2671  template< typename VT2 > inline Subvector& operator-=( const Vector<VT2,TF>& rhs );
2672  template< typename VT2 > inline Subvector& operator*=( const DenseVector<VT2,TF>& rhs );
2673  template< typename VT2 > inline Subvector& operator*=( const SparseVector<VT2,TF>& rhs );
2674  template< typename VT2 > inline Subvector& operator/=( const DenseVector<VT2,TF>& rhs );
2675 
2676  template< typename Other >
2677  inline EnableIf_< IsNumeric<Other>, Subvector >& operator*=( Other rhs );
2678 
2679  template< typename Other >
2680  inline EnableIf_< IsNumeric<Other>, Subvector >& operator/=( Other rhs );
2682  //**********************************************************************************************
2683 
2684  //**Utility functions***************************************************************************
2687  inline size_t size() const noexcept;
2688  inline size_t capacity() const noexcept;
2689  inline size_t nonZeros() const;
2690  inline void reset();
2692  //**********************************************************************************************
2693 
2694  //**Numeric functions***************************************************************************
2697  template< typename Other > inline Subvector& scale( const Other& scalar );
2699  //**********************************************************************************************
2700 
2701  private:
2702  //**********************************************************************************************
2704  template< typename VT2 >
2705  struct VectorizedAssign {
2706  enum : bool { value = useOptimizedKernels &&
2707  simdEnabled && VT2::simdEnabled &&
2708  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value };
2709  };
2710  //**********************************************************************************************
2711 
2712  //**********************************************************************************************
2714  template< typename VT2 >
2715  struct VectorizedAddAssign {
2716  enum : bool { value = useOptimizedKernels &&
2717  simdEnabled && VT2::simdEnabled &&
2718  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2719  HasSIMDAdd< ElementType, ElementType_<VT2> >::value };
2720  };
2721  //**********************************************************************************************
2722 
2723  //**********************************************************************************************
2725  template< typename VT2 >
2726  struct VectorizedSubAssign {
2727  enum : bool { value = useOptimizedKernels &&
2728  simdEnabled && VT2::simdEnabled &&
2729  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2730  HasSIMDSub< ElementType, ElementType_<VT2> >::value };
2731  };
2732  //**********************************************************************************************
2733 
2734  //**********************************************************************************************
2736  template< typename VT2 >
2737  struct VectorizedMultAssign {
2738  enum : bool { value = useOptimizedKernels &&
2739  simdEnabled && VT2::simdEnabled &&
2740  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2741  HasSIMDMult< ElementType, ElementType_<VT2> >::value };
2742  };
2743  //**********************************************************************************************
2744 
2745  //**********************************************************************************************
2747  template< typename VT2 >
2748  struct VectorizedDivAssign {
2749  enum : bool { value = useOptimizedKernels &&
2750  simdEnabled && VT2::simdEnabled &&
2751  IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2752  HasSIMDDiv< ElementType, ElementType_<VT2> >::value };
2753  };
2754  //**********************************************************************************************
2755 
2756  //**SIMD properties*****************************************************************************
2758  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
2759  //**********************************************************************************************
2760 
2761  public:
2762  //**Expression template evaluation functions****************************************************
2765  template< typename Other >
2766  inline bool canAlias( const Other* alias ) const noexcept;
2767 
2768  template< typename VT2, bool AF2, bool TF2 >
2769  inline bool canAlias( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept;
2770 
2771  template< typename Other >
2772  inline bool isAliased( const Other* alias ) const noexcept;
2773 
2774  template< typename VT2, bool AF2, bool TF2 >
2775  inline bool isAliased( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept;
2776 
2777  inline bool isAligned () const noexcept;
2778  inline bool canSMPAssign() const noexcept;
2779 
2780  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
2781  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
2782  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
2783 
2784  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
2785  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
2786  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
2787  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
2788 
2789  template< typename VT2 >
2790  inline DisableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
2791 
2792  template< typename VT2 >
2793  inline EnableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
2794 
2795  template< typename VT2 > inline void assign( const SparseVector<VT2,TF>& rhs );
2796 
2797  template< typename VT2 >
2798  inline DisableIf_< VectorizedAddAssign<VT2> > addAssign( const DenseVector <VT2,TF>& rhs );
2799 
2800  template< typename VT2 >
2801  inline EnableIf_< VectorizedAddAssign<VT2> > addAssign ( const DenseVector <VT2,TF>& rhs );
2802 
2803  template< typename VT2 > inline void addAssign( const SparseVector<VT2,TF>& rhs );
2804 
2805  template< typename VT2 >
2806  inline DisableIf_< VectorizedSubAssign<VT2> > subAssign ( const DenseVector <VT2,TF>& rhs );
2807 
2808  template< typename VT2 >
2809  inline EnableIf_< VectorizedSubAssign<VT2> > subAssign( const DenseVector <VT2,TF>& rhs );
2810 
2811  template< typename VT2 > inline void subAssign( const SparseVector<VT2,TF>& rhs );
2812 
2813  template< typename VT2 >
2814  inline DisableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
2815 
2816  template< typename VT2 >
2817  inline EnableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
2818 
2819  template< typename VT2 > inline void multAssign( const SparseVector<VT2,TF>& rhs );
2820 
2821  template< typename VT2 >
2822  inline DisableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
2823 
2824  template< typename VT2 >
2825  inline EnableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
2827  //**********************************************************************************************
2828 
2829  private:
2830  //**Member variables****************************************************************************
2833  Operand vector_;
2834  const size_t offset_;
2835  const size_t size_;
2836 
2837  //**********************************************************************************************
2838 
2839  //**Friend declarations*************************************************************************
2840  template< typename VT2, bool AF2, bool TF2, bool DF2 > friend class Subvector;
2841 
2842  template< bool AF1, typename VT2, bool AF2, bool TF2, bool DF2 >
2843  friend const Subvector<VT2,AF1,TF2,DF2>
2844  subvector( const Subvector<VT2,AF2,TF2,DF2>& sv, size_t index, size_t size );
2845 
2846  template< typename VT2, bool AF2, bool TF2, bool DF2 >
2847  friend bool isIntact( const Subvector<VT2,AF2,TF2,DF2>& sv ) noexcept;
2848 
2849  template< typename VT2, bool AF2, bool TF2, bool DF2 >
2850  friend bool isSame( const Subvector<VT2,AF2,TF2,DF2>& a, const Vector<VT2,TF2>& b ) noexcept;
2851 
2852  template< typename VT2, bool AF2, bool TF2, bool DF2 >
2853  friend bool isSame( const Vector<VT2,TF2>& a, const Subvector<VT2,AF2,TF2,DF2>& b ) noexcept;
2854 
2855  template< typename VT2, bool AF2, bool TF2, bool DF2 >
2856  friend bool isSame( const Subvector<VT2,AF2,TF2,DF2>& a, const Subvector<VT2,AF2,TF2,DF2>& b ) noexcept;
2857 
2858  template< typename VT2, bool AF2, bool TF2, bool DF2, typename VT3 >
2859  friend bool tryAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
2860 
2861  template< typename VT2, bool AF2, bool TF2, bool DF2, typename VT3 >
2862  friend bool tryAddAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
2863 
2864  template< typename VT2, bool AF2, bool TF2, bool DF2, typename VT3 >
2865  friend bool trySubAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
2866 
2867  template< typename VT2, bool AF2, bool TF2, bool DF2, typename VT3 >
2868  friend bool tryMultAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
2869 
2870  template< typename VT2, bool AF2, bool TF2, bool DF2 >
2871  friend DerestrictTrait_< Subvector<VT2,AF2,TF2,DF2> > derestrict( Subvector<VT2,AF2,TF2,DF2>& sv );
2872  //**********************************************************************************************
2873 
2874  //**Compile time checks*************************************************************************
2880  //**********************************************************************************************
2881 };
2883 //*************************************************************************************************
2884 
2885 
2886 
2887 
2888 //=================================================================================================
2889 //
2890 // CONSTRUCTOR
2891 //
2892 //=================================================================================================
2893 
2894 //*************************************************************************************************
2907 template< typename VT // Type of the dense vector
2908  , bool TF > // Transpose flag
2909 inline Subvector<VT,aligned,TF,true>::Subvector( Operand vector, size_t index, size_t n )
2910  : vector_( vector ) // The vector containing the subvector
2911  , offset_( index ) // The offset of the subvector within the dense vector
2912  , size_ ( n ) // The size of the subvector
2913 {
2914  if( index + n > vector.size() ) {
2915  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
2916  }
2917 
2918  if( simdEnabled && vector_.data() != nullptr && !checkAlignment( data() ) ) {
2919  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector alignment" );
2920  }
2921 }
2923 //*************************************************************************************************
2924 
2925 
2926 
2927 
2928 //=================================================================================================
2929 //
2930 // DATA ACCESS FUNCTIONS
2931 //
2932 //=================================================================================================
2933 
2934 //*************************************************************************************************
2941 template< typename VT // Type of the dense vector
2942  , bool TF > // Transpose flag
2944  Subvector<VT,aligned,TF,true>::operator[]( size_t index )
2945 {
2946  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
2947  return vector_[offset_+index];
2948 }
2950 //*************************************************************************************************
2951 
2952 
2953 //*************************************************************************************************
2960 template< typename VT // Type of the dense vector
2961  , bool TF > // Transpose flag
2963  Subvector<VT,aligned,TF,true>::operator[]( size_t index ) const
2964 {
2965  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
2966  return const_cast<const VT&>( vector_ )[offset_+index];
2967 }
2969 //*************************************************************************************************
2970 
2971 
2972 //*************************************************************************************************
2983 template< typename VT // Type of the dense vector
2984  , bool TF > // Transpose flag
2986  Subvector<VT,aligned,TF,true>::at( size_t index )
2987 {
2988  if( index >= size() ) {
2989  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
2990  }
2991  return (*this)[index];
2992 }
2994 //*************************************************************************************************
2995 
2996 
2997 //*************************************************************************************************
3008 template< typename VT // Type of the dense vector
3009  , bool TF > // Transpose flag
3011  Subvector<VT,aligned,TF,true>::at( size_t index ) const
3012 {
3013  if( index >= size() ) {
3014  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
3015  }
3016  return (*this)[index];
3017 }
3019 //*************************************************************************************************
3020 
3021 
3022 //*************************************************************************************************
3030 template< typename VT // Type of the dense vector
3031  , bool TF > // Transpose flag
3032 inline typename Subvector<VT,aligned,TF,true>::Pointer Subvector<VT,aligned,TF,true>::data() noexcept
3033 {
3034  return vector_.data() + offset_;
3035 }
3037 //*************************************************************************************************
3038 
3039 
3040 //*************************************************************************************************
3048 template< typename VT // Type of the dense vector
3049  , bool TF > // Transpose flag
3050 inline typename Subvector<VT,aligned,TF,true>::ConstPointer
3051  Subvector<VT,aligned,TF,true>::data() const noexcept
3052 {
3053  return vector_.data() + offset_;
3054 }
3056 //*************************************************************************************************
3057 
3058 
3059 //*************************************************************************************************
3067 template< typename VT // Type of the dense vector
3068  , bool TF > // Transpose flag
3070 {
3071  return ( vector_.begin() + offset_ );
3072 }
3074 //*************************************************************************************************
3075 
3076 
3077 //*************************************************************************************************
3085 template< typename VT // Type of the dense vector
3086  , bool TF > // Transpose flag
3089 {
3090  return ( vector_.cbegin() + offset_ );
3091 }
3093 //*************************************************************************************************
3094 
3095 
3096 //*************************************************************************************************
3104 template< typename VT // Type of the dense vector
3105  , bool TF > // Transpose flag
3108 {
3109  return ( vector_.cbegin() + offset_ );
3110 }
3112 //*************************************************************************************************
3113 
3114 
3115 //*************************************************************************************************
3123 template< typename VT // Type of the dense vector
3124  , bool TF > // Transpose flag
3126 {
3127  return ( vector_.begin() + offset_ + size_ );
3128 }
3130 //*************************************************************************************************
3131 
3132 
3133 //*************************************************************************************************
3141 template< typename VT // Type of the dense vector
3142  , bool TF > // Transpose flag
3145 {
3146  return ( vector_.cbegin() + offset_ + size_ );
3147 }
3149 //*************************************************************************************************
3150 
3151 
3152 //*************************************************************************************************
3160 template< typename VT // Type of the dense vector
3161  , bool TF > // Transpose flag
3164 {
3165  return ( vector_.cbegin() + offset_ + size_ );
3166 }
3168 //*************************************************************************************************
3169 
3170 
3171 
3172 
3173 //=================================================================================================
3174 //
3175 // ASSIGNMENT OPERATORS
3176 //
3177 //=================================================================================================
3178 
3179 //*************************************************************************************************
3186 template< typename VT // Type of the dense vector
3187  , bool TF > // Transpose flag
3188 inline Subvector<VT,aligned,TF,true>&
3189  Subvector<VT,aligned,TF,true>::operator=( const ElementType& rhs )
3190 {
3191  const size_t iend( offset_ + size_ );
3192 
3193  for( size_t i=offset_; i<iend; ++i )
3194  vector_[i] = rhs;
3195 
3196  return *this;
3197 }
3199 //*************************************************************************************************
3200 
3201 
3202 //*************************************************************************************************
3215 template< typename VT // Type of the dense vector
3216  , bool TF > // Transpose flag
3217 inline Subvector<VT,aligned,TF,true>&
3218  Subvector<VT,aligned,TF,true>::operator=( initializer_list<ElementType> list )
3219 {
3220  if( list.size() > size() ) {
3221  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to subvector" );
3222  }
3223 
3224  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
3225 
3226  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3227 
3228  return *this;
3229 }
3231 //*************************************************************************************************
3232 
3233 
3234 //*************************************************************************************************
3246 template< typename VT // Type of the dense vector
3247  , bool TF > // Transpose flag
3248 inline Subvector<VT,aligned,TF,true>&
3249  Subvector<VT,aligned,TF,true>::operator=( const Subvector& rhs )
3250 {
3253 
3254  if( &rhs == this || ( &vector_ == &rhs.vector_ && offset_ == rhs.offset_ ) )
3255  return *this;
3256 
3257  if( size() != rhs.size() ) {
3258  BLAZE_THROW_INVALID_ARGUMENT( "Subvector sizes do not match" );
3259  }
3260 
3261  if( !tryAssign( vector_, rhs, offset_ ) ) {
3262  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3263  }
3264 
3265  DerestrictTrait_<This> left( derestrict( *this ) );
3266 
3267  if( rhs.canAlias( &vector_ ) ) {
3268  const ResultType tmp( ~rhs );
3269  smpAssign( left, tmp );
3270  }
3271  else {
3272  smpAssign( left, rhs );
3273  }
3274 
3275  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3276 
3277  return *this;
3278 }
3280 //*************************************************************************************************
3281 
3282 
3283 //*************************************************************************************************
3295 template< typename VT // Type of the dense vector
3296  , bool TF > // Transpose flag
3297 template< typename VT2 > // Type of the right-hand side vector
3298 inline Subvector<VT,aligned,TF,true>&
3299  Subvector<VT,aligned,TF,true>::operator=( const Vector<VT2,TF>& rhs )
3300 {
3303 
3304  if( size() != (~rhs).size() ) {
3305  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3306  }
3307 
3308  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
3309  Right right( ~rhs );
3310 
3311  if( !tryAssign( vector_, right, offset_ ) ) {
3312  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3313  }
3314 
3315  DerestrictTrait_<This> left( derestrict( *this ) );
3316 
3317  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3318  const ResultType_<VT2> tmp( right );
3319  smpAssign( left, tmp );
3320  }
3321  else {
3322  if( IsSparseVector<VT2>::value )
3323  reset();
3324  smpAssign( left, right );
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  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
3361  Right right( ~rhs );
3362 
3363  if( !tryAddAssign( vector_, right, offset_ ) ) {
3364  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3365  }
3366 
3367  DerestrictTrait_<This> left( derestrict( *this ) );
3368 
3369  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3370  const ResultType_<VT2> tmp( right );
3371  smpAddAssign( left, tmp );
3372  }
3373  else {
3374  smpAddAssign( left, right );
3375  }
3376 
3377  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3378 
3379  return *this;
3380 }
3382 //*************************************************************************************************
3383 
3384 
3385 //*************************************************************************************************
3397 template< typename VT // Type of the dense vector
3398  , bool TF > // Transpose flag
3399 template< typename VT2 > // Type of the right-hand side vector
3400 inline Subvector<VT,aligned,TF,true>&
3401  Subvector<VT,aligned,TF,true>::operator-=( const Vector<VT2,TF>& rhs )
3402 {
3405 
3406  if( size() != (~rhs).size() ) {
3407  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3408  }
3409 
3410  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
3411  Right right( ~rhs );
3412 
3413  if( !trySubAssign( vector_, right, offset_ ) ) {
3414  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3415  }
3416 
3417  DerestrictTrait_<This> left( derestrict( *this ) );
3418 
3419  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3420  const ResultType_<VT2> tmp( right );
3421  smpSubAssign( left, tmp );
3422  }
3423  else {
3424  smpSubAssign( left, right );
3425  }
3426 
3427  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3428 
3429  return *this;
3430 }
3432 //*************************************************************************************************
3433 
3434 
3435 //*************************************************************************************************
3448 template< typename VT // Type of the dense vector
3449  , bool TF > // Transpose flag
3450 template< typename VT2 > // Type of the right-hand side dense vector
3451 inline Subvector<VT,aligned,TF,true>&
3452  Subvector<VT,aligned,TF,true>::operator*=( const DenseVector<VT2,TF>& rhs )
3453 {
3456 
3457  if( size() != (~rhs).size() ) {
3458  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3459  }
3460 
3461  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
3462  Right right( ~rhs );
3463 
3464  if( !tryMultAssign( vector_, right, offset_ ) ) {
3465  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3466  }
3467 
3468  DerestrictTrait_<This> left( derestrict( *this ) );
3469 
3470  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3471  const ResultType_<VT2> tmp( right );
3472  smpMultAssign( left, tmp );
3473  }
3474  else {
3475  smpMultAssign( left, right );
3476  }
3477 
3478  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3479 
3480  return *this;
3481 }
3483 //*************************************************************************************************
3484 
3485 
3486 //*************************************************************************************************
3499 template< typename VT // Type of the dense vector
3500  , bool TF > // Transpose flag
3501 template< typename VT2 > // Type of the right-hand side sparse vector
3502 inline Subvector<VT,aligned,TF,true>&
3503  Subvector<VT,aligned,TF,true>::operator*=( const SparseVector<VT2,TF>& rhs )
3504 {
3507 
3508  if( size() != (~rhs).size() ) {
3509  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3510  }
3511 
3512  const ResultType tmp( *this * (~rhs) );
3513 
3514  if( !tryAssign( vector_, tmp, offset_ ) ) {
3515  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3516  }
3517 
3518  DerestrictTrait_<This> left( derestrict( *this ) );
3519 
3520  smpAssign( left, tmp );
3521 
3522  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3523 
3524  return *this;
3525 }
3527 //*************************************************************************************************
3528 
3529 
3530 //*************************************************************************************************
3542 template< typename VT // Type of the dense vector
3543  , bool TF > // Transpose flag
3544 template< typename VT2 > // Type of the right-hand side dense vector
3545 inline Subvector<VT,aligned,TF,true>&
3546  Subvector<VT,aligned,TF,true>::operator/=( const DenseVector<VT2,TF>& rhs )
3547 {
3550 
3551  if( size() != (~rhs).size() ) {
3552  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3553  }
3554 
3555  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
3556  Right right( ~rhs );
3557 
3558  if( !tryDivAssign( vector_, right, offset_ ) ) {
3559  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3560  }
3561 
3562  DerestrictTrait_<This> left( derestrict( *this ) );
3563 
3564  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3565  const ResultType_<VT2> tmp( right );
3566  smpDivAssign( left, tmp );
3567  }
3568  else {
3569  smpDivAssign( left, right );
3570  }
3571 
3572  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3573 
3574  return *this;
3575 }
3577 //*************************************************************************************************
3578 
3579 
3580 //*************************************************************************************************
3588 template< typename VT // Type of the dense vector
3589  , bool TF > // Transpose flag
3590 template< typename Other > // Data type of the right-hand side scalar
3591 inline EnableIf_< IsNumeric<Other>, Subvector<VT,aligned,TF,true> >&
3593 {
3594  DerestrictTrait_<This> left( derestrict( *this ) );
3595  smpAssign( left, (*this) * rhs );
3596 
3597  return *this;
3598 }
3600 //*************************************************************************************************
3601 
3602 
3603 //*************************************************************************************************
3613 template< typename VT // Type of the dense vector
3614  , bool TF > // Transpose flag
3615 template< typename Other > // Data type of the right-hand side scalar
3616 inline EnableIf_< IsNumeric<Other>, Subvector<VT,aligned,TF,true> >&
3618 {
3619  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3620 
3621  DerestrictTrait_<This> left( derestrict( *this ) );
3622  smpAssign( left, (*this) / rhs );
3623 
3624  return *this;
3625 }
3627 //*************************************************************************************************
3628 
3629 
3630 
3631 
3632 //=================================================================================================
3633 //
3634 // UTILITY FUNCTIONS
3635 //
3636 //=================================================================================================
3637 
3638 //*************************************************************************************************
3644 template< typename VT // Type of the dense vector
3645  , bool TF > // Transpose flag
3646 inline size_t Subvector<VT,aligned,TF,true>::size() const noexcept
3647 {
3648  return size_;
3649 }
3651 //*************************************************************************************************
3652 
3653 
3654 //*************************************************************************************************
3660 template< typename VT // Type of the dense vector
3661  , bool TF > // Transpose flag
3662 inline size_t Subvector<VT,aligned,TF,true>::capacity() const noexcept
3663 {
3664  return vector_.capacity() - offset_;
3665 }
3667 //*************************************************************************************************
3668 
3669 
3670 //*************************************************************************************************
3679 template< typename VT // Type of the dense vector
3680  , bool TF > // Transpose flag
3681 inline size_t Subvector<VT,aligned,TF,true>::nonZeros() const
3682 {
3683  size_t nonzeros( 0 );
3684 
3685  const size_t iend( offset_ + size_ );
3686  for( size_t i=offset_; i<iend; ++i ) {
3687  if( !isDefault( vector_[i] ) )
3688  ++nonzeros;
3689  }
3690 
3691  return nonzeros;
3692 }
3694 //*************************************************************************************************
3695 
3696 
3697 //*************************************************************************************************
3703 template< typename VT // Type of the dense vector
3704  , bool TF > // Transpose flag
3706 {
3707  using blaze::clear;
3708 
3709  const size_t iend( offset_ + size_ );
3710  for( size_t i=offset_; i<iend; ++i )
3711  clear( vector_[i] );
3712 }
3714 //*************************************************************************************************
3715 
3716 
3717 
3718 
3719 //=================================================================================================
3720 //
3721 // NUMERIC FUNCTIONS
3722 //
3723 //=================================================================================================
3724 
3725 //*************************************************************************************************
3732 template< typename VT // Type of the dense vector
3733  , bool TF > // Transpose flag
3734 template< typename Other > // Data type of the scalar value
3735 inline Subvector<VT,aligned,TF,true>& Subvector<VT,aligned,TF,true>::scale( const Other& scalar )
3736 {
3737  const size_t iend( offset_ + size_ );
3738  for( size_t i=offset_; i<iend; ++i )
3739  vector_[i] *= scalar;
3740  return *this;
3741 }
3743 //*************************************************************************************************
3744 
3745 
3746 
3747 
3748 //=================================================================================================
3749 //
3750 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3751 //
3752 //=================================================================================================
3753 
3754 //*************************************************************************************************
3765 template< typename VT // Type of the dense vector
3766  , bool TF > // Transpose flag
3767 template< typename Other > // Data type of the foreign expression
3768 inline bool Subvector<VT,aligned,TF,true>::canAlias( const Other* alias ) const noexcept
3769 {
3770  return vector_.isAliased( alias );
3771 }
3773 //*************************************************************************************************
3774 
3775 
3776 //*************************************************************************************************
3787 template< typename VT // Type of the dense vector
3788  , bool TF > // Transpose flag
3789 template< typename VT2 // Data type of the foreign dense subvector
3790  , bool AF2 // Alignment flag of the foreign dense subvector
3791  , bool TF2 > // Transpose flag of the foreign dense subvector
3792 inline bool Subvector<VT,aligned,TF,true>::canAlias( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept
3793 {
3794  return ( vector_.isAliased( &alias->vector_ ) &&
3795  ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
3796 }
3798 //*************************************************************************************************
3799 
3800 
3801 //*************************************************************************************************
3812 template< typename VT // Type of the dense vector
3813  , bool TF > // Transpose flag
3814 template< typename Other > // Data type of the foreign expression
3815 inline bool Subvector<VT,aligned,TF,true>::isAliased( const Other* alias ) const noexcept
3816 {
3817  return vector_.isAliased( alias );
3818 }
3820 //*************************************************************************************************
3821 
3822 
3823 //*************************************************************************************************
3834 template< typename VT // Type of the dense vector
3835  , bool TF > // Transpose flag
3836 template< typename VT2 // Data type of the foreign dense subvector
3837  , bool AF2 // Alignment flag of the foreign dense subvector
3838  , bool TF2 > // Transpose flag of the foreign dense subvector
3839 inline bool Subvector<VT,aligned,TF,true>::isAliased( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept
3840 {
3841  return ( vector_.isAliased( &alias->vector_ ) &&
3842  ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
3843 }
3845 //*************************************************************************************************
3846 
3847 
3848 //*************************************************************************************************
3858 template< typename VT // Type of the dense vector
3859  , bool TF > // Transpose flag
3860 inline bool Subvector<VT,aligned,TF,true>::isAligned() const noexcept
3861 {
3862  return true;
3863 }
3865 //*************************************************************************************************
3866 
3867 
3868 //*************************************************************************************************
3879 template< typename VT // Type of the dense vector
3880  , bool TF > // Transpose flag
3881 inline bool Subvector<VT,aligned,TF,true>::canSMPAssign() const noexcept
3882 {
3883  return ( size() > SMP_DVECASSIGN_THRESHOLD );
3884 }
3886 //*************************************************************************************************
3887 
3888 
3889 //*************************************************************************************************
3903 template< typename VT // Type of the dense vector
3904  , bool TF > // Transpose flag
3905 BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true>::SIMDType
3906  Subvector<VT,aligned,TF,true>::load( size_t index ) const noexcept
3907 {
3908  return loada( index );
3909 }
3911 //*************************************************************************************************
3912 
3913 
3914 //*************************************************************************************************
3928 template< typename VT // Type of the dense vector
3929  , bool TF > // Transpose flag
3930 BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true>::SIMDType
3931  Subvector<VT,aligned,TF,true>::loada( size_t index ) const noexcept
3932 {
3934 
3935  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
3936  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
3937  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
3938 
3939  return vector_.loada( offset_+index );
3940 }
3942 //*************************************************************************************************
3943 
3944 
3945 //*************************************************************************************************
3959 template< typename VT // Type of the dense vector
3960  , bool TF > // Transpose flag
3961 BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true>::SIMDType
3962  Subvector<VT,aligned,TF,true>::loadu( size_t index ) const noexcept
3963 {
3965 
3966  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
3967  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
3968  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
3969 
3970  return vector_.loadu( offset_+index );
3971 }
3973 //*************************************************************************************************
3974 
3975 
3976 //*************************************************************************************************
3991 template< typename VT // Type of the dense vector
3992  , bool TF > // Transpose flag
3994  Subvector<VT,aligned,TF,true>::store( size_t index, const SIMDType& value ) noexcept
3995 {
3996  storea( index, value );
3997 }
3999 //*************************************************************************************************
4000 
4001 
4002 //*************************************************************************************************
4017 template< typename VT // Type of the dense vector
4018  , bool TF > // Transpose flag
4020  Subvector<VT,aligned,TF,true>::storea( size_t index, const SIMDType& value ) noexcept
4021 {
4023 
4024  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4025  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4026  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4027 
4028  vector_.storea( offset_+index, value );
4029 }
4031 //*************************************************************************************************
4032 
4033 
4034 //*************************************************************************************************
4049 template< typename VT // Type of the dense vector
4050  , bool TF > // Transpose flag
4052  Subvector<VT,aligned,TF,true>::storeu( size_t index, const SIMDType& value ) noexcept
4053 {
4055 
4056  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4057  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4058  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4059 
4060  vector_.storeu( offset_+index, value );
4061 }
4063 //*************************************************************************************************
4064 
4065 
4066 //*************************************************************************************************
4081 template< typename VT // Type of the dense vector
4082  , bool TF > // Transpose flag
4084  Subvector<VT,aligned,TF,true>::stream( size_t index, const SIMDType& value ) noexcept
4085 {
4087 
4088  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4089  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4090  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4091 
4092  vector_.stream( offset_+index, value );
4093 }
4095 //*************************************************************************************************
4096 
4097 
4098 //*************************************************************************************************
4110 template< typename VT // Type of the dense vector
4111  , bool TF > // Transpose flag
4112 template< typename VT2 > // Type of the right-hand side dense vector
4113 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
4114  Subvector<VT,aligned,TF,true>::assign( const DenseVector<VT2,TF>& rhs )
4115 {
4116  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4117 
4118  const size_t ipos( size() & size_t(-2) );
4119  for( size_t i=0UL; i<ipos; i+=2UL ) {
4120  vector_[offset_+i ] = (~rhs)[i ];
4121  vector_[offset_+i+1UL] = (~rhs)[i+1UL];
4122  }
4123  if( ipos < size() ) {
4124  vector_[offset_+ipos] = (~rhs)[ipos];
4125  }
4126 }
4128 //*************************************************************************************************
4129 
4130 
4131 //*************************************************************************************************
4143 template< typename VT // Type of the dense vector
4144  , bool TF > // Transpose flag
4145 template< typename VT2 > // Type of the right-hand side dense vector
4146 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
4147  Subvector<VT,aligned,TF,true>::assign( const DenseVector<VT2,TF>& rhs )
4148 {
4150 
4151  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4152 
4153  const size_t ipos( size_ & size_t(-SIMDSIZE) );
4154  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4155 
4156  size_t i( 0UL );
4157  Iterator left( begin() );
4158  ConstIterator_<VT2> right( (~rhs).begin() );
4159 
4160  if( useStreaming && size_ > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( &vector_ ) )
4161  {
4162  for( ; i<ipos; i+=SIMDSIZE ) {
4163  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4164  }
4165  for( ; i<size_; ++i ) {
4166  *left = *right; ++left; ++right;
4167  }
4168  }
4169  else
4170  {
4171  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4172  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4173  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4174  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4175  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4176  }
4177  for( ; i<ipos; i+=SIMDSIZE ) {
4178  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4179  }
4180  for( ; i<size_; ++i ) {
4181  *left = *right; ++left; ++right;
4182  }
4183  }
4184 }
4186 //*************************************************************************************************
4187 
4188 
4189 //*************************************************************************************************
4201 template< typename VT // Type of the dense vector
4202  , bool TF > // Transpose flag
4203 template< typename VT2 > // Type of the right-hand side sparse vector
4204 inline void Subvector<VT,aligned,TF,true>::assign( const SparseVector<VT2,TF>& rhs )
4205 {
4206  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4207 
4208  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4209  vector_[offset_+element->index()] = element->value();
4210 }
4212 //*************************************************************************************************
4213 
4214 
4215 //*************************************************************************************************
4227 template< typename VT // Type of the dense vector
4228  , bool TF > // Transpose flag
4229 template< typename VT2 > // Type of the right-hand side dense vector
4230 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
4231  Subvector<VT,aligned,TF,true>::addAssign( const DenseVector<VT2,TF>& rhs )
4232 {
4233  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4234 
4235  const size_t ipos( size() & size_t(-2) );
4236  for( size_t i=0UL; i<ipos; i+=2UL ) {
4237  vector_[offset_+i ] += (~rhs)[i ];
4238  vector_[offset_+i+1UL] += (~rhs)[i+1UL];
4239  }
4240  if( ipos < size() ) {
4241  vector_[offset_+ipos] += (~rhs)[ipos];
4242  }
4243 }
4245 //*************************************************************************************************
4246 
4247 
4248 //*************************************************************************************************
4260 template< typename VT // Type of the dense vector
4261  , bool TF > // Transpose flag
4262 template< typename VT2 > // Type of the right-hand side dense vector
4263 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
4264  Subvector<VT,aligned,TF,true>::addAssign( const DenseVector<VT2,TF>& rhs )
4265 {
4267 
4268  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4269 
4270  const size_t ipos( size_ & size_t(-SIMDSIZE) );
4271  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4272 
4273  size_t i( 0UL );
4274  Iterator left( begin() );
4275  ConstIterator_<VT2> right( (~rhs).begin() );
4276 
4277  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4278  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4279  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4280  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4281  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4282  }
4283  for( ; i<ipos; i+=SIMDSIZE ) {
4284  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4285  }
4286  for( ; i<size_; ++i ) {
4287  *left += *right; ++left; ++right;
4288  }
4289 }
4291 //*************************************************************************************************
4292 
4293 
4294 //*************************************************************************************************
4306 template< typename VT // Type of the dense vector
4307  , bool TF > // Transpose flag
4308 template< typename VT2 > // Type of the right-hand side sparse vector
4309 inline void Subvector<VT,aligned,TF,true>::addAssign( const SparseVector<VT2,TF>& rhs )
4310 {
4311  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4312 
4313  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4314  vector_[offset_+element->index()] += element->value();
4315 }
4317 //*************************************************************************************************
4318 
4319 
4320 //*************************************************************************************************
4332 template< typename VT // Type of the dense vector
4333  , bool TF > // Transpose flag
4334 template< typename VT2 > // Type of the right-hand side dense vector
4335 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
4336  Subvector<VT,aligned,TF,true>::subAssign( const DenseVector<VT2,TF>& rhs )
4337 {
4338  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4339 
4340  const size_t ipos( size() & size_t(-2) );
4341  for( size_t i=0UL; i<ipos; i+=2UL ) {
4342  vector_[offset_+i ] -= (~rhs)[i ];
4343  vector_[offset_+i+1UL] -= (~rhs)[i+1UL];
4344  }
4345  if( ipos < size() ) {
4346  vector_[offset_+ipos] -= (~rhs)[ipos];
4347  }
4348 }
4350 //*************************************************************************************************
4351 
4352 
4353 //*************************************************************************************************
4365 template< typename VT // Type of the dense vector
4366  , bool TF > // Transpose flag
4367 template< typename VT2 > // Type of the right-hand side dense vector
4368 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
4369  Subvector<VT,aligned,TF,true>::subAssign( const DenseVector<VT2,TF>& rhs )
4370 {
4372 
4373  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4374 
4375  const size_t ipos( size_ & size_t(-SIMDSIZE) );
4376  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4377 
4378  size_t i( 0UL );
4379  Iterator left( begin() );
4380  ConstIterator_<VT2> right( (~rhs).begin() );
4381 
4382  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4383  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4384  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4385  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4386  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4387  }
4388  for( ; i<ipos; i+=SIMDSIZE ) {
4389  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4390  }
4391  for( ; i<size_; ++i ) {
4392  *left -= *right; ++left; ++right;
4393  }
4394 }
4396 //*************************************************************************************************
4397 
4398 
4399 //*************************************************************************************************
4411 template< typename VT // Type of the dense vector
4412  , bool TF > // Transpose flag
4413 template< typename VT2 > // Type of the right-hand side sparse vector
4414 inline void Subvector<VT,aligned,TF,true>::subAssign( const SparseVector<VT2,TF>& rhs )
4415 {
4416  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4417 
4418  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4419  vector_[offset_+element->index()] -= element->value();
4420 }
4422 //*************************************************************************************************
4423 
4424 
4425 //*************************************************************************************************
4437 template< typename VT // Type of the dense vector
4438  , bool TF > // Transpose flag
4439 template< typename VT2 > // Type of the right-hand side dense vector
4440 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
4441  Subvector<VT,aligned,TF,true>::multAssign( const DenseVector<VT2,TF>& rhs )
4442 {
4443  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4444 
4445  const size_t ipos( size() & size_t(-2) );
4446  for( size_t i=0UL; i<ipos; i+=2UL ) {
4447  vector_[offset_+i ] *= (~rhs)[i ];
4448  vector_[offset_+i+1UL] *= (~rhs)[i+1UL];
4449  }
4450  if( ipos < size() ) {
4451  vector_[offset_+ipos] *= (~rhs)[ipos];
4452  }
4453 }
4455 //*************************************************************************************************
4456 
4457 
4458 //*************************************************************************************************
4470 template< typename VT // Type of the dense vector
4471  , bool TF > // Transpose flag
4472 template< typename VT2 > // Type of the right-hand side dense vector
4473 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
4474  Subvector<VT,aligned,TF,true>::multAssign( const DenseVector<VT2,TF>& rhs )
4475 {
4477 
4478  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4479 
4480  const size_t ipos( size_ & size_t(-SIMDSIZE) );
4481  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4482 
4483  size_t i( 0UL );
4484  Iterator left( begin() );
4485  ConstIterator_<VT2> right( (~rhs).begin() );
4486 
4487  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4488  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4489  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4490  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4491  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4492  }
4493  for( ; i<ipos; i+=SIMDSIZE ) {
4494  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4495  }
4496  for( ; i<size_; ++i ) {
4497  *left *= *right; ++left; ++right;
4498  }
4499 }
4501 //*************************************************************************************************
4502 
4503 
4504 //*************************************************************************************************
4516 template< typename VT // Type of the dense vector
4517  , bool TF > // Transpose flag
4518 template< typename VT2 > // Type of the right-hand side sparse vector
4519 inline void Subvector<VT,aligned,TF,true>::multAssign( const SparseVector<VT2,TF>& rhs )
4520 {
4521  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4522 
4523  const ResultType tmp( serial( *this ) );
4524 
4525  reset();
4526 
4527  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4528  vector_[offset_+element->index()] = tmp[element->index()] * element->value();
4529 }
4531 //*************************************************************************************************
4532 
4533 
4534 //*************************************************************************************************
4546 template< typename VT // Type of the dense vector
4547  , bool TF > // Transpose flag
4548 template< typename VT2 > // Type of the right-hand side dense vector
4549 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
4550  Subvector<VT,aligned,TF,true>::divAssign( const DenseVector<VT2,TF>& rhs )
4551 {
4552  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4553 
4554  const size_t ipos( size() & size_t(-2) );
4555  for( size_t i=0UL; i<ipos; i+=2UL ) {
4556  vector_[offset_+i ] /= (~rhs)[i ];
4557  vector_[offset_+i+1UL] /= (~rhs)[i+1UL];
4558  }
4559  if( ipos < size() ) {
4560  vector_[offset_+ipos] /= (~rhs)[ipos];
4561  }
4562 }
4564 //*************************************************************************************************
4565 
4566 
4567 //*************************************************************************************************
4579 template< typename VT // Type of the dense vector
4580  , bool TF > // Transpose flag
4581 template< typename VT2 > // Type of the right-hand side dense vector
4582 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
4583  Subvector<VT,aligned,TF,true>::divAssign( const DenseVector<VT2,TF>& rhs )
4584 {
4586 
4587  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4588 
4589  const size_t ipos( size_ & size_t(-SIMDSIZE) );
4590  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4591 
4592  size_t i( 0UL );
4593  Iterator left( begin() );
4594  ConstIterator_<VT2> right( (~rhs).begin() );
4595 
4596  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4597  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4598  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4599  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4600  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4601  }
4602  for( ; i<ipos; i+=SIMDSIZE ) {
4603  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4604  }
4605  for( ; i<size_; ++i ) {
4606  *left /= *right; ++left; ++right;
4607  }
4608 }
4610 //*************************************************************************************************
4611 
4612 
4613 
4614 
4615 
4616 
4617 
4618 
4619 //=================================================================================================
4620 //
4621 // CLASS TEMPLATE SPECIALIZATION FOR DVECDVECCROSSEXPR
4622 //
4623 //=================================================================================================
4624 
4625 //*************************************************************************************************
4633 template< typename VT1 // Type of the left-hand side dense vector
4634  , typename VT2 // Type of the right-hand side dense vector
4635  , bool TF > // Transpose flag
4636 class Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
4637  : public DenseVector< Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF >
4638  , private View
4639 {
4640  private:
4641  //**Type definitions****************************************************************************
4642  typedef DVecDVecCrossExpr<VT1,VT2,TF> CPE;
4643  typedef ResultType_<CPE> RT;
4644  //**********************************************************************************************
4645 
4646  public:
4647  //**Type definitions****************************************************************************
4648  typedef Subvector<CPE,unaligned,TF,true> This;
4649  typedef DenseVector<This,TF> BaseType;
4650  typedef SubvectorTrait_<RT> ResultType;
4651  typedef TransposeType_<ResultType> TransposeType;
4652  typedef ElementType_<CPE> ElementType;
4653  typedef ReturnType_<CPE> ReturnType;
4654  typedef const ResultType CompositeType;
4655  //**********************************************************************************************
4656 
4657  //**Compilation flags***************************************************************************
4659  enum : bool { simdEnabled = false };
4660 
4662  enum : bool { smpAssignable = false };
4663  //**********************************************************************************************
4664 
4665  //**Constructor*********************************************************************************
4672  explicit inline Subvector( const CPE& vector, size_t index, size_t n ) noexcept
4673  : vector_( vector ) // The dense vector/dense vector cross product expression
4674  , offset_( index ) // The offset of the subvector within the cross product expression
4675  , size_ ( n ) // The size of the subvector
4676  {}
4677  //**********************************************************************************************
4678 
4679  //**Subscript operator**************************************************************************
4685  inline ReturnType operator[]( size_t index ) const {
4686  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
4687  return vector_[offset_+index];
4688  }
4689  //**********************************************************************************************
4690 
4691  //**At function*********************************************************************************
4698  inline ReturnType at( size_t index ) const {
4699  if( index >= size() ) {
4700  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
4701  }
4702  return (*this)[index];
4703  }
4704  //**********************************************************************************************
4705 
4706  //**Size function*******************************************************************************
4711  inline size_t size() const noexcept {
4712  return size_;
4713  }
4714  //**********************************************************************************************
4715 
4716  //**********************************************************************************************
4722  template< typename T >
4723  inline bool canAlias( const T* alias ) const noexcept {
4724  return vector_.canAlias( alias );
4725  }
4726  //**********************************************************************************************
4727 
4728  //**********************************************************************************************
4734  template< typename T >
4735  inline bool isAliased( const T* alias ) const noexcept {
4736  return vector_.isAliased( alias );
4737  }
4738  //**********************************************************************************************
4739 
4740  private:
4741  //**Member variables****************************************************************************
4744  CPE vector_;
4745  const size_t offset_;
4746  const size_t size_;
4747 
4748  //**********************************************************************************************
4749 
4750  //**Friend declarations*************************************************************************
4751  template< bool AF1, typename VT, bool AF2, bool TF2, bool DF2 >
4752  friend const Subvector<VT,AF1,TF2,DF2>
4753  subvector( const Subvector<VT,AF2,TF2,DF2>& sv, size_t index, size_t size );
4754 
4755  template< typename VT3, bool AF, bool TF2, bool DF2 >
4756  friend bool isIntact( const Subvector<VT3,AF,TF2,DF2>& sv ) noexcept;
4757 
4758  template< typename VT3, bool AF, bool TF2, bool DF2 >
4759  friend bool isSame( const Subvector<VT3,AF,TF2,DF2>& a, const Vector<VT3,TF2>& b ) noexcept;
4760 
4761  template< typename VT3, bool AF, bool TF2, bool DF2 >
4762  friend bool isSame( const Vector<VT3,TF2>& a, const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
4763 
4764  template< typename VT3, bool AF, bool TF2, bool DF2 >
4765  friend bool isSame( const Subvector<VT3,AF,TF2,DF2>& a, const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
4766 
4767  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
4768  friend bool tryAssign( const Subvector<VT3,AF,TF2,DF2>& lhs, const Vector<VT4,TF2>& rhs, size_t index );
4769 
4770  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
4771  friend bool tryAddAssign( const Subvector<VT2,AF,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
4772 
4773  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
4774  friend bool trySubAssign( const Subvector<VT2,AF,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
4775 
4776  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
4777  friend bool tryMultAssign( const Subvector<VT3,AF,TF2,DF2>& lhs, const Vector<VT4,TF2>& rhs, size_t index );
4778  //**********************************************************************************************
4779 };
4781 //*************************************************************************************************
4782 
4783 
4784 
4785 
4786 
4787 
4788 
4789 
4790 //=================================================================================================
4791 //
4792 // CLASS TEMPLATE SPECIALIZATION FOR DVECSVECCROSSEXPR
4793 //
4794 //=================================================================================================
4795 
4796 //*************************************************************************************************
4804 template< typename VT1 // Type of the left-hand side dense vector
4805  , typename VT2 // Type of the right-hand side sparse vector
4806  , bool TF > // Transpose flag
4807 class Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
4808  : public DenseVector< Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF >
4809  , private View
4810 {
4811  private:
4812  //**Type definitions****************************************************************************
4813  typedef DVecSVecCrossExpr<VT1,VT2,TF> CPE;
4814  typedef ResultType_<CPE> RT;
4815  //**********************************************************************************************
4816 
4817  public:
4818  //**Type definitions****************************************************************************
4819  typedef Subvector<CPE,unaligned,TF,true> This;
4820  typedef DenseVector<This,TF> BaseType;
4821  typedef SubvectorTrait_<RT> ResultType;
4822  typedef TransposeType_<ResultType> TransposeType;
4823  typedef ElementType_<CPE> ElementType;
4824  typedef ReturnType_<CPE> ReturnType;
4825  typedef const ResultType CompositeType;
4826  //**********************************************************************************************
4827 
4828  //**Compilation flags***************************************************************************
4830  enum : bool { simdEnabled = false };
4831 
4833  enum : bool { smpAssignable = false };
4834  //**********************************************************************************************
4835 
4836  //**Constructor*********************************************************************************
4843  explicit inline Subvector( const CPE& vector, size_t index, size_t n ) noexcept
4844  : vector_( vector ) // The dense vector/sparse vector cross product expression
4845  , offset_( index ) // The offset of the subvector within the cross product expression
4846  , size_ ( n ) // The size of the subvector
4847  {}
4848  //**********************************************************************************************
4849 
4850  //**Subscript operator**************************************************************************
4856  inline ReturnType operator[]( size_t index ) const {
4857  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
4858  return vector_[offset_+index];
4859  }
4860  //**********************************************************************************************
4861 
4862  //**At function*********************************************************************************
4869  inline ReturnType at( size_t index ) const {
4870  if( index >= size() ) {
4871  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
4872  }
4873  return (*this)[index];
4874  }
4875  //**********************************************************************************************
4876 
4877  //**Size function*******************************************************************************
4882  inline size_t size() const noexcept {
4883  return size_;
4884  }
4885  //**********************************************************************************************
4886 
4887  //**********************************************************************************************
4893  template< typename T >
4894  inline bool canAlias( const T* alias ) const noexcept {
4895  return vector_.canAlias( alias );
4896  }
4897  //**********************************************************************************************
4898 
4899  //**********************************************************************************************
4905  template< typename T >
4906  inline bool isAliased( const T* alias ) const noexcept {
4907  return vector_.isAliased( alias );
4908  }
4909  //**********************************************************************************************
4910 
4911  private:
4912  //**Member variables****************************************************************************
4915  CPE vector_;
4916  const size_t offset_;
4917  const size_t size_;
4918 
4919  //**********************************************************************************************
4920 
4921  //**Friend declarations*************************************************************************
4922  template< bool AF1, typename VT, bool AF2, bool TF2, bool DF2 >
4923  friend const Subvector<VT,AF1,TF2,DF2>
4924  subvector( const Subvector<VT,AF2,TF2,DF2>& sv, size_t index, size_t size );
4925 
4926  template< typename VT3, bool AF, bool TF2, bool DF2 >
4927  friend bool isIntact( const Subvector<VT3,AF,TF2,DF2>& sv ) noexcept;
4928 
4929  template< typename VT3, bool AF, bool TF2, bool DF2 >
4930  friend bool isSame( const Subvector<VT3,AF,TF2,DF2>& a, const Vector<VT3,TF2>& b ) noexcept;
4931 
4932  template< typename VT3, bool AF, bool TF2, bool DF2 >
4933  friend bool isSame( const Vector<VT3,TF2>& a, const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
4934 
4935  template< typename VT3, bool AF, bool TF2, bool DF2 >
4936  friend bool isSame( const Subvector<VT3,AF,TF2,DF2>& a, const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
4937 
4938  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
4939  friend bool tryAssign( const Subvector<VT3,AF,TF2,DF2>& lhs, const Vector<VT4,TF2>& rhs, size_t index );
4940 
4941  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
4942  friend bool tryAddAssign( const Subvector<VT2,AF,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
4943 
4944  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
4945  friend bool trySubAssign( const Subvector<VT2,AF,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
4946 
4947  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
4948  friend bool tryMultAssign( const Subvector<VT3,AF,TF2,DF2>& lhs, const Vector<VT4,TF2>& rhs, size_t index );
4949  //**********************************************************************************************
4950 };
4952 //*************************************************************************************************
4953 
4954 
4955 
4956 
4957 
4958 
4959 
4960 
4961 //=================================================================================================
4962 //
4963 // CLASS TEMPLATE SPECIALIZATION FOR SVECDVECCROSSEXPR
4964 //
4965 //=================================================================================================
4966 
4967 //*************************************************************************************************
4975 template< typename VT1 // Type of the left-hand side sparse vector
4976  , typename VT2 // Type of the right-hand side dense vector
4977  , bool TF > // Transpose flag
4978 class Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
4979  : public DenseVector< Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF >
4980  , private View
4981 {
4982  private:
4983  //**Type definitions****************************************************************************
4984  typedef SVecDVecCrossExpr<VT1,VT2,TF> CPE;
4985  typedef ResultType_<CPE> RT;
4986  //**********************************************************************************************
4987 
4988  public:
4989  //**Type definitions****************************************************************************
4990  typedef Subvector<CPE,unaligned,TF,true> This;
4991  typedef DenseVector<This,TF> BaseType;
4992  typedef SubvectorTrait_<RT> ResultType;
4993  typedef TransposeType_<ResultType> TransposeType;
4994  typedef ElementType_<CPE> ElementType;
4995  typedef ReturnType_<CPE> ReturnType;
4996  typedef const ResultType CompositeType;
4997  //**********************************************************************************************
4998 
4999  //**Compilation flags***************************************************************************
5001  enum : bool { simdEnabled = false };
5002 
5004  enum : bool { smpAssignable = false };
5005  //**********************************************************************************************
5006 
5007  //**Constructor*********************************************************************************
5014  explicit inline Subvector( const CPE& vector, size_t index, size_t n ) noexcept
5015  : vector_( vector ) // The sparse vector/dense vector cross product expression
5016  , offset_( index ) // The offset of the subvector within the cross product expression
5017  , size_ ( n ) // The size of the subvector
5018  {}
5019  //**********************************************************************************************
5020 
5021  //**Subscript operator**************************************************************************
5027  inline ReturnType operator[]( size_t index ) const {
5028  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
5029  return vector_[offset_+index];
5030  }
5031  //**********************************************************************************************
5032 
5033  //**At function*********************************************************************************
5040  inline ReturnType at( size_t index ) const {
5041  if( index >= size() ) {
5042  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
5043  }
5044  return (*this)[index];
5045  }
5046  //**********************************************************************************************
5047 
5048  //**Size function*******************************************************************************
5053  inline size_t size() const noexcept {
5054  return size_;
5055  }
5056  //**********************************************************************************************
5057 
5058  //**********************************************************************************************
5064  template< typename T >
5065  inline bool canAlias( const T* alias ) const noexcept {
5066  return vector_.canAlias( alias );
5067  }
5068  //**********************************************************************************************
5069 
5070  //**********************************************************************************************
5076  template< typename T >
5077  inline bool isAliased( const T* alias ) const noexcept {
5078  return vector_.isAliased( alias );
5079  }
5080  //**********************************************************************************************
5081 
5082  private:
5083  //**Member variables****************************************************************************
5086  CPE vector_;
5087  const size_t offset_;
5088  const size_t size_;
5089 
5090  //**********************************************************************************************
5091 
5092  //**Friend declarations*************************************************************************
5093  template< bool AF1, typename VT, bool AF2, bool TF2, bool DF2 >
5094  friend const Subvector<VT,AF1,TF2,DF2>
5095  subvector( const Subvector<VT,AF2,TF2,DF2>& sv, size_t index, size_t size );
5096 
5097  template< typename VT3, bool AF, bool TF2, bool DF2 >
5098  friend bool isIntact( const Subvector<VT3,AF,TF2,DF2>& sv ) noexcept;
5099 
5100  template< typename VT3, bool AF, bool TF2, bool DF2 >
5101  friend bool isSame( const Subvector<VT3,AF,TF2,DF2>& a, const Vector<VT3,TF2>& b ) noexcept;
5102 
5103  template< typename VT3, bool AF, bool TF2, bool DF2 >
5104  friend bool isSame( const Vector<VT3,TF2>& a, const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
5105 
5106  template< typename VT3, bool AF, bool TF2, bool DF2 >
5107  friend bool isSame( const Subvector<VT3,AF,TF2,DF2>& a, const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
5108 
5109  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
5110  friend bool tryAssign( const Subvector<VT3,AF,TF2,DF2>& lhs, const Vector<VT4,TF2>& rhs, size_t index );
5111 
5112  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
5113  friend bool tryAddAssign( const Subvector<VT2,AF,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
5114 
5115  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
5116  friend bool trySubAssign( const Subvector<VT2,AF,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
5117 
5118  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
5119  friend bool tryMultAssign( const Subvector<VT3,AF,TF2,DF2>& lhs, const Vector<VT4,TF2>& rhs, size_t index );
5120  //**********************************************************************************************
5121 };
5123 //*************************************************************************************************
5124 
5125 
5126 
5127 
5128 
5129 
5130 
5131 
5132 //=================================================================================================
5133 //
5134 // CLASS TEMPLATE SPECIALIZATION FOR SVECSVECCROSSEXPR
5135 //
5136 //=================================================================================================
5137 
5138 //*************************************************************************************************
5146 template< typename VT1 // Type of the left-hand side sparse vector
5147  , typename VT2 // Type of the right-hand side sparse vector
5148  , bool TF > // Transpose flag
5149 class Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
5150  : public DenseVector< Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF >
5151  , private View
5152 {
5153  private:
5154  //**Type definitions****************************************************************************
5155  typedef SVecSVecCrossExpr<VT1,VT2,TF> CPE;
5156  typedef ResultType_<CPE> RT;
5157  //**********************************************************************************************
5158 
5159  public:
5160  //**Type definitions****************************************************************************
5161  typedef Subvector<CPE,unaligned,TF,true> This;
5162  typedef DenseVector<This,TF> BaseType;
5163  typedef SubvectorTrait_<RT> ResultType;
5164  typedef TransposeType_<ResultType> TransposeType;
5165  typedef ElementType_<CPE> ElementType;
5166  typedef ReturnType_<CPE> ReturnType;
5167  typedef const ResultType CompositeType;
5168  //**********************************************************************************************
5169 
5170  //**Compilation flags***************************************************************************
5172  enum : bool { simdEnabled = false };
5173 
5175  enum : bool { smpAssignable = false };
5176  //**********************************************************************************************
5177 
5178  //**Constructor*********************************************************************************
5185  explicit inline Subvector( const CPE& vector, size_t index, size_t n ) noexcept
5186  : vector_( vector ) // The sparse vector/sparse vector cross product expression
5187  , offset_( index ) // The offset of the subvector within the cross product expression
5188  , size_ ( n ) // The size of the subvector
5189  {}
5190  //**********************************************************************************************
5191 
5192  //**Subscript operator**************************************************************************
5198  inline ReturnType operator[]( size_t index ) const {
5199  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
5200  return vector_[offset_+index];
5201  }
5202  //**********************************************************************************************
5203 
5204  //**At function*********************************************************************************
5211  inline ReturnType at( size_t index ) const {
5212  if( index >= size() ) {
5213  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
5214  }
5215  return (*this)[index];
5216  }
5217  //**********************************************************************************************
5218 
5219  //**Size function*******************************************************************************
5224  inline size_t size() const noexcept {
5225  return size_;
5226  }
5227  //**********************************************************************************************
5228 
5229  //**********************************************************************************************
5235  template< typename T >
5236  inline bool canAlias( const T* alias ) const noexcept {
5237  return vector_.canAlias( alias );
5238  }
5239  //**********************************************************************************************
5240 
5241  //**********************************************************************************************
5247  template< typename T >
5248  inline bool isAliased( const T* alias ) const {
5249  return vector_.isAliased( alias );
5250  }
5251  //**********************************************************************************************
5252 
5253  private:
5254  //**Member variables****************************************************************************
5257  CPE vector_;
5258  const size_t offset_;
5259  const size_t size_;
5260 
5261  //**********************************************************************************************
5262 
5263  //**Friend declarations*************************************************************************
5264  template< bool AF1, typename VT, bool AF2, bool TF2, bool DF2 >
5265  friend const Subvector<VT,AF1,TF2,DF2>
5266  subvector( const Subvector<VT,AF2,TF2,DF2>& sv, size_t index, size_t size );
5267 
5268  template< typename VT3, bool AF, bool TF2, bool DF2 >
5269  friend bool isIntact( const Subvector<VT3,AF,TF2,DF2>& sv ) noexcept;
5270 
5271  template< typename VT3, bool AF, bool TF2, bool DF2 >
5272  friend bool isSame( const Subvector<VT3,AF,TF2,DF2>& a, const Vector<VT3,TF2>& b ) noexcept;
5273 
5274  template< typename VT3, bool AF, bool TF2, bool DF2 >
5275  friend bool isSame( const Vector<VT3,TF2>& a, const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
5276 
5277  template< typename VT3, bool AF, bool TF2, bool DF2 >
5278  friend bool isSame( const Subvector<VT3,AF,TF2,DF2>& a, const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
5279 
5280  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
5281  friend bool tryAssign( const Subvector<VT3,AF,TF2,DF2>& lhs, const Vector<VT4,TF2>& rhs, size_t index );
5282 
5283  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
5284  friend bool tryAddAssign( const Subvector<VT2,AF,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
5285 
5286  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
5287  friend bool trySubAssign( const Subvector<VT2,AF,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
5288 
5289  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
5290  friend bool tryMultAssign( const Subvector<VT3,AF,TF2,DF2>& lhs, const Vector<VT4,TF2>& rhs, size_t index );
5291  //**********************************************************************************************
5292 };
5294 //*************************************************************************************************
5295 
5296 } // namespace blaze
5297 
5298 #endif
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.
constexpr bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
typename DerestrictTrait< T >::Type DerestrictTrait_
Auxiliary alias declaration for the DerestrictTrait type trait.The DerestrictTrait_ alias declaration...
Definition: DerestrictTrait.h:110
#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:352
BLAZE_ALWAYS_INLINE bool isSame(const Matrix< MT1, SO1 > &a, const Matrix< MT2, SO2 > &b) noexcept
Returns whether the two given matrices represent the same observable state.
Definition: Matrix.h:721
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:160
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:261
#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 size_t cacheSize
Cache size of the target architecture.This setting specifies the available cache size in Byte of the ...
Definition: CacheSize.h:48
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
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1339
const bool aligned
Alignment flag for aligned vectors and matrices.Via this flag it is possible to specify subvectors...
Definition: AlignmentFlag.h:85
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:194
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:533
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
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2935
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:223
Header file for the DenseVector base class.
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2928
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:721
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:390
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
#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:1321
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:129
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:304
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:238
Header file for the std::initializer_list aliases.
Constraint on the data type.
SubvectorExprTrait_< VT, unaligned > subvector(Vector< VT, TF > &vector, size_t index, size_t size)
Creating a view on a specific subvector of the given vector.
Definition: Subvector.h:152
Header file for the DisableIf class template.
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.
constexpr bool useStreaming
Configuration of the streaming behavior.For large vectors and matrices non-temporal stores can provid...
Definition: Optimizations.h:68
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2939
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:98
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.
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
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:2932
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:260
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:2933
const bool unaligned
Alignment flag for unaligned vectors and matrices.Via this flag it is possible to specify subvectors...
Definition: AlignmentFlag.h:64
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.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2937
Header file for the EnableIf class template.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:553
Header file for the DerestrictTrait class template.
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.
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2934
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:1285
Header file for run time assertion macros.
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.
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2938
Header file for the isDefault shim.
Header file for the HasSIMDSub type trait.
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:223
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
#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
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2929
#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.
Header file for the alignment check function.
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2930
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:249
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2936
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:1303
Header file for the IsRestricted type trait.
const DMatDMatMultExpr< T1, T2, false, false, false, false > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:7505
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.