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();
616  template< typename Other > inline Subvector& scale( const Other& scalar );
618  //**********************************************************************************************
619 
620  private:
621  //**********************************************************************************************
623  template< typename VT2 >
624  struct VectorizedAssign {
625  enum : bool { value = useOptimizedKernels &&
626  simdEnabled && VT2::simdEnabled &&
627  AreSIMDCombinable< ElementType, ElementType_<VT2> >::value };
628  };
629  //**********************************************************************************************
630 
631  //**********************************************************************************************
633  template< typename VT2 >
634  struct VectorizedAddAssign {
635  enum : bool { value = useOptimizedKernels &&
636  simdEnabled && VT2::simdEnabled &&
637  AreSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
638  HasSIMDAdd< ElementType, ElementType_<VT2> >::value };
639  };
640  //**********************************************************************************************
641 
642  //**********************************************************************************************
644  template< typename VT2 >
645  struct VectorizedSubAssign {
646  enum : bool { value = useOptimizedKernels &&
647  simdEnabled && VT2::simdEnabled &&
648  AreSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
649  HasSIMDSub< ElementType, ElementType_<VT2> >::value };
650  };
651  //**********************************************************************************************
652 
653  //**********************************************************************************************
655  template< typename VT2 >
656  struct VectorizedMultAssign {
657  enum : bool { value = useOptimizedKernels &&
658  simdEnabled && VT2::simdEnabled &&
659  AreSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
660  HasSIMDMult< ElementType, ElementType_<VT2> >::value };
661  };
662  //**********************************************************************************************
663 
664  //**********************************************************************************************
666  template< typename VT2 >
667  struct VectorizedDivAssign {
668  enum : bool { value = useOptimizedKernels &&
669  simdEnabled && VT2::simdEnabled &&
670  AreSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
671  HasSIMDDiv< ElementType, ElementType_<VT2> >::value };
672  };
673  //**********************************************************************************************
674 
675  //**SIMD properties*****************************************************************************
677  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
678  //**********************************************************************************************
679 
680  public:
681  //**Expression template evaluation functions****************************************************
684  template< typename Other >
685  inline bool canAlias( const Other* alias ) const noexcept;
686 
687  template< typename VT2, bool AF2, bool TF2 >
688  inline bool canAlias( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept;
689 
690  template< typename Other >
691  inline bool isAliased( const Other* alias ) const noexcept;
692 
693  template< typename VT2, bool AF2, bool TF2 >
694  inline bool isAliased( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept;
695 
696  inline bool isAligned () const noexcept;
697  inline bool canSMPAssign() const noexcept;
698 
699  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
700  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
701  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
702 
703  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
704  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
705  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
706  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
707 
708  template< typename VT2 >
709  inline DisableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
710 
711  template< typename VT2 >
712  inline EnableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
713 
714  template< typename VT2 > inline void assign( const SparseVector<VT2,TF>& rhs );
715 
716  template< typename VT2 >
717  inline DisableIf_< VectorizedAddAssign<VT2> > addAssign( const DenseVector <VT2,TF>& rhs );
718 
719  template< typename VT2 >
720  inline EnableIf_< VectorizedAddAssign<VT2> > addAssign ( const DenseVector <VT2,TF>& rhs );
721 
722  template< typename VT2 > inline void addAssign( const SparseVector<VT2,TF>& rhs );
723 
724  template< typename VT2 >
725  inline DisableIf_< VectorizedSubAssign<VT2> > subAssign ( const DenseVector <VT2,TF>& rhs );
726 
727  template< typename VT2 >
728  inline EnableIf_< VectorizedSubAssign<VT2> > subAssign( const DenseVector <VT2,TF>& rhs );
729 
730  template< typename VT2 > inline void subAssign( const SparseVector<VT2,TF>& rhs );
731 
732  template< typename VT2 >
733  inline DisableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
734 
735  template< typename VT2 >
736  inline EnableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
737 
738  template< typename VT2 > inline void multAssign( const SparseVector<VT2,TF>& rhs );
739 
740  template< typename VT2 >
741  inline DisableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
742 
743  template< typename VT2 >
744  inline EnableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
746  //**********************************************************************************************
747 
748  private:
749  //**Member variables****************************************************************************
752  Operand vector_;
753  const size_t offset_;
754  const size_t size_;
755  const bool isAligned_;
756 
763  //**********************************************************************************************
764 
765  //**Friend declarations*************************************************************************
766  template< typename VT2, bool AF2, bool TF2, bool DF2 > friend class Subvector;
767 
768  template< bool AF1, typename VT2, bool AF2, bool TF2, bool DF2 >
769  friend const Subvector<VT2,AF1,TF2,DF2>
770  subvector( const Subvector<VT2,AF2,TF2,DF2>& sv, size_t index, size_t size );
771 
772  template< typename VT2, bool AF2, bool TF2, bool DF2 >
773  friend bool isIntact( const Subvector<VT2,AF2,TF2,DF2>& sv ) noexcept;
774 
775  template< typename VT2, bool AF2, bool TF2, bool DF2 >
776  friend bool isSame( const Subvector<VT2,AF2,TF2,DF2>& a, const Vector<VT2,TF2>& b ) noexcept;
777 
778  template< typename VT2, bool AF2, bool TF2, bool DF2 >
779  friend bool isSame( const Vector<VT2,TF2>& a, const Subvector<VT2,AF2,TF2,DF2>& b ) noexcept;
780 
781  template< typename VT2, bool AF2, bool TF2, bool DF2 >
782  friend bool isSame( const Subvector<VT2,AF2,TF2,DF2>& a, const Subvector<VT2,AF2,TF2,DF2>& b ) noexcept;
783 
784  template< typename VT2, bool AF2, bool TF2, bool DF2, typename VT3 >
785  friend bool tryAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
786 
787  template< typename VT2, bool AF2, bool TF2, bool DF2, typename VT3 >
788  friend bool tryAddAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
789 
790  template< typename VT2, bool AF2, bool TF2, bool DF2, typename VT3 >
791  friend bool trySubAssign( const Subvector<VT2,AF2,DF2,TF2>& 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 tryMultAssign( 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 >
797  friend DerestrictTrait_< Subvector<VT2,AF2,TF2,DF2> > derestrict( Subvector<VT2,AF2,TF2,DF2>& sv );
798  //**********************************************************************************************
799 
800  //**Compile time checks*************************************************************************
806  //**********************************************************************************************
807 };
809 //*************************************************************************************************
810 
811 
812 
813 
814 //=================================================================================================
815 //
816 // CONSTRUCTOR
817 //
818 //=================================================================================================
819 
820 //*************************************************************************************************
833 template< typename VT // Type of the dense vector
834  , bool TF > // Transpose flag
835 inline Subvector<VT,unaligned,TF,true>::Subvector( Operand vector, size_t index, size_t n )
836  : vector_ ( vector ) // The vector containing the subvector
837  , offset_ ( index ) // The offset of the subvector within the dense vector
838  , size_ ( n ) // The size of the subvector
839  , isAligned_( simdEnabled && vector.data() != nullptr && checkAlignment( data() ) )
840 {
841  if( index + n > vector.size() ) {
842  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
843  }
844 }
846 //*************************************************************************************************
847 
848 
849 
850 
851 //=================================================================================================
852 //
853 // DATA ACCESS FUNCTIONS
854 //
855 //=================================================================================================
856 
857 //*************************************************************************************************
867 template< typename VT // Type of the dense vector
868  , bool TF > // Transpose flag
870  Subvector<VT,unaligned,TF,true>::operator[]( size_t index )
871 {
872  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
873  return vector_[offset_+index];
874 }
876 //*************************************************************************************************
877 
878 
879 //*************************************************************************************************
889 template< typename VT // Type of the dense vector
890  , bool TF > // Transpose flag
892  Subvector<VT,unaligned,TF,true>::operator[]( size_t index ) const
893 {
894  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
895  return const_cast<const VT&>( vector_ )[offset_+index];
896 }
898 //*************************************************************************************************
899 
900 
901 //*************************************************************************************************
912 template< typename VT // Type of the dense vector
913  , bool TF > // Transpose flag
915  Subvector<VT,unaligned,TF,true>::at( size_t index )
916 {
917  if( index >= size() ) {
918  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
919  }
920  return (*this)[index];
921 }
923 //*************************************************************************************************
924 
925 
926 //*************************************************************************************************
937 template< typename VT // Type of the dense vector
938  , bool TF > // Transpose flag
940  Subvector<VT,unaligned,TF,true>::at( size_t index ) const
941 {
942  if( index >= size() ) {
943  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
944  }
945  return (*this)[index];
946 }
948 //*************************************************************************************************
949 
950 
951 //*************************************************************************************************
959 template< typename VT // Type of the dense vector
960  , bool TF > // Transpose flag
961 inline typename Subvector<VT,unaligned,TF,true>::Pointer
962  Subvector<VT,unaligned,TF,true>::data() noexcept
963 {
964  return vector_.data() + offset_;
965 }
967 //*************************************************************************************************
968 
969 
970 //*************************************************************************************************
978 template< typename VT // Type of the dense vector
979  , bool TF > // Transpose flag
980 inline typename Subvector<VT,unaligned,TF,true>::ConstPointer
981  Subvector<VT,unaligned,TF,true>::data() const noexcept
982 {
983  return vector_.data() + offset_;
984 }
986 //*************************************************************************************************
987 
988 
989 //*************************************************************************************************
997 template< typename VT // Type of the dense vector
998  , bool TF > // Transpose flag
1001 {
1002  return Iterator( vector_.begin() + offset_, isAligned_ );
1003 }
1005 //*************************************************************************************************
1006 
1007 
1008 //*************************************************************************************************
1016 template< typename VT // Type of the dense vector
1017  , bool TF > // Transpose flag
1020 {
1021  return ConstIterator( vector_.cbegin() + offset_, isAligned_ );
1022 }
1024 //*************************************************************************************************
1025 
1026 
1027 //*************************************************************************************************
1035 template< typename VT // Type of the dense vector
1036  , bool TF > // Transpose flag
1039 {
1040  return ConstIterator( vector_.cbegin() + offset_, isAligned_ );
1041 }
1043 //*************************************************************************************************
1044 
1045 
1046 //*************************************************************************************************
1054 template< typename VT // Type of the dense vector
1055  , bool TF > // Transpose flag
1058 {
1059  return Iterator( vector_.begin() + offset_ + size_, isAligned_ );
1060 }
1062 //*************************************************************************************************
1063 
1064 
1065 //*************************************************************************************************
1073 template< typename VT // Type of the dense vector
1074  , bool TF > // Transpose flag
1077 {
1078  return ConstIterator( vector_.cbegin() + offset_ + size_, isAligned_ );
1079 }
1081 //*************************************************************************************************
1082 
1083 
1084 //*************************************************************************************************
1092 template< typename VT // Type of the dense vector
1093  , bool TF > // Transpose flag
1096 {
1097  return ConstIterator( vector_.cbegin() + offset_ + size_, isAligned_ );
1098 }
1100 //*************************************************************************************************
1101 
1102 
1103 
1104 
1105 //=================================================================================================
1106 //
1107 // ASSIGNMENT OPERATORS
1108 //
1109 //=================================================================================================
1110 
1111 //*************************************************************************************************
1118 template< typename VT // Type of the dense vector
1119  , bool TF > // Transpose flag
1120 inline Subvector<VT,unaligned,TF,true>&
1121  Subvector<VT,unaligned,TF,true>::operator=( const ElementType& rhs )
1122 {
1123  const size_t iend( offset_ + size_ );
1124 
1125  for( size_t i=offset_; i<iend; ++i )
1126  vector_[i] = rhs;
1127 
1128  return *this;
1129 }
1131 //*************************************************************************************************
1132 
1133 
1134 //*************************************************************************************************
1147 template< typename VT // Type of the dense vector
1148  , bool TF > // Transpose flag
1149 inline Subvector<VT,unaligned,TF,true>&
1150  Subvector<VT,unaligned,TF,true>::operator=( initializer_list<ElementType> list )
1151 {
1152  if( list.size() > size() ) {
1153  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to subvector" );
1154  }
1155 
1156  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
1157 
1158  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1159 
1160  return *this;
1161 }
1163 //*************************************************************************************************
1164 
1165 
1166 //*************************************************************************************************
1178 template< typename VT // Type of the dense vector
1179  , bool TF > // Transpose flag
1180 inline Subvector<VT,unaligned,TF,true>&
1181  Subvector<VT,unaligned,TF,true>::operator=( const Subvector& rhs )
1182 {
1185 
1186  if( &rhs == this || ( &vector_ == &rhs.vector_ && offset_ == rhs.offset_ ) )
1187  return *this;
1188 
1189  if( size() != rhs.size() ) {
1190  BLAZE_THROW_INVALID_ARGUMENT( "Subvector sizes do not match" );
1191  }
1192 
1193  if( !tryAssign( vector_, rhs, offset_ ) ) {
1194  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1195  }
1196 
1197  DerestrictTrait_<This> left( derestrict( *this ) );
1198 
1199  if( rhs.canAlias( &vector_ ) ) {
1200  const ResultType tmp( rhs );
1201  smpAssign( left, tmp );
1202  }
1203  else {
1204  smpAssign( left, rhs );
1205  }
1206 
1207  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1208 
1209  return *this;
1210 }
1212 //*************************************************************************************************
1213 
1214 
1215 //*************************************************************************************************
1227 template< typename VT // Type of the dense vector
1228  , bool TF > // Transpose flag
1229 template< typename VT2 > // Type of the right-hand side vector
1230 inline Subvector<VT,unaligned,TF,true>&
1231  Subvector<VT,unaligned,TF,true>::operator=( const Vector<VT2,TF>& rhs )
1232 {
1235 
1236  if( size() != (~rhs).size() ) {
1237  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1238  }
1239 
1240  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
1241  Right right( ~rhs );
1242 
1243  if( !tryAssign( vector_, right, offset_ ) ) {
1244  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1245  }
1246 
1247  DerestrictTrait_<This> left( derestrict( *this ) );
1248 
1249  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1250  const ResultType_<VT2> tmp( right );
1251  smpAssign( left, tmp );
1252  }
1253  else {
1254  if( IsSparseVector<VT2>::value )
1255  reset();
1256  smpAssign( left, right );
1257  }
1258 
1259  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1260 
1261  return *this;
1262 }
1264 //*************************************************************************************************
1265 
1266 
1267 //*************************************************************************************************
1279 template< typename VT // Type of the dense vector
1280  , bool TF > // Transpose flag
1281 template< typename VT2 > // Type of the right-hand side vector
1282 inline Subvector<VT,unaligned,TF,true>&
1283  Subvector<VT,unaligned,TF,true>::operator+=( const Vector<VT2,TF>& rhs )
1284 {
1287 
1288  if( size() != (~rhs).size() ) {
1289  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1290  }
1291 
1292  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
1293  Right right( ~rhs );
1294 
1295  if( !tryAddAssign( vector_, right, offset_ ) ) {
1296  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1297  }
1298 
1299  DerestrictTrait_<This> left( derestrict( *this ) );
1300 
1301  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1302  const ResultType_<VT2> tmp( right );
1303  smpAddAssign( left, tmp );
1304  }
1305  else {
1306  smpAddAssign( left, right );
1307  }
1308 
1309  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1310 
1311  return *this;
1312 }
1314 //*************************************************************************************************
1315 
1316 
1317 //*************************************************************************************************
1329 template< typename VT // Type of the dense vector
1330  , bool TF > // Transpose flag
1331 template< typename VT2 > // Type of the right-hand side vector
1332 inline Subvector<VT,unaligned,TF,true>&
1333  Subvector<VT,unaligned,TF,true>::operator-=( const Vector<VT2,TF>& rhs )
1334 {
1337 
1338  if( size() != (~rhs).size() ) {
1339  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1340  }
1341 
1342  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
1343  Right right( ~rhs );
1344 
1345  if( !trySubAssign( vector_, right, offset_ ) ) {
1346  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1347  }
1348 
1349  DerestrictTrait_<This> left( derestrict( *this ) );
1350 
1351  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1352  const ResultType_<VT2> tmp( right );
1353  smpSubAssign( left, tmp );
1354  }
1355  else {
1356  smpSubAssign( left, right );
1357  }
1358 
1359  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1360 
1361  return *this;
1362 }
1364 //*************************************************************************************************
1365 
1366 
1367 //*************************************************************************************************
1380 template< typename VT // Type of the dense vector
1381  , bool TF > // Transpose flag
1382 template< typename VT2 > // Type of the right-hand side dense vector
1383 inline Subvector<VT,unaligned,TF,true>&
1384  Subvector<VT,unaligned,TF,true>::operator*=( const DenseVector<VT2,TF>& rhs )
1385 {
1388 
1389  if( size() != (~rhs).size() ) {
1390  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1391  }
1392 
1393  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
1394  Right right( ~rhs );
1395 
1396  if( !tryMultAssign( vector_, right, offset_ ) ) {
1397  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1398  }
1399 
1400  DerestrictTrait_<This> left( derestrict( *this ) );
1401 
1402  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1403  const ResultType_<VT2> tmp( right );
1404  smpMultAssign( left, tmp );
1405  }
1406  else {
1407  smpMultAssign( left, right );
1408  }
1409 
1410  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1411 
1412  return *this;
1413 }
1415 //*************************************************************************************************
1416 
1417 
1418 //*************************************************************************************************
1431 template< typename VT // Type of the dense vector
1432  , bool TF > // Transpose flag
1433 template< typename VT2 > // Type of the right-hand side sparse vector
1434 inline Subvector<VT,unaligned,TF,true>&
1435  Subvector<VT,unaligned,TF,true>::operator*=( const SparseVector<VT2,TF>& rhs )
1436 {
1439 
1440  if( size() != (~rhs).size() ) {
1441  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1442  }
1443 
1444  const ResultType tmp( *this * (~rhs) );
1445 
1446  if( !tryAssign( vector_, tmp, offset_ ) ) {
1447  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1448  }
1449 
1450  DerestrictTrait_<This> left( derestrict( *this ) );
1451 
1452  smpAssign( left, tmp );
1453 
1454  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1455 
1456  return *this;
1457 }
1459 //*************************************************************************************************
1460 
1461 
1462 //*************************************************************************************************
1474 template< typename VT // Type of the dense vector
1475  , bool TF > // Transpose flag
1476 template< typename VT2 > // Type of the right-hand side dense vector
1477 inline Subvector<VT,unaligned,TF,true>&
1478  Subvector<VT,unaligned,TF,true>::operator/=( const DenseVector<VT2,TF>& rhs )
1479 {
1482 
1483  if( size() != (~rhs).size() ) {
1484  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1485  }
1486 
1487  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
1488  Right right( ~rhs );
1489 
1490  if( !tryDivAssign( vector_, right, offset_ ) ) {
1491  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1492  }
1493 
1494  DerestrictTrait_<This> left( derestrict( *this ) );
1495 
1496  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1497  const ResultType_<VT2> tmp( right );
1498  smpDivAssign( left, tmp );
1499  }
1500  else {
1501  smpDivAssign( left, right );
1502  }
1503 
1504  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1505 
1506  return *this;
1507 }
1509 //*************************************************************************************************
1510 
1511 
1512 //*************************************************************************************************
1520 template< typename VT // Type of the dense vector
1521  , bool TF > // Transpose flag
1522 template< typename Other > // Data type of the right-hand side scalar
1523 inline EnableIf_< IsNumeric<Other>, Subvector<VT,unaligned,TF,true> >&
1525 {
1526  DerestrictTrait_<This> left( derestrict( *this ) );
1527  smpAssign( left, (*this) * rhs );
1528 
1529  return *this;
1530 }
1532 //*************************************************************************************************
1533 
1534 
1535 //*************************************************************************************************
1545 template< typename VT // Type of the dense vector
1546  , bool TF > // Transpose flag
1547 template< typename Other > // Data type of the right-hand side scalar
1548 inline EnableIf_< IsNumeric<Other>, Subvector<VT,unaligned,TF,true> >&
1550 {
1551  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1552 
1553  DerestrictTrait_<This> left( derestrict( *this ) );
1554  smpAssign( left, (*this) / rhs );
1555 
1556  return *this;
1557 }
1559 //*************************************************************************************************
1560 
1561 
1562 
1563 
1564 //=================================================================================================
1565 //
1566 // UTILITY FUNCTIONS
1567 //
1568 //=================================================================================================
1569 
1570 //*************************************************************************************************
1576 template< typename VT // Type of the dense vector
1577  , bool TF > // Transpose flag
1578 inline size_t Subvector<VT,unaligned,TF,true>::size() const noexcept
1579 {
1580  return size_;
1581 }
1583 //*************************************************************************************************
1584 
1585 
1586 //*************************************************************************************************
1592 template< typename VT // Type of the dense vector
1593  , bool TF > // Transpose flag
1594 inline size_t Subvector<VT,unaligned,TF,true>::capacity() const noexcept
1595 {
1596  return vector_.capacity() - offset_;
1597 }
1599 //*************************************************************************************************
1600 
1601 
1602 //*************************************************************************************************
1611 template< typename VT // Type of the dense vector
1612  , bool TF > // Transpose flag
1613 inline size_t Subvector<VT,unaligned,TF,true>::nonZeros() const
1614 {
1615  size_t nonzeros( 0 );
1616 
1617  const size_t iend( offset_ + size_ );
1618  for( size_t i=offset_; i<iend; ++i ) {
1619  if( !isDefault( vector_[i] ) )
1620  ++nonzeros;
1621  }
1622 
1623  return nonzeros;
1624 }
1626 //*************************************************************************************************
1627 
1628 
1629 //*************************************************************************************************
1635 template< typename VT // Type of the dense vector
1636  , bool TF > // Transpose flag
1638 {
1639  using blaze::clear;
1640 
1641  const size_t iend( offset_ + size_ );
1642  for( size_t i=offset_; i<iend; ++i )
1643  clear( vector_[i] );
1644 }
1646 //*************************************************************************************************
1647 
1648 
1649 //*************************************************************************************************
1656 template< typename VT // Type of the dense vector
1657  , bool TF > // Transpose flag
1658 template< typename Other > // Data type of the scalar value
1659 inline Subvector<VT,unaligned,TF,true>&
1660  Subvector<VT,unaligned,TF,true>::scale( const Other& scalar )
1661 {
1662  const size_t iend( offset_ + size_ );
1663  for( size_t i=offset_; i<iend; ++i )
1664  vector_[i] *= scalar;
1665  return *this;
1666 }
1668 //*************************************************************************************************
1669 
1670 
1671 
1672 
1673 //=================================================================================================
1674 //
1675 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1676 //
1677 //=================================================================================================
1678 
1679 //*************************************************************************************************
1690 template< typename VT // Type of the dense vector
1691  , bool TF > // Transpose flag
1692 template< typename Other > // Data type of the foreign expression
1693 inline bool Subvector<VT,unaligned,TF,true>::canAlias( const Other* alias ) const noexcept
1694 {
1695  return vector_.isAliased( alias );
1696 }
1698 //*************************************************************************************************
1699 
1700 
1701 //*************************************************************************************************
1712 template< typename VT // Type of the dense vector
1713  , bool TF > // Transpose flag
1714 template< typename VT2 // Data type of the foreign dense subvector
1715  , bool AF2 // Alignment flag of the foreign dense subvector
1716  , bool TF2 > // Transpose flag of the foreign dense subvector
1717 inline bool Subvector<VT,unaligned,TF,true>::canAlias( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept
1718 {
1719  return ( vector_.isAliased( &alias->vector_ ) &&
1720  ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
1721 }
1723 //*************************************************************************************************
1724 
1725 
1726 //*************************************************************************************************
1737 template< typename VT // Type of the dense vector
1738  , bool TF > // Transpose flag
1739 template< typename Other > // Data type of the foreign expression
1740 inline bool Subvector<VT,unaligned,TF,true>::isAliased( const Other* alias ) const noexcept
1741 {
1742  return vector_.isAliased( alias );
1743 }
1745 //*************************************************************************************************
1746 
1747 
1748 //*************************************************************************************************
1759 template< typename VT // Type of the dense vector
1760  , bool TF > // Transpose flag
1761 template< typename VT2 // Data type of the foreign dense subvector
1762  , bool AF2 // Alignment flag of the foreign dense subvector
1763  , bool TF2 > // Transpose flag of the foreign dense subvector
1764 inline bool Subvector<VT,unaligned,TF,true>::isAliased( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept
1765 {
1766  return ( vector_.isAliased( &alias->vector_ ) &&
1767  ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
1768 }
1770 //*************************************************************************************************
1771 
1772 
1773 //*************************************************************************************************
1783 template< typename VT // Type of the dense vector
1784  , bool TF > // Transpose flag
1785 inline bool Subvector<VT,unaligned,TF,true>::isAligned() const noexcept
1786 {
1787  return isAligned_;
1788 }
1790 //*************************************************************************************************
1791 
1792 
1793 //*************************************************************************************************
1804 template< typename VT // Type of the dense vector
1805  , bool TF > // Transpose flag
1806 inline bool Subvector<VT,unaligned,TF,true>::canSMPAssign() const noexcept
1807 {
1808  return ( size() > SMP_DVECASSIGN_THRESHOLD );
1809 }
1811 //*************************************************************************************************
1812 
1813 
1814 //*************************************************************************************************
1828 template< typename VT // Type of the dense vector
1829  , bool TF > // Transpose flag
1830 BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true>::SIMDType
1831  Subvector<VT,unaligned,TF,true>::load( size_t index ) const noexcept
1832 {
1833  if( isAligned_ )
1834  return loada( index );
1835  else
1836  return loadu( index );
1837 }
1839 //*************************************************************************************************
1840 
1841 
1842 //*************************************************************************************************
1856 template< typename VT // Type of the dense vector
1857  , bool TF > // Transpose flag
1858 BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true>::SIMDType
1859  Subvector<VT,unaligned,TF,true>::loada( size_t index ) const noexcept
1860 {
1862 
1863  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
1864  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
1865  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
1866 
1867  return vector_.loada( offset_+index );
1868 }
1870 //*************************************************************************************************
1871 
1872 
1873 //*************************************************************************************************
1887 template< typename VT // Type of the dense vector
1888  , bool TF > // Transpose flag
1889 BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true>::SIMDType
1890  Subvector<VT,unaligned,TF,true>::loadu( size_t index ) const noexcept
1891 {
1893 
1894  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
1895  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
1896  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
1897 
1898  return vector_.loadu( offset_+index );
1899 }
1901 //*************************************************************************************************
1902 
1903 
1904 //*************************************************************************************************
1919 template< typename VT // Type of the dense vector
1920  , bool TF > // Transpose flag
1922  Subvector<VT,unaligned,TF,true>::store( size_t index, const SIMDType& value ) noexcept
1923 {
1924  if( isAligned_ )
1925  storea( index, value );
1926  else
1927  storeu( index, value );
1928 }
1930 //*************************************************************************************************
1931 
1932 
1933 //*************************************************************************************************
1948 template< typename VT // Type of the dense vector
1949  , bool TF > // Transpose flag
1951  Subvector<VT,unaligned,TF,true>::storea( size_t index, const SIMDType& value ) noexcept
1952 {
1954 
1955  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
1956  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
1957  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
1958 
1959  vector_.storea( offset_+index, value );
1960 }
1962 //*************************************************************************************************
1963 
1964 
1965 //*************************************************************************************************
1980 template< typename VT // Type of the dense vector
1981  , bool TF > // Transpose flag
1983  Subvector<VT,unaligned,TF,true>::storeu( size_t index, const SIMDType& value ) noexcept
1984 {
1986 
1987  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
1988  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
1989  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
1990 
1991  vector_.storeu( offset_+index, value );
1992 }
1994 //*************************************************************************************************
1995 
1996 
1997 //*************************************************************************************************
2012 template< typename VT // Type of the dense vector
2013  , bool TF > // Transpose flag
2015  Subvector<VT,unaligned,TF,true>::stream( size_t index, const SIMDType& value ) noexcept
2016 {
2018 
2019  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
2020  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
2021  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
2022 
2023  if( isAligned_ )
2024  vector_.stream( offset_+index, value );
2025  else
2026  vector_.storeu( offset_+index, value );
2027 }
2029 //*************************************************************************************************
2030 
2031 
2032 //*************************************************************************************************
2044 template< typename VT // Type of the dense vector
2045  , bool TF > // Transpose flag
2046 template< typename VT2 > // Type of the right-hand side dense vector
2047 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
2048  Subvector<VT,unaligned,TF,true>::assign( const DenseVector<VT2,TF>& rhs )
2049 {
2050  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2051 
2052  const size_t ipos( size() & size_t(-2) );
2053  for( size_t i=0UL; i<ipos; i+=2UL ) {
2054  vector_[offset_+i ] = (~rhs)[i ];
2055  vector_[offset_+i+1UL] = (~rhs)[i+1UL];
2056  }
2057  if( ipos < size() ) {
2058  vector_[offset_+ipos] = (~rhs)[ipos];
2059  }
2060 }
2062 //*************************************************************************************************
2063 
2064 
2065 //*************************************************************************************************
2077 template< typename VT // Type of the dense vector
2078  , bool TF > // Transpose flag
2079 template< typename VT2 > // Type of the right-hand side dense vector
2080 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
2081  Subvector<VT,unaligned,TF,true>::assign( const DenseVector<VT2,TF>& rhs )
2082 {
2084 
2085  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2086 
2087  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2088  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2089 
2090  size_t i( 0UL );
2091  Iterator left( begin() );
2092  ConstIterator_<VT2> right( (~rhs).begin() );
2093 
2094  if( useStreaming && isAligned_ &&
2095  ( size_ > ( cacheSize/( sizeof(ElementType) * 3UL ) ) ) &&
2096  !(~rhs).isAliased( &vector_ ) )
2097  {
2098  for( ; i<ipos; i+=SIMDSIZE ) {
2099  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2100  }
2101  for( ; i<size_; ++i ) {
2102  *left = *right;
2103  }
2104  }
2105  else
2106  {
2107  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2108  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2109  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2110  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2111  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2112  }
2113  for( ; i<ipos; i+=SIMDSIZE ) {
2114  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2115  }
2116  for( ; i<size_; ++i ) {
2117  *left = *right; ++left; ++right;
2118  }
2119  }
2120 }
2122 //*************************************************************************************************
2123 
2124 
2125 //*************************************************************************************************
2137 template< typename VT // Type of the dense vector
2138  , bool TF > // Transpose flag
2139 template< typename VT2 > // Type of the right-hand side sparse vector
2140 inline void Subvector<VT,unaligned,TF,true>::assign( const SparseVector<VT2,TF>& rhs )
2141 {
2142  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2143 
2144  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2145  vector_[offset_+element->index()] = element->value();
2146 }
2148 //*************************************************************************************************
2149 
2150 
2151 //*************************************************************************************************
2163 template< typename VT // Type of the dense vector
2164  , bool TF > // Transpose flag
2165 template< typename VT2 > // Type of the right-hand side dense vector
2166 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
2167  Subvector<VT,unaligned,TF,true>::addAssign( const DenseVector<VT2,TF>& rhs )
2168 {
2169  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2170 
2171  const size_t ipos( size() & size_t(-2) );
2172  for( size_t i=0UL; i<ipos; i+=2UL ) {
2173  vector_[offset_+i ] += (~rhs)[i ];
2174  vector_[offset_+i+1UL] += (~rhs)[i+1UL];
2175  }
2176  if( ipos < size() ) {
2177  vector_[offset_+ipos] += (~rhs)[ipos];
2178  }
2179 }
2181 //*************************************************************************************************
2182 
2183 
2184 //*************************************************************************************************
2196 template< typename VT // Type of the dense vector
2197  , bool TF > // Transpose flag
2198 template< typename VT2 > // Type of the right-hand side dense vector
2199 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
2200  Subvector<VT,unaligned,TF,true>::addAssign( const DenseVector<VT2,TF>& rhs )
2201 {
2203 
2204  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2205 
2206  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2207  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2208 
2209  size_t i( 0UL );
2210  Iterator left( begin() );
2211  ConstIterator_<VT2> right( (~rhs).begin() );
2212 
2213  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2214  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2215  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2216  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2217  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2218  }
2219  for( ; i<ipos; i+=SIMDSIZE ) {
2220  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2221  }
2222  for( ; i<size_; ++i ) {
2223  *left += *right; ++left; ++right;
2224  }
2225 }
2227 //*************************************************************************************************
2228 
2229 
2230 //*************************************************************************************************
2242 template< typename VT // Type of the dense vector
2243  , bool TF > // Transpose flag
2244 template< typename VT2 > // Type of the right-hand side sparse vector
2245 inline void Subvector<VT,unaligned,TF,true>::addAssign( const SparseVector<VT2,TF>& rhs )
2246 {
2247  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2248 
2249  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2250  vector_[offset_+element->index()] += element->value();
2251 }
2253 //*************************************************************************************************
2254 
2255 
2256 //*************************************************************************************************
2268 template< typename VT // Type of the dense vector
2269  , bool TF > // Transpose flag
2270 template< typename VT2 > // Type of the right-hand side dense vector
2271 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
2272  Subvector<VT,unaligned,TF,true>::subAssign( const DenseVector<VT2,TF>& rhs )
2273 {
2274  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2275 
2276  const size_t ipos( size() & size_t(-2) );
2277  for( size_t i=0UL; i<ipos; i+=2UL ) {
2278  vector_[offset_+i ] -= (~rhs)[i ];
2279  vector_[offset_+i+1UL] -= (~rhs)[i+1UL];
2280  }
2281  if( ipos < size() ) {
2282  vector_[offset_+ipos] -= (~rhs)[ipos];
2283  }
2284 }
2286 //*************************************************************************************************
2287 
2288 
2289 //*************************************************************************************************
2301 template< typename VT // Type of the dense vector
2302  , bool TF > // Transpose flag
2303 template< typename VT2 > // Type of the right-hand side dense vector
2304 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
2305  Subvector<VT,unaligned,TF,true>::subAssign( const DenseVector<VT2,TF>& rhs )
2306 {
2308 
2309  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2310 
2311  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2312  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2313 
2314  size_t i( 0UL );
2315  Iterator left( begin() );
2316  ConstIterator_<VT2> right( (~rhs).begin() );
2317 
2318  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2319  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2320  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2321  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2322  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2323  }
2324  for( ; i<ipos; i+=SIMDSIZE ) {
2325  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2326  }
2327  for( ; i<size_; ++i ) {
2328  *left -= *right; ++left; ++right;
2329  }
2330 }
2332 //*************************************************************************************************
2333 
2334 
2335 //*************************************************************************************************
2347 template< typename VT // Type of the dense vector
2348  , bool TF > // Transpose flag
2349 template< typename VT2 > // Type of the right-hand side sparse vector
2350 inline void Subvector<VT,unaligned,TF,true>::subAssign( const SparseVector<VT2,TF>& rhs )
2351 {
2352  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2353 
2354  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2355  vector_[offset_+element->index()] -= element->value();
2356 }
2358 //*************************************************************************************************
2359 
2360 
2361 //*************************************************************************************************
2373 template< typename VT // Type of the dense vector
2374  , bool TF > // Transpose flag
2375 template< typename VT2 > // Type of the right-hand side dense vector
2376 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
2377  Subvector<VT,unaligned,TF,true>::multAssign( const DenseVector<VT2,TF>& rhs )
2378 {
2379  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2380 
2381  const size_t ipos( size() & size_t(-2) );
2382  for( size_t i=0UL; i<ipos; i+=2UL ) {
2383  vector_[offset_+i ] *= (~rhs)[i ];
2384  vector_[offset_+i+1UL] *= (~rhs)[i+1UL];
2385  }
2386  if( ipos < size() ) {
2387  vector_[offset_+ipos] *= (~rhs)[ipos];
2388  }
2389 }
2391 //*************************************************************************************************
2392 
2393 
2394 //*************************************************************************************************
2406 template< typename VT // Type of the dense vector
2407  , bool TF > // Transpose flag
2408 template< typename VT2 > // Type of the right-hand side dense vector
2409 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
2410  Subvector<VT,unaligned,TF,true>::multAssign( const DenseVector<VT2,TF>& rhs )
2411 {
2413 
2414  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2415 
2416  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2417  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2418 
2419  size_t i( 0UL );
2420  Iterator left( begin() );
2421  ConstIterator_<VT2> right( (~rhs).begin() );
2422 
2423  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2424  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2425  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2426  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2427  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2428  }
2429  for( ; i<ipos; i+=SIMDSIZE ) {
2430  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2431  }
2432  for( ; i<size_; ++i ) {
2433  *left *= *right; ++left; ++right;
2434  }
2435 }
2437 //*************************************************************************************************
2438 
2439 
2440 //*************************************************************************************************
2452 template< typename VT // Type of the dense vector
2453  , bool TF > // Transpose flag
2454 template< typename VT2 > // Type of the right-hand side sparse vector
2455 inline void Subvector<VT,unaligned,TF,true>::multAssign( const SparseVector<VT2,TF>& rhs )
2456 {
2457  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2458 
2459  const ResultType tmp( serial( *this ) );
2460 
2461  reset();
2462 
2463  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2464  vector_[offset_+element->index()] = tmp[element->index()] * element->value();
2465 }
2467 //*************************************************************************************************
2468 
2469 
2470 //*************************************************************************************************
2482 template< typename VT // Type of the dense vector
2483  , bool TF > // Transpose flag
2484 template< typename VT2 > // Type of the right-hand side dense vector
2485 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
2486  Subvector<VT,unaligned,TF,true>::divAssign( const DenseVector<VT2,TF>& rhs )
2487 {
2488  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2489 
2490  const size_t ipos( size() & size_t(-2) );
2491  for( size_t i=0UL; i<ipos; i+=2UL ) {
2492  vector_[offset_+i ] /= (~rhs)[i ];
2493  vector_[offset_+i+1UL] /= (~rhs)[i+1UL];
2494  }
2495  if( ipos < size() ) {
2496  vector_[offset_+ipos] /= (~rhs)[ipos];
2497  }
2498 }
2500 //*************************************************************************************************
2501 
2502 
2503 //*************************************************************************************************
2515 template< typename VT // Type of the dense vector
2516  , bool TF > // Transpose flag
2517 template< typename VT2 > // Type of the right-hand side dense vector
2518 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
2519  Subvector<VT,unaligned,TF,true>::divAssign( const DenseVector<VT2,TF>& rhs )
2520 {
2522 
2523  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2524 
2525  const size_t ipos( size_ & size_t(-SIMDSIZE) );
2526  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2527 
2528  size_t i( 0UL );
2529  Iterator left( begin() );
2530  ConstIterator_<VT2> right( (~rhs).begin() );
2531 
2532  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2533  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2534  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2535  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2536  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2537  }
2538  for( ; i<ipos; i+=SIMDSIZE ) {
2539  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2540  }
2541  for( ; i<size_; ++i ) {
2542  *left /= *right; ++left; ++right;
2543  }
2544 }
2546 //*************************************************************************************************
2547 
2548 
2549 
2550 
2551 
2552 
2553 
2554 
2555 //=================================================================================================
2556 //
2557 // CLASS TEMPLATE SPECIALIZATION FOR ALIGNED DENSE SUBVECTORS
2558 //
2559 //=================================================================================================
2560 
2561 //*************************************************************************************************
2569 template< typename VT // Type of the dense vector
2570  , bool TF > // Transpose flag
2571 class Subvector<VT,aligned,TF,true>
2572  : public DenseVector< Subvector<VT,aligned,TF,true>, TF >
2573  , private View
2574 {
2575  private:
2576  //**Type definitions****************************************************************************
2578  typedef If_< IsExpression<VT>, VT, VT& > Operand;
2579  //**********************************************************************************************
2580 
2581  public:
2582  //**Type definitions****************************************************************************
2583  typedef Subvector<VT,aligned,TF,true> This;
2584  typedef DenseVector<This,TF> BaseType;
2585  typedef SubvectorTrait_<VT> ResultType;
2586  typedef TransposeType_<ResultType> TransposeType;
2587  typedef ElementType_<VT> ElementType;
2588  typedef SIMDTrait_<ElementType> SIMDType;
2589  typedef ReturnType_<VT> ReturnType;
2590  typedef const Subvector& CompositeType;
2591 
2593  typedef ConstReference_<VT> ConstReference;
2594 
2596  typedef If_< IsConst<VT>, ConstReference, Reference_<VT> > Reference;
2597 
2599  typedef const ElementType* ConstPointer;
2600 
2602  typedef If_< Or< IsConst<VT>, Not< HasMutableDataAccess<VT> > >, ConstPointer, ElementType* > Pointer;
2603 
2605  typedef ConstIterator_<VT> ConstIterator;
2606 
2608  typedef If_< IsConst<VT>, ConstIterator, Iterator_<VT> > Iterator;
2609  //**********************************************************************************************
2610 
2611  //**Compilation flags***************************************************************************
2613  enum : bool { simdEnabled = VT::simdEnabled };
2614 
2616  enum : bool { smpAssignable = VT::smpAssignable };
2617  //**********************************************************************************************
2618 
2619  //**Constructors********************************************************************************
2622  explicit inline Subvector( Operand vector, size_t index, size_t n );
2623  // No explicitly declared copy constructor.
2625  //**********************************************************************************************
2626 
2627  //**Destructor**********************************************************************************
2628  // No explicitly declared destructor.
2629  //**********************************************************************************************
2630 
2631  //**Data access functions***********************************************************************
2634  inline Reference operator[]( size_t index );
2635  inline ConstReference operator[]( size_t index ) const;
2636  inline Reference at( size_t index );
2637  inline ConstReference at( size_t index ) const;
2638  inline Pointer data () noexcept;
2639  inline ConstPointer data () const noexcept;
2640  inline Iterator begin ();
2641  inline ConstIterator begin () const;
2642  inline ConstIterator cbegin() const;
2643  inline Iterator end ();
2644  inline ConstIterator end () const;
2645  inline ConstIterator cend () const;
2647  //**********************************************************************************************
2648 
2649  //**Assignment operators************************************************************************
2652  inline Subvector& operator= ( const ElementType& rhs );
2653  inline Subvector& operator= ( initializer_list<ElementType> list );
2654  inline Subvector& operator= ( const Subvector& rhs );
2655  template< typename VT2 > inline Subvector& operator= ( const Vector<VT2,TF>& rhs );
2656  template< typename VT2 > inline Subvector& operator+=( const Vector<VT2,TF>& rhs );
2657  template< typename VT2 > inline Subvector& operator-=( const Vector<VT2,TF>& rhs );
2658  template< typename VT2 > inline Subvector& operator*=( const DenseVector<VT2,TF>& rhs );
2659  template< typename VT2 > inline Subvector& operator*=( const SparseVector<VT2,TF>& rhs );
2660  template< typename VT2 > inline Subvector& operator/=( const DenseVector<VT2,TF>& rhs );
2661 
2662  template< typename Other >
2663  inline EnableIf_< IsNumeric<Other>, Subvector >& operator*=( Other rhs );
2664 
2665  template< typename Other >
2666  inline EnableIf_< IsNumeric<Other>, Subvector >& operator/=( Other rhs );
2668  //**********************************************************************************************
2669 
2670  //**Utility functions***************************************************************************
2673  inline size_t size() const noexcept;
2674  inline size_t capacity() const noexcept;
2675  inline size_t nonZeros() const;
2676  inline void reset();
2677  template< typename Other > inline Subvector& scale( const Other& scalar );
2679  //**********************************************************************************************
2680 
2681  private:
2682  //**********************************************************************************************
2684  template< typename VT2 >
2685  struct VectorizedAssign {
2686  enum : bool { value = useOptimizedKernels &&
2687  simdEnabled && VT2::simdEnabled &&
2688  AreSIMDCombinable< ElementType, ElementType_<VT2> >::value };
2689  };
2690  //**********************************************************************************************
2691 
2692  //**********************************************************************************************
2694  template< typename VT2 >
2695  struct VectorizedAddAssign {
2696  enum : bool { value = useOptimizedKernels &&
2697  simdEnabled && VT2::simdEnabled &&
2698  AreSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2699  HasSIMDAdd< ElementType, ElementType_<VT2> >::value };
2700  };
2701  //**********************************************************************************************
2702 
2703  //**********************************************************************************************
2705  template< typename VT2 >
2706  struct VectorizedSubAssign {
2707  enum : bool { value = useOptimizedKernels &&
2708  simdEnabled && VT2::simdEnabled &&
2709  AreSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2710  HasSIMDSub< ElementType, ElementType_<VT2> >::value };
2711  };
2712  //**********************************************************************************************
2713 
2714  //**********************************************************************************************
2716  template< typename VT2 >
2717  struct VectorizedMultAssign {
2718  enum : bool { value = useOptimizedKernels &&
2719  simdEnabled && VT2::simdEnabled &&
2720  AreSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2721  HasSIMDMult< ElementType, ElementType_<VT2> >::value };
2722  };
2723  //**********************************************************************************************
2724 
2725  //**********************************************************************************************
2727  template< typename VT2 >
2728  struct VectorizedDivAssign {
2729  enum : bool { value = useOptimizedKernels &&
2730  simdEnabled && VT2::simdEnabled &&
2731  AreSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2732  HasSIMDDiv< ElementType, ElementType_<VT2> >::value };
2733  };
2734  //**********************************************************************************************
2735 
2736  //**SIMD properties*****************************************************************************
2738  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
2739  //**********************************************************************************************
2740 
2741  public:
2742  //**Expression template evaluation functions****************************************************
2745  template< typename Other >
2746  inline bool canAlias( const Other* alias ) const noexcept;
2747 
2748  template< typename VT2, bool AF2, bool TF2 >
2749  inline bool canAlias( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept;
2750 
2751  template< typename Other >
2752  inline bool isAliased( const Other* alias ) const noexcept;
2753 
2754  template< typename VT2, bool AF2, bool TF2 >
2755  inline bool isAliased( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept;
2756 
2757  inline bool isAligned () const noexcept;
2758  inline bool canSMPAssign() const noexcept;
2759 
2760  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
2761  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
2762  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
2763 
2764  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
2765  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
2766  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
2767  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
2768 
2769  template< typename VT2 >
2770  inline DisableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
2771 
2772  template< typename VT2 >
2773  inline EnableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
2774 
2775  template< typename VT2 > inline void assign( const SparseVector<VT2,TF>& rhs );
2776 
2777  template< typename VT2 >
2778  inline DisableIf_< VectorizedAddAssign<VT2> > addAssign( const DenseVector <VT2,TF>& rhs );
2779 
2780  template< typename VT2 >
2781  inline EnableIf_< VectorizedAddAssign<VT2> > addAssign ( const DenseVector <VT2,TF>& rhs );
2782 
2783  template< typename VT2 > inline void addAssign( const SparseVector<VT2,TF>& rhs );
2784 
2785  template< typename VT2 >
2786  inline DisableIf_< VectorizedSubAssign<VT2> > subAssign ( const DenseVector <VT2,TF>& rhs );
2787 
2788  template< typename VT2 >
2789  inline EnableIf_< VectorizedSubAssign<VT2> > subAssign( const DenseVector <VT2,TF>& rhs );
2790 
2791  template< typename VT2 > inline void subAssign( const SparseVector<VT2,TF>& rhs );
2792 
2793  template< typename VT2 >
2794  inline DisableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
2795 
2796  template< typename VT2 >
2797  inline EnableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
2798 
2799  template< typename VT2 > inline void multAssign( const SparseVector<VT2,TF>& rhs );
2800 
2801  template< typename VT2 >
2802  inline DisableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
2803 
2804  template< typename VT2 >
2805  inline EnableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
2807  //**********************************************************************************************
2808 
2809  private:
2810  //**Member variables****************************************************************************
2813  Operand vector_;
2814  const size_t offset_;
2815  const size_t size_;
2816 
2817  //**********************************************************************************************
2818 
2819  //**Friend declarations*************************************************************************
2820  template< typename VT2, bool AF2, bool TF2, bool DF2 > friend class Subvector;
2821 
2822  template< bool AF1, typename VT2, bool AF2, bool TF2, bool DF2 >
2823  friend const Subvector<VT2,AF1,TF2,DF2>
2824  subvector( const Subvector<VT2,AF2,TF2,DF2>& sv, size_t index, size_t size );
2825 
2826  template< typename VT2, bool AF2, bool TF2, bool DF2 >
2827  friend bool isIntact( const Subvector<VT2,AF2,TF2,DF2>& sv ) noexcept;
2828 
2829  template< typename VT2, bool AF2, bool TF2, bool DF2 >
2830  friend bool isSame( const Subvector<VT2,AF2,TF2,DF2>& a, const Vector<VT2,TF2>& b ) noexcept;
2831 
2832  template< typename VT2, bool AF2, bool TF2, bool DF2 >
2833  friend bool isSame( const Vector<VT2,TF2>& a, const Subvector<VT2,AF2,TF2,DF2>& b ) noexcept;
2834 
2835  template< typename VT2, bool AF2, bool TF2, bool DF2 >
2836  friend bool isSame( const Subvector<VT2,AF2,TF2,DF2>& a, const Subvector<VT2,AF2,TF2,DF2>& b ) noexcept;
2837 
2838  template< typename VT2, bool AF2, bool TF2, bool DF2, typename VT3 >
2839  friend bool tryAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
2840 
2841  template< typename VT2, bool AF2, bool TF2, bool DF2, typename VT3 >
2842  friend bool tryAddAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
2843 
2844  template< typename VT2, bool AF2, bool TF2, bool DF2, typename VT3 >
2845  friend bool trySubAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
2846 
2847  template< typename VT2, bool AF2, bool TF2, bool DF2, typename VT3 >
2848  friend bool tryMultAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
2849 
2850  template< typename VT2, bool AF2, bool TF2, bool DF2 >
2851  friend DerestrictTrait_< Subvector<VT2,AF2,TF2,DF2> > derestrict( Subvector<VT2,AF2,TF2,DF2>& sv );
2852  //**********************************************************************************************
2853 
2854  //**Compile time checks*************************************************************************
2860  //**********************************************************************************************
2861 };
2863 //*************************************************************************************************
2864 
2865 
2866 
2867 
2868 //=================================================================================================
2869 //
2870 // CONSTRUCTOR
2871 //
2872 //=================================================================================================
2873 
2874 //*************************************************************************************************
2887 template< typename VT // Type of the dense vector
2888  , bool TF > // Transpose flag
2889 inline Subvector<VT,aligned,TF,true>::Subvector( Operand vector, size_t index, size_t n )
2890  : vector_( vector ) // The vector containing the subvector
2891  , offset_( index ) // The offset of the subvector within the dense vector
2892  , size_ ( n ) // The size of the subvector
2893 {
2894  if( index + n > vector.size() ) {
2895  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
2896  }
2897 
2898  if( simdEnabled && vector_.data() != nullptr && !checkAlignment( data() ) ) {
2899  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector alignment" );
2900  }
2901 }
2903 //*************************************************************************************************
2904 
2905 
2906 
2907 
2908 //=================================================================================================
2909 //
2910 // DATA ACCESS FUNCTIONS
2911 //
2912 //=================================================================================================
2913 
2914 //*************************************************************************************************
2921 template< typename VT // Type of the dense vector
2922  , bool TF > // Transpose flag
2924  Subvector<VT,aligned,TF,true>::operator[]( size_t index )
2925 {
2926  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
2927  return vector_[offset_+index];
2928 }
2930 //*************************************************************************************************
2931 
2932 
2933 //*************************************************************************************************
2940 template< typename VT // Type of the dense vector
2941  , bool TF > // Transpose flag
2943  Subvector<VT,aligned,TF,true>::operator[]( size_t index ) const
2944 {
2945  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
2946  return const_cast<const VT&>( vector_ )[offset_+index];
2947 }
2949 //*************************************************************************************************
2950 
2951 
2952 //*************************************************************************************************
2963 template< typename VT // Type of the dense vector
2964  , bool TF > // Transpose flag
2966  Subvector<VT,aligned,TF,true>::at( size_t index )
2967 {
2968  if( index >= size() ) {
2969  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
2970  }
2971  return (*this)[index];
2972 }
2974 //*************************************************************************************************
2975 
2976 
2977 //*************************************************************************************************
2988 template< typename VT // Type of the dense vector
2989  , bool TF > // Transpose flag
2991  Subvector<VT,aligned,TF,true>::at( size_t index ) const
2992 {
2993  if( index >= size() ) {
2994  BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
2995  }
2996  return (*this)[index];
2997 }
2999 //*************************************************************************************************
3000 
3001 
3002 //*************************************************************************************************
3010 template< typename VT // Type of the dense vector
3011  , bool TF > // Transpose flag
3012 inline typename Subvector<VT,aligned,TF,true>::Pointer Subvector<VT,aligned,TF,true>::data() noexcept
3013 {
3014  return vector_.data() + offset_;
3015 }
3017 //*************************************************************************************************
3018 
3019 
3020 //*************************************************************************************************
3028 template< typename VT // Type of the dense vector
3029  , bool TF > // Transpose flag
3030 inline typename Subvector<VT,aligned,TF,true>::ConstPointer
3031  Subvector<VT,aligned,TF,true>::data() const noexcept
3032 {
3033  return vector_.data() + offset_;
3034 }
3036 //*************************************************************************************************
3037 
3038 
3039 //*************************************************************************************************
3047 template< typename VT // Type of the dense vector
3048  , bool TF > // Transpose flag
3050 {
3051  return ( vector_.begin() + offset_ );
3052 }
3054 //*************************************************************************************************
3055 
3056 
3057 //*************************************************************************************************
3065 template< typename VT // Type of the dense vector
3066  , bool TF > // Transpose flag
3069 {
3070  return ( vector_.cbegin() + offset_ );
3071 }
3073 //*************************************************************************************************
3074 
3075 
3076 //*************************************************************************************************
3084 template< typename VT // Type of the dense vector
3085  , bool TF > // Transpose flag
3088 {
3089  return ( vector_.cbegin() + offset_ );
3090 }
3092 //*************************************************************************************************
3093 
3094 
3095 //*************************************************************************************************
3103 template< typename VT // Type of the dense vector
3104  , bool TF > // Transpose flag
3106 {
3107  return ( vector_.begin() + offset_ + size_ );
3108 }
3110 //*************************************************************************************************
3111 
3112 
3113 //*************************************************************************************************
3121 template< typename VT // Type of the dense vector
3122  , bool TF > // Transpose flag
3125 {
3126  return ( vector_.cbegin() + offset_ + size_ );
3127 }
3129 //*************************************************************************************************
3130 
3131 
3132 //*************************************************************************************************
3140 template< typename VT // Type of the dense vector
3141  , bool TF > // Transpose flag
3144 {
3145  return ( vector_.cbegin() + offset_ + size_ );
3146 }
3148 //*************************************************************************************************
3149 
3150 
3151 
3152 
3153 //=================================================================================================
3154 //
3155 // ASSIGNMENT OPERATORS
3156 //
3157 //=================================================================================================
3158 
3159 //*************************************************************************************************
3166 template< typename VT // Type of the dense vector
3167  , bool TF > // Transpose flag
3168 inline Subvector<VT,aligned,TF,true>&
3169  Subvector<VT,aligned,TF,true>::operator=( const ElementType& rhs )
3170 {
3171  const size_t iend( offset_ + size_ );
3172 
3173  for( size_t i=offset_; i<iend; ++i )
3174  vector_[i] = rhs;
3175 
3176  return *this;
3177 }
3179 //*************************************************************************************************
3180 
3181 
3182 //*************************************************************************************************
3195 template< typename VT // Type of the dense vector
3196  , bool TF > // Transpose flag
3197 inline Subvector<VT,aligned,TF,true>&
3198  Subvector<VT,aligned,TF,true>::operator=( initializer_list<ElementType> list )
3199 {
3200  if( list.size() > size() ) {
3201  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to subvector" );
3202  }
3203 
3204  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
3205 
3206  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3207 
3208  return *this;
3209 }
3211 //*************************************************************************************************
3212 
3213 
3214 //*************************************************************************************************
3226 template< typename VT // Type of the dense vector
3227  , bool TF > // Transpose flag
3228 inline Subvector<VT,aligned,TF,true>&
3229  Subvector<VT,aligned,TF,true>::operator=( const Subvector& rhs )
3230 {
3233 
3234  if( &rhs == this || ( &vector_ == &rhs.vector_ && offset_ == rhs.offset_ ) )
3235  return *this;
3236 
3237  if( size() != rhs.size() ) {
3238  BLAZE_THROW_INVALID_ARGUMENT( "Subvector sizes do not match" );
3239  }
3240 
3241  if( !tryAssign( vector_, rhs, offset_ ) ) {
3242  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3243  }
3244 
3245  DerestrictTrait_<This> left( derestrict( *this ) );
3246 
3247  if( rhs.canAlias( &vector_ ) ) {
3248  const ResultType tmp( ~rhs );
3249  smpAssign( left, tmp );
3250  }
3251  else {
3252  smpAssign( left, rhs );
3253  }
3254 
3255  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3256 
3257  return *this;
3258 }
3260 //*************************************************************************************************
3261 
3262 
3263 //*************************************************************************************************
3275 template< typename VT // Type of the dense vector
3276  , bool TF > // Transpose flag
3277 template< typename VT2 > // Type of the right-hand side vector
3278 inline Subvector<VT,aligned,TF,true>&
3279  Subvector<VT,aligned,TF,true>::operator=( const Vector<VT2,TF>& rhs )
3280 {
3283 
3284  if( size() != (~rhs).size() ) {
3285  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3286  }
3287 
3288  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
3289  Right right( ~rhs );
3290 
3291  if( !tryAssign( vector_, right, offset_ ) ) {
3292  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3293  }
3294 
3295  DerestrictTrait_<This> left( derestrict( *this ) );
3296 
3297  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3298  const ResultType_<VT2> tmp( right );
3299  smpAssign( left, tmp );
3300  }
3301  else {
3302  if( IsSparseVector<VT2>::value )
3303  reset();
3304  smpAssign( left, right );
3305  }
3306 
3307  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3308 
3309  return *this;
3310 }
3312 //*************************************************************************************************
3313 
3314 
3315 //*************************************************************************************************
3327 template< typename VT // Type of the dense vector
3328  , bool TF > // Transpose flag
3329 template< typename VT2 > // Type of the right-hand side vector
3330 inline Subvector<VT,aligned,TF,true>&
3331  Subvector<VT,aligned,TF,true>::operator+=( const Vector<VT2,TF>& rhs )
3332 {
3335 
3336  if( size() != (~rhs).size() ) {
3337  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3338  }
3339 
3340  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
3341  Right right( ~rhs );
3342 
3343  if( !tryAddAssign( vector_, right, offset_ ) ) {
3344  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3345  }
3346 
3347  DerestrictTrait_<This> left( derestrict( *this ) );
3348 
3349  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3350  const ResultType_<VT2> tmp( right );
3351  smpAddAssign( left, tmp );
3352  }
3353  else {
3354  smpAddAssign( left, right );
3355  }
3356 
3357  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3358 
3359  return *this;
3360 }
3362 //*************************************************************************************************
3363 
3364 
3365 //*************************************************************************************************
3377 template< typename VT // Type of the dense vector
3378  , bool TF > // Transpose flag
3379 template< typename VT2 > // Type of the right-hand side vector
3380 inline Subvector<VT,aligned,TF,true>&
3381  Subvector<VT,aligned,TF,true>::operator-=( const Vector<VT2,TF>& rhs )
3382 {
3385 
3386  if( size() != (~rhs).size() ) {
3387  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3388  }
3389 
3390  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
3391  Right right( ~rhs );
3392 
3393  if( !trySubAssign( vector_, right, offset_ ) ) {
3394  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3395  }
3396 
3397  DerestrictTrait_<This> left( derestrict( *this ) );
3398 
3399  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3400  const ResultType_<VT2> tmp( right );
3401  smpSubAssign( left, tmp );
3402  }
3403  else {
3404  smpSubAssign( left, right );
3405  }
3406 
3407  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3408 
3409  return *this;
3410 }
3412 //*************************************************************************************************
3413 
3414 
3415 //*************************************************************************************************
3428 template< typename VT // Type of the dense vector
3429  , bool TF > // Transpose flag
3430 template< typename VT2 > // Type of the right-hand side dense vector
3431 inline Subvector<VT,aligned,TF,true>&
3432  Subvector<VT,aligned,TF,true>::operator*=( const DenseVector<VT2,TF>& rhs )
3433 {
3436 
3437  if( size() != (~rhs).size() ) {
3438  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3439  }
3440 
3441  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
3442  Right right( ~rhs );
3443 
3444  if( !tryMultAssign( vector_, right, offset_ ) ) {
3445  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3446  }
3447 
3448  DerestrictTrait_<This> left( derestrict( *this ) );
3449 
3450  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3451  const ResultType_<VT2> tmp( right );
3452  smpMultAssign( left, tmp );
3453  }
3454  else {
3455  smpMultAssign( left, right );
3456  }
3457 
3458  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3459 
3460  return *this;
3461 }
3463 //*************************************************************************************************
3464 
3465 
3466 //*************************************************************************************************
3479 template< typename VT // Type of the dense vector
3480  , bool TF > // Transpose flag
3481 template< typename VT2 > // Type of the right-hand side sparse vector
3482 inline Subvector<VT,aligned,TF,true>&
3483  Subvector<VT,aligned,TF,true>::operator*=( const SparseVector<VT2,TF>& rhs )
3484 {
3487 
3488  if( size() != (~rhs).size() ) {
3489  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3490  }
3491 
3492  const ResultType tmp( *this * (~rhs) );
3493 
3494  if( !tryAssign( vector_, tmp, offset_ ) ) {
3495  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3496  }
3497 
3498  DerestrictTrait_<This> left( derestrict( *this ) );
3499 
3500  smpAssign( left, tmp );
3501 
3502  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3503 
3504  return *this;
3505 }
3507 //*************************************************************************************************
3508 
3509 
3510 //*************************************************************************************************
3522 template< typename VT // Type of the dense vector
3523  , bool TF > // Transpose flag
3524 template< typename VT2 > // Type of the right-hand side dense vector
3525 inline Subvector<VT,aligned,TF,true>&
3526  Subvector<VT,aligned,TF,true>::operator/=( const DenseVector<VT2,TF>& rhs )
3527 {
3530 
3531  if( size() != (~rhs).size() ) {
3532  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3533  }
3534 
3535  typedef If_< IsRestricted<VT>, CompositeType_<VT2>, const VT2& > Right;
3536  Right right( ~rhs );
3537 
3538  if( !tryDivAssign( vector_, right, offset_ ) ) {
3539  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3540  }
3541 
3542  DerestrictTrait_<This> left( derestrict( *this ) );
3543 
3544  if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3545  const ResultType_<VT2> tmp( right );
3546  smpDivAssign( left, tmp );
3547  }
3548  else {
3549  smpDivAssign( left, right );
3550  }
3551 
3552  BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3553 
3554  return *this;
3555 }
3557 //*************************************************************************************************
3558 
3559 
3560 //*************************************************************************************************
3568 template< typename VT // Type of the dense vector
3569  , bool TF > // Transpose flag
3570 template< typename Other > // Data type of the right-hand side scalar
3571 inline EnableIf_< IsNumeric<Other>, Subvector<VT,aligned,TF,true> >&
3573 {
3574  DerestrictTrait_<This> left( derestrict( *this ) );
3575  smpAssign( left, (*this) * rhs );
3576 
3577  return *this;
3578 }
3580 //*************************************************************************************************
3581 
3582 
3583 //*************************************************************************************************
3593 template< typename VT // Type of the dense vector
3594  , bool TF > // Transpose flag
3595 template< typename Other > // Data type of the right-hand side scalar
3596 inline EnableIf_< IsNumeric<Other>, Subvector<VT,aligned,TF,true> >&
3598 {
3599  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3600 
3601  DerestrictTrait_<This> left( derestrict( *this ) );
3602  smpAssign( left, (*this) / rhs );
3603 
3604  return *this;
3605 }
3607 //*************************************************************************************************
3608 
3609 
3610 
3611 
3612 //=================================================================================================
3613 //
3614 // UTILITY FUNCTIONS
3615 //
3616 //=================================================================================================
3617 
3618 //*************************************************************************************************
3624 template< typename VT // Type of the dense vector
3625  , bool TF > // Transpose flag
3626 inline size_t Subvector<VT,aligned,TF,true>::size() const noexcept
3627 {
3628  return size_;
3629 }
3631 //*************************************************************************************************
3632 
3633 
3634 //*************************************************************************************************
3640 template< typename VT // Type of the dense vector
3641  , bool TF > // Transpose flag
3642 inline size_t Subvector<VT,aligned,TF,true>::capacity() const noexcept
3643 {
3644  return vector_.capacity() - offset_;
3645 }
3647 //*************************************************************************************************
3648 
3649 
3650 //*************************************************************************************************
3659 template< typename VT // Type of the dense vector
3660  , bool TF > // Transpose flag
3661 inline size_t Subvector<VT,aligned,TF,true>::nonZeros() const
3662 {
3663  size_t nonzeros( 0 );
3664 
3665  const size_t iend( offset_ + size_ );
3666  for( size_t i=offset_; i<iend; ++i ) {
3667  if( !isDefault( vector_[i] ) )
3668  ++nonzeros;
3669  }
3670 
3671  return nonzeros;
3672 }
3674 //*************************************************************************************************
3675 
3676 
3677 //*************************************************************************************************
3683 template< typename VT // Type of the dense vector
3684  , bool TF > // Transpose flag
3686 {
3687  using blaze::clear;
3688 
3689  const size_t iend( offset_ + size_ );
3690  for( size_t i=offset_; i<iend; ++i )
3691  clear( vector_[i] );
3692 }
3694 //*************************************************************************************************
3695 
3696 
3697 //*************************************************************************************************
3704 template< typename VT // Type of the dense vector
3705  , bool TF > // Transpose flag
3706 template< typename Other > // Data type of the scalar value
3707 inline Subvector<VT,aligned,TF,true>& Subvector<VT,aligned,TF,true>::scale( const Other& scalar )
3708 {
3709  const size_t iend( offset_ + size_ );
3710  for( size_t i=offset_; i<iend; ++i )
3711  vector_[i] *= scalar;
3712  return *this;
3713 }
3715 //*************************************************************************************************
3716 
3717 
3718 
3719 
3720 //=================================================================================================
3721 //
3722 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3723 //
3724 //=================================================================================================
3725 
3726 //*************************************************************************************************
3737 template< typename VT // Type of the dense vector
3738  , bool TF > // Transpose flag
3739 template< typename Other > // Data type of the foreign expression
3740 inline bool Subvector<VT,aligned,TF,true>::canAlias( const Other* alias ) const noexcept
3741 {
3742  return vector_.isAliased( alias );
3743 }
3745 //*************************************************************************************************
3746 
3747 
3748 //*************************************************************************************************
3759 template< typename VT // Type of the dense vector
3760  , bool TF > // Transpose flag
3761 template< typename VT2 // Data type of the foreign dense subvector
3762  , bool AF2 // Alignment flag of the foreign dense subvector
3763  , bool TF2 > // Transpose flag of the foreign dense subvector
3764 inline bool Subvector<VT,aligned,TF,true>::canAlias( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept
3765 {
3766  return ( vector_.isAliased( &alias->vector_ ) &&
3767  ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
3768 }
3770 //*************************************************************************************************
3771 
3772 
3773 //*************************************************************************************************
3784 template< typename VT // Type of the dense vector
3785  , bool TF > // Transpose flag
3786 template< typename Other > // Data type of the foreign expression
3787 inline bool Subvector<VT,aligned,TF,true>::isAliased( const Other* alias ) const noexcept
3788 {
3789  return vector_.isAliased( alias );
3790 }
3792 //*************************************************************************************************
3793 
3794 
3795 //*************************************************************************************************
3806 template< typename VT // Type of the dense vector
3807  , bool TF > // Transpose flag
3808 template< typename VT2 // Data type of the foreign dense subvector
3809  , bool AF2 // Alignment flag of the foreign dense subvector
3810  , bool TF2 > // Transpose flag of the foreign dense subvector
3811 inline bool Subvector<VT,aligned,TF,true>::isAliased( const Subvector<VT2,AF2,TF2,true>* alias ) const noexcept
3812 {
3813  return ( vector_.isAliased( &alias->vector_ ) &&
3814  ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
3815 }
3817 //*************************************************************************************************
3818 
3819 
3820 //*************************************************************************************************
3830 template< typename VT // Type of the dense vector
3831  , bool TF > // Transpose flag
3832 inline bool Subvector<VT,aligned,TF,true>::isAligned() const noexcept
3833 {
3834  return true;
3835 }
3837 //*************************************************************************************************
3838 
3839 
3840 //*************************************************************************************************
3851 template< typename VT // Type of the dense vector
3852  , bool TF > // Transpose flag
3853 inline bool Subvector<VT,aligned,TF,true>::canSMPAssign() const noexcept
3854 {
3855  return ( size() > SMP_DVECASSIGN_THRESHOLD );
3856 }
3858 //*************************************************************************************************
3859 
3860 
3861 //*************************************************************************************************
3875 template< typename VT // Type of the dense vector
3876  , bool TF > // Transpose flag
3877 BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true>::SIMDType
3878  Subvector<VT,aligned,TF,true>::load( size_t index ) const noexcept
3879 {
3880  return loada( index );
3881 }
3883 //*************************************************************************************************
3884 
3885 
3886 //*************************************************************************************************
3900 template< typename VT // Type of the dense vector
3901  , bool TF > // Transpose flag
3902 BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true>::SIMDType
3903  Subvector<VT,aligned,TF,true>::loada( size_t index ) const noexcept
3904 {
3906 
3907  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
3908  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
3909  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
3910 
3911  return vector_.loada( offset_+index );
3912 }
3914 //*************************************************************************************************
3915 
3916 
3917 //*************************************************************************************************
3931 template< typename VT // Type of the dense vector
3932  , bool TF > // Transpose flag
3933 BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true>::SIMDType
3934  Subvector<VT,aligned,TF,true>::loadu( size_t index ) const noexcept
3935 {
3937 
3938  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
3939  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
3940  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
3941 
3942  return vector_.loadu( offset_+index );
3943 }
3945 //*************************************************************************************************
3946 
3947 
3948 //*************************************************************************************************
3963 template< typename VT // Type of the dense vector
3964  , bool TF > // Transpose flag
3966  Subvector<VT,aligned,TF,true>::store( size_t index, const SIMDType& value ) noexcept
3967 {
3968  storea( index, value );
3969 }
3971 //*************************************************************************************************
3972 
3973 
3974 //*************************************************************************************************
3989 template< typename VT // Type of the dense vector
3990  , bool TF > // Transpose flag
3992  Subvector<VT,aligned,TF,true>::storea( size_t index, const SIMDType& value ) noexcept
3993 {
3995 
3996  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
3997  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
3998  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
3999 
4000  vector_.storea( offset_+index, value );
4001 }
4003 //*************************************************************************************************
4004 
4005 
4006 //*************************************************************************************************
4021 template< typename VT // Type of the dense vector
4022  , bool TF > // Transpose flag
4024  Subvector<VT,aligned,TF,true>::storeu( size_t index, const SIMDType& value ) noexcept
4025 {
4027 
4028  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4029  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4030  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4031 
4032  vector_.storeu( offset_+index, value );
4033 }
4035 //*************************************************************************************************
4036 
4037 
4038 //*************************************************************************************************
4053 template< typename VT // Type of the dense vector
4054  , bool TF > // Transpose flag
4056  Subvector<VT,aligned,TF,true>::stream( size_t index, const SIMDType& value ) noexcept
4057 {
4059 
4060  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4061  BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4062  BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4063 
4064  vector_.stream( offset_+index, value );
4065 }
4067 //*************************************************************************************************
4068 
4069 
4070 //*************************************************************************************************
4082 template< typename VT // Type of the dense vector
4083  , bool TF > // Transpose flag
4084 template< typename VT2 > // Type of the right-hand side dense vector
4085 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
4086  Subvector<VT,aligned,TF,true>::assign( const DenseVector<VT2,TF>& rhs )
4087 {
4088  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4089 
4090  const size_t ipos( size() & size_t(-2) );
4091  for( size_t i=0UL; i<ipos; i+=2UL ) {
4092  vector_[offset_+i ] = (~rhs)[i ];
4093  vector_[offset_+i+1UL] = (~rhs)[i+1UL];
4094  }
4095  if( ipos < size() ) {
4096  vector_[offset_+ipos] = (~rhs)[ipos];
4097  }
4098 }
4100 //*************************************************************************************************
4101 
4102 
4103 //*************************************************************************************************
4115 template< typename VT // Type of the dense vector
4116  , bool TF > // Transpose flag
4117 template< typename VT2 > // Type of the right-hand side dense vector
4118 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
4119  Subvector<VT,aligned,TF,true>::assign( const DenseVector<VT2,TF>& rhs )
4120 {
4122 
4123  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4124 
4125  const size_t ipos( size_ & size_t(-SIMDSIZE) );
4126  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4127 
4128  size_t i( 0UL );
4129  Iterator left( begin() );
4130  ConstIterator_<VT2> right( (~rhs).begin() );
4131 
4132  if( useStreaming && size_ > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( &vector_ ) )
4133  {
4134  for( ; i<ipos; i+=SIMDSIZE ) {
4135  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4136  }
4137  for( ; i<size_; ++i ) {
4138  *left = *right; ++left; ++right;
4139  }
4140  }
4141  else
4142  {
4143  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4144  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4145  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4146  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4147  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4148  }
4149  for( ; i<ipos; i+=SIMDSIZE ) {
4150  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4151  }
4152  for( ; i<size_; ++i ) {
4153  *left = *right; ++left; ++right;
4154  }
4155  }
4156 }
4158 //*************************************************************************************************
4159 
4160 
4161 //*************************************************************************************************
4173 template< typename VT // Type of the dense vector
4174  , bool TF > // Transpose flag
4175 template< typename VT2 > // Type of the right-hand side sparse vector
4176 inline void Subvector<VT,aligned,TF,true>::assign( const SparseVector<VT2,TF>& rhs )
4177 {
4178  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4179 
4180  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4181  vector_[offset_+element->index()] = element->value();
4182 }
4184 //*************************************************************************************************
4185 
4186 
4187 //*************************************************************************************************
4199 template< typename VT // Type of the dense vector
4200  , bool TF > // Transpose flag
4201 template< typename VT2 > // Type of the right-hand side dense vector
4202 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
4203  Subvector<VT,aligned,TF,true>::addAssign( const DenseVector<VT2,TF>& rhs )
4204 {
4205  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4206 
4207  const size_t ipos( size() & size_t(-2) );
4208  for( size_t i=0UL; i<ipos; i+=2UL ) {
4209  vector_[offset_+i ] += (~rhs)[i ];
4210  vector_[offset_+i+1UL] += (~rhs)[i+1UL];
4211  }
4212  if( ipos < size() ) {
4213  vector_[offset_+ipos] += (~rhs)[ipos];
4214  }
4215 }
4217 //*************************************************************************************************
4218 
4219 
4220 //*************************************************************************************************
4232 template< typename VT // Type of the dense vector
4233  , bool TF > // Transpose flag
4234 template< typename VT2 > // Type of the right-hand side dense vector
4235 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
4236  Subvector<VT,aligned,TF,true>::addAssign( const DenseVector<VT2,TF>& rhs )
4237 {
4239 
4240  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4241 
4242  const size_t ipos( size_ & size_t(-SIMDSIZE) );
4243  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4244 
4245  size_t i( 0UL );
4246  Iterator left( begin() );
4247  ConstIterator_<VT2> right( (~rhs).begin() );
4248 
4249  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4250  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4251  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4252  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4253  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4254  }
4255  for( ; i<ipos; i+=SIMDSIZE ) {
4256  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4257  }
4258  for( ; i<size_; ++i ) {
4259  *left += *right; ++left; ++right;
4260  }
4261 }
4263 //*************************************************************************************************
4264 
4265 
4266 //*************************************************************************************************
4278 template< typename VT // Type of the dense vector
4279  , bool TF > // Transpose flag
4280 template< typename VT2 > // Type of the right-hand side sparse vector
4281 inline void Subvector<VT,aligned,TF,true>::addAssign( const SparseVector<VT2,TF>& rhs )
4282 {
4283  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4284 
4285  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4286  vector_[offset_+element->index()] += element->value();
4287 }
4289 //*************************************************************************************************
4290 
4291 
4292 //*************************************************************************************************
4304 template< typename VT // Type of the dense vector
4305  , bool TF > // Transpose flag
4306 template< typename VT2 > // Type of the right-hand side dense vector
4307 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
4308  Subvector<VT,aligned,TF,true>::subAssign( const DenseVector<VT2,TF>& rhs )
4309 {
4310  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4311 
4312  const size_t ipos( size() & size_t(-2) );
4313  for( size_t i=0UL; i<ipos; i+=2UL ) {
4314  vector_[offset_+i ] -= (~rhs)[i ];
4315  vector_[offset_+i+1UL] -= (~rhs)[i+1UL];
4316  }
4317  if( ipos < size() ) {
4318  vector_[offset_+ipos] -= (~rhs)[ipos];
4319  }
4320 }
4322 //*************************************************************************************************
4323 
4324 
4325 //*************************************************************************************************
4337 template< typename VT // Type of the dense vector
4338  , bool TF > // Transpose flag
4339 template< typename VT2 > // Type of the right-hand side dense vector
4340 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
4341  Subvector<VT,aligned,TF,true>::subAssign( const DenseVector<VT2,TF>& rhs )
4342 {
4344 
4345  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4346 
4347  const size_t ipos( size_ & size_t(-SIMDSIZE) );
4348  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4349 
4350  size_t i( 0UL );
4351  Iterator left( begin() );
4352  ConstIterator_<VT2> right( (~rhs).begin() );
4353 
4354  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4355  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4356  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4357  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4358  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4359  }
4360  for( ; i<ipos; i+=SIMDSIZE ) {
4361  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4362  }
4363  for( ; i<size_; ++i ) {
4364  *left -= *right; ++left; ++right;
4365  }
4366 }
4368 //*************************************************************************************************
4369 
4370 
4371 //*************************************************************************************************
4383 template< typename VT // Type of the dense vector
4384  , bool TF > // Transpose flag
4385 template< typename VT2 > // Type of the right-hand side sparse vector
4386 inline void Subvector<VT,aligned,TF,true>::subAssign( const SparseVector<VT2,TF>& rhs )
4387 {
4388  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4389 
4390  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4391  vector_[offset_+element->index()] -= element->value();
4392 }
4394 //*************************************************************************************************
4395 
4396 
4397 //*************************************************************************************************
4409 template< typename VT // Type of the dense vector
4410  , bool TF > // Transpose flag
4411 template< typename VT2 > // Type of the right-hand side dense vector
4412 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
4413  Subvector<VT,aligned,TF,true>::multAssign( const DenseVector<VT2,TF>& rhs )
4414 {
4415  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4416 
4417  const size_t ipos( size() & size_t(-2) );
4418  for( size_t i=0UL; i<ipos; i+=2UL ) {
4419  vector_[offset_+i ] *= (~rhs)[i ];
4420  vector_[offset_+i+1UL] *= (~rhs)[i+1UL];
4421  }
4422  if( ipos < size() ) {
4423  vector_[offset_+ipos] *= (~rhs)[ipos];
4424  }
4425 }
4427 //*************************************************************************************************
4428 
4429 
4430 //*************************************************************************************************
4442 template< typename VT // Type of the dense vector
4443  , bool TF > // Transpose flag
4444 template< typename VT2 > // Type of the right-hand side dense vector
4445 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
4446  Subvector<VT,aligned,TF,true>::multAssign( const DenseVector<VT2,TF>& rhs )
4447 {
4449 
4450  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4451 
4452  const size_t ipos( size_ & size_t(-SIMDSIZE) );
4453  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4454 
4455  size_t i( 0UL );
4456  Iterator left( begin() );
4457  ConstIterator_<VT2> right( (~rhs).begin() );
4458 
4459  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4460  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4461  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4462  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4463  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4464  }
4465  for( ; i<ipos; i+=SIMDSIZE ) {
4466  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4467  }
4468  for( ; i<size_; ++i ) {
4469  *left *= *right; ++left; ++right;
4470  }
4471 }
4473 //*************************************************************************************************
4474 
4475 
4476 //*************************************************************************************************
4488 template< typename VT // Type of the dense vector
4489  , bool TF > // Transpose flag
4490 template< typename VT2 > // Type of the right-hand side sparse vector
4491 inline void Subvector<VT,aligned,TF,true>::multAssign( const SparseVector<VT2,TF>& rhs )
4492 {
4493  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4494 
4495  const ResultType tmp( serial( *this ) );
4496 
4497  reset();
4498 
4499  for( ConstIterator_<VT2> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4500  vector_[offset_+element->index()] = tmp[element->index()] * element->value();
4501 }
4503 //*************************************************************************************************
4504 
4505 
4506 //*************************************************************************************************
4518 template< typename VT // Type of the dense vector
4519  , bool TF > // Transpose flag
4520 template< typename VT2 > // Type of the right-hand side dense vector
4521 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
4522  Subvector<VT,aligned,TF,true>::divAssign( const DenseVector<VT2,TF>& rhs )
4523 {
4524  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4525 
4526  const size_t ipos( size() & size_t(-2) );
4527  for( size_t i=0UL; i<ipos; i+=2UL ) {
4528  vector_[offset_+i ] /= (~rhs)[i ];
4529  vector_[offset_+i+1UL] /= (~rhs)[i+1UL];
4530  }
4531  if( ipos < size() ) {
4532  vector_[offset_+ipos] /= (~rhs)[ipos];
4533  }
4534 }
4536 //*************************************************************************************************
4537 
4538 
4539 //*************************************************************************************************
4551 template< typename VT // Type of the dense vector
4552  , bool TF > // Transpose flag
4553 template< typename VT2 > // Type of the right-hand side dense vector
4554 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
4555  Subvector<VT,aligned,TF,true>::divAssign( const DenseVector<VT2,TF>& rhs )
4556 {
4558 
4559  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4560 
4561  const size_t ipos( size_ & size_t(-SIMDSIZE) );
4562  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
4563 
4564  size_t i( 0UL );
4565  Iterator left( begin() );
4566  ConstIterator_<VT2> right( (~rhs).begin() );
4567 
4568  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4569  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4570  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4571  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4572  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4573  }
4574  for( ; i<ipos; i+=SIMDSIZE ) {
4575  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4576  }
4577  for( ; i<size_; ++i ) {
4578  *left /= *right; ++left; ++right;
4579  }
4580 }
4582 //*************************************************************************************************
4583 
4584 
4585 
4586 
4587 
4588 
4589 
4590 
4591 //=================================================================================================
4592 //
4593 // CLASS TEMPLATE SPECIALIZATION FOR DVECDVECCROSSEXPR
4594 //
4595 //=================================================================================================
4596 
4597 //*************************************************************************************************
4605 template< typename VT1 // Type of the left-hand side dense vector
4606  , typename VT2 // Type of the right-hand side dense vector
4607  , bool TF > // Transpose flag
4608 class Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
4609  : public DenseVector< Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF >
4610  , private View
4611 {
4612  private:
4613  //**Type definitions****************************************************************************
4614  typedef DVecDVecCrossExpr<VT1,VT2,TF> CPE;
4615  typedef ResultType_<CPE> RT;
4616  //**********************************************************************************************
4617 
4618  public:
4619  //**Type definitions****************************************************************************
4620  typedef Subvector<CPE,unaligned,TF,true> This;
4621  typedef DenseVector<This,TF> BaseType;
4622  typedef SubvectorTrait_<RT> ResultType;
4623  typedef TransposeType_<ResultType> TransposeType;
4624  typedef ElementType_<CPE> ElementType;
4625  typedef ReturnType_<CPE> ReturnType;
4626  typedef const ResultType CompositeType;
4627  //**********************************************************************************************
4628 
4629  //**Compilation flags***************************************************************************
4631  enum : bool { simdEnabled = false };
4632 
4634  enum : bool { smpAssignable = false };
4635  //**********************************************************************************************
4636 
4637  //**Constructor*********************************************************************************
4644  explicit inline Subvector( const CPE& vector, size_t index, size_t n ) noexcept
4645  : vector_( vector ) // The dense vector/dense vector cross product expression
4646  , offset_( index ) // The offset of the subvector within the cross product expression
4647  , size_ ( n ) // The size of the subvector
4648  {}
4649  //**********************************************************************************************
4650 
4651  //**Subscript operator**************************************************************************
4657  inline ReturnType operator[]( size_t index ) const {
4658  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
4659  return vector_[offset_+index];
4660  }
4661  //**********************************************************************************************
4662 
4663  //**At function*********************************************************************************
4670  inline ReturnType at( size_t index ) const {
4671  if( index >= size() ) {
4672  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
4673  }
4674  return (*this)[index];
4675  }
4676  //**********************************************************************************************
4677 
4678  //**Size function*******************************************************************************
4683  inline size_t size() const noexcept {
4684  return size_;
4685  }
4686  //**********************************************************************************************
4687 
4688  //**********************************************************************************************
4694  template< typename T >
4695  inline bool canAlias( const T* alias ) const noexcept {
4696  return vector_.canAlias( alias );
4697  }
4698  //**********************************************************************************************
4699 
4700  //**********************************************************************************************
4706  template< typename T >
4707  inline bool isAliased( const T* alias ) const noexcept {
4708  return vector_.isAliased( alias );
4709  }
4710  //**********************************************************************************************
4711 
4712  private:
4713  //**Member variables****************************************************************************
4716  CPE vector_;
4717  const size_t offset_;
4718  const size_t size_;
4719 
4720  //**********************************************************************************************
4721 
4722  //**Friend declarations*************************************************************************
4723  template< bool AF1, typename VT, bool AF2, bool TF2, bool DF2 >
4724  friend const Subvector<VT,AF1,TF2,DF2>
4725  subvector( const Subvector<VT,AF2,TF2,DF2>& sv, size_t index, size_t size );
4726 
4727  template< typename VT3, bool AF, bool TF2, bool DF2 >
4728  friend bool isIntact( const Subvector<VT3,AF,TF2,DF2>& sv ) noexcept;
4729 
4730  template< typename VT3, bool AF, bool TF2, bool DF2 >
4731  friend bool isSame( const Subvector<VT3,AF,TF2,DF2>& a, const Vector<VT3,TF2>& b ) noexcept;
4732 
4733  template< typename VT3, bool AF, bool TF2, bool DF2 >
4734  friend bool isSame( const Vector<VT3,TF2>& a, const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
4735 
4736  template< typename VT3, bool AF, bool TF2, bool DF2 >
4737  friend bool isSame( const Subvector<VT3,AF,TF2,DF2>& a, const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
4738 
4739  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
4740  friend bool tryAssign( const Subvector<VT3,AF,TF2,DF2>& lhs, const Vector<VT4,TF2>& rhs, size_t index );
4741 
4742  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
4743  friend bool tryAddAssign( const Subvector<VT2,AF,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
4744 
4745  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
4746  friend bool trySubAssign( const Subvector<VT2,AF,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
4747 
4748  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
4749  friend bool tryMultAssign( const Subvector<VT3,AF,TF2,DF2>& lhs, const Vector<VT4,TF2>& rhs, size_t index );
4750  //**********************************************************************************************
4751 };
4753 //*************************************************************************************************
4754 
4755 
4756 
4757 
4758 
4759 
4760 
4761 
4762 //=================================================================================================
4763 //
4764 // CLASS TEMPLATE SPECIALIZATION FOR DVECSVECCROSSEXPR
4765 //
4766 //=================================================================================================
4767 
4768 //*************************************************************************************************
4776 template< typename VT1 // Type of the left-hand side dense vector
4777  , typename VT2 // Type of the right-hand side sparse vector
4778  , bool TF > // Transpose flag
4779 class Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
4780  : public DenseVector< Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF >
4781  , private View
4782 {
4783  private:
4784  //**Type definitions****************************************************************************
4785  typedef DVecSVecCrossExpr<VT1,VT2,TF> CPE;
4786  typedef ResultType_<CPE> RT;
4787  //**********************************************************************************************
4788 
4789  public:
4790  //**Type definitions****************************************************************************
4791  typedef Subvector<CPE,unaligned,TF,true> This;
4792  typedef DenseVector<This,TF> BaseType;
4793  typedef SubvectorTrait_<RT> ResultType;
4794  typedef TransposeType_<ResultType> TransposeType;
4795  typedef ElementType_<CPE> ElementType;
4796  typedef ReturnType_<CPE> ReturnType;
4797  typedef const ResultType CompositeType;
4798  //**********************************************************************************************
4799 
4800  //**Compilation flags***************************************************************************
4802  enum : bool { simdEnabled = false };
4803 
4805  enum : bool { smpAssignable = false };
4806  //**********************************************************************************************
4807 
4808  //**Constructor*********************************************************************************
4815  explicit inline Subvector( const CPE& vector, size_t index, size_t n ) noexcept
4816  : vector_( vector ) // The dense vector/sparse vector cross product expression
4817  , offset_( index ) // The offset of the subvector within the cross product expression
4818  , size_ ( n ) // The size of the subvector
4819  {}
4820  //**********************************************************************************************
4821 
4822  //**Subscript operator**************************************************************************
4828  inline ReturnType operator[]( size_t index ) const {
4829  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
4830  return vector_[offset_+index];
4831  }
4832  //**********************************************************************************************
4833 
4834  //**At function*********************************************************************************
4841  inline ReturnType at( size_t index ) const {
4842  if( index >= size() ) {
4843  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
4844  }
4845  return (*this)[index];
4846  }
4847  //**********************************************************************************************
4848 
4849  //**Size function*******************************************************************************
4854  inline size_t size() const noexcept {
4855  return size_;
4856  }
4857  //**********************************************************************************************
4858 
4859  //**********************************************************************************************
4865  template< typename T >
4866  inline bool canAlias( const T* alias ) const noexcept {
4867  return vector_.canAlias( alias );
4868  }
4869  //**********************************************************************************************
4870 
4871  //**********************************************************************************************
4877  template< typename T >
4878  inline bool isAliased( const T* alias ) const noexcept {
4879  return vector_.isAliased( alias );
4880  }
4881  //**********************************************************************************************
4882 
4883  private:
4884  //**Member variables****************************************************************************
4887  CPE vector_;
4888  const size_t offset_;
4889  const size_t size_;
4890 
4891  //**********************************************************************************************
4892 
4893  //**Friend declarations*************************************************************************
4894  template< bool AF1, typename VT, bool AF2, bool TF2, bool DF2 >
4895  friend const Subvector<VT,AF1,TF2,DF2>
4896  subvector( const Subvector<VT,AF2,TF2,DF2>& sv, size_t index, size_t size );
4897 
4898  template< typename VT3, bool AF, bool TF2, bool DF2 >
4899  friend bool isIntact( const Subvector<VT3,AF,TF2,DF2>& sv ) noexcept;
4900 
4901  template< typename VT3, bool AF, bool TF2, bool DF2 >
4902  friend bool isSame( const Subvector<VT3,AF,TF2,DF2>& a, const Vector<VT3,TF2>& b ) noexcept;
4903 
4904  template< typename VT3, bool AF, bool TF2, bool DF2 >
4905  friend bool isSame( const Vector<VT3,TF2>& a, const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
4906 
4907  template< typename VT3, bool AF, bool TF2, bool DF2 >
4908  friend bool isSame( const Subvector<VT3,AF,TF2,DF2>& a, const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
4909 
4910  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
4911  friend bool tryAssign( const Subvector<VT3,AF,TF2,DF2>& lhs, const Vector<VT4,TF2>& rhs, size_t index );
4912 
4913  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
4914  friend bool tryAddAssign( const Subvector<VT2,AF,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
4915 
4916  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
4917  friend bool trySubAssign( const Subvector<VT2,AF,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
4918 
4919  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
4920  friend bool tryMultAssign( const Subvector<VT3,AF,TF2,DF2>& lhs, const Vector<VT4,TF2>& rhs, size_t index );
4921  //**********************************************************************************************
4922 };
4924 //*************************************************************************************************
4925 
4926 
4927 
4928 
4929 
4930 
4931 
4932 
4933 //=================================================================================================
4934 //
4935 // CLASS TEMPLATE SPECIALIZATION FOR SVECDVECCROSSEXPR
4936 //
4937 //=================================================================================================
4938 
4939 //*************************************************************************************************
4947 template< typename VT1 // Type of the left-hand side sparse vector
4948  , typename VT2 // Type of the right-hand side dense vector
4949  , bool TF > // Transpose flag
4950 class Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
4951  : public DenseVector< Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF >
4952  , private View
4953 {
4954  private:
4955  //**Type definitions****************************************************************************
4956  typedef SVecDVecCrossExpr<VT1,VT2,TF> CPE;
4957  typedef ResultType_<CPE> RT;
4958  //**********************************************************************************************
4959 
4960  public:
4961  //**Type definitions****************************************************************************
4962  typedef Subvector<CPE,unaligned,TF,true> This;
4963  typedef DenseVector<This,TF> BaseType;
4964  typedef SubvectorTrait_<RT> ResultType;
4965  typedef TransposeType_<ResultType> TransposeType;
4966  typedef ElementType_<CPE> ElementType;
4967  typedef ReturnType_<CPE> ReturnType;
4968  typedef const ResultType CompositeType;
4969  //**********************************************************************************************
4970 
4971  //**Compilation flags***************************************************************************
4973  enum : bool { simdEnabled = false };
4974 
4976  enum : bool { smpAssignable = false };
4977  //**********************************************************************************************
4978 
4979  //**Constructor*********************************************************************************
4986  explicit inline Subvector( const CPE& vector, size_t index, size_t n ) noexcept
4987  : vector_( vector ) // The sparse vector/dense vector cross product expression
4988  , offset_( index ) // The offset of the subvector within the cross product expression
4989  , size_ ( n ) // The size of the subvector
4990  {}
4991  //**********************************************************************************************
4992 
4993  //**Subscript operator**************************************************************************
4999  inline ReturnType operator[]( size_t index ) const {
5000  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
5001  return vector_[offset_+index];
5002  }
5003  //**********************************************************************************************
5004 
5005  //**At function*********************************************************************************
5012  inline ReturnType at( size_t index ) const {
5013  if( index >= size() ) {
5014  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
5015  }
5016  return (*this)[index];
5017  }
5018  //**********************************************************************************************
5019 
5020  //**Size function*******************************************************************************
5025  inline size_t size() const noexcept {
5026  return size_;
5027  }
5028  //**********************************************************************************************
5029 
5030  //**********************************************************************************************
5036  template< typename T >
5037  inline bool canAlias( const T* alias ) const noexcept {
5038  return vector_.canAlias( alias );
5039  }
5040  //**********************************************************************************************
5041 
5042  //**********************************************************************************************
5048  template< typename T >
5049  inline bool isAliased( const T* alias ) const noexcept {
5050  return vector_.isAliased( alias );
5051  }
5052  //**********************************************************************************************
5053 
5054  private:
5055  //**Member variables****************************************************************************
5058  CPE vector_;
5059  const size_t offset_;
5060  const size_t size_;
5061 
5062  //**********************************************************************************************
5063 
5064  //**Friend declarations*************************************************************************
5065  template< bool AF1, typename VT, bool AF2, bool TF2, bool DF2 >
5066  friend const Subvector<VT,AF1,TF2,DF2>
5067  subvector( const Subvector<VT,AF2,TF2,DF2>& sv, size_t index, size_t size );
5068 
5069  template< typename VT3, bool AF, bool TF2, bool DF2 >
5070  friend bool isIntact( const Subvector<VT3,AF,TF2,DF2>& sv ) noexcept;
5071 
5072  template< typename VT3, bool AF, bool TF2, bool DF2 >
5073  friend bool isSame( const Subvector<VT3,AF,TF2,DF2>& a, const Vector<VT3,TF2>& b ) noexcept;
5074 
5075  template< typename VT3, bool AF, bool TF2, bool DF2 >
5076  friend bool isSame( const Vector<VT3,TF2>& a, const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
5077 
5078  template< typename VT3, bool AF, bool TF2, bool DF2 >
5079  friend bool isSame( const Subvector<VT3,AF,TF2,DF2>& a, const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
5080 
5081  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
5082  friend bool tryAssign( const Subvector<VT3,AF,TF2,DF2>& lhs, const Vector<VT4,TF2>& rhs, size_t index );
5083 
5084  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
5085  friend bool tryAddAssign( const Subvector<VT2,AF,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
5086 
5087  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
5088  friend bool trySubAssign( const Subvector<VT2,AF,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
5089 
5090  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
5091  friend bool tryMultAssign( const Subvector<VT3,AF,TF2,DF2>& lhs, const Vector<VT4,TF2>& rhs, size_t index );
5092  //**********************************************************************************************
5093 };
5095 //*************************************************************************************************
5096 
5097 
5098 
5099 
5100 
5101 
5102 
5103 
5104 //=================================================================================================
5105 //
5106 // CLASS TEMPLATE SPECIALIZATION FOR SVECSVECCROSSEXPR
5107 //
5108 //=================================================================================================
5109 
5110 //*************************************************************************************************
5118 template< typename VT1 // Type of the left-hand side sparse vector
5119  , typename VT2 // Type of the right-hand side sparse vector
5120  , bool TF > // Transpose flag
5121 class Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
5122  : public DenseVector< Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF >
5123  , private View
5124 {
5125  private:
5126  //**Type definitions****************************************************************************
5127  typedef SVecSVecCrossExpr<VT1,VT2,TF> CPE;
5128  typedef ResultType_<CPE> RT;
5129  //**********************************************************************************************
5130 
5131  public:
5132  //**Type definitions****************************************************************************
5133  typedef Subvector<CPE,unaligned,TF,true> This;
5134  typedef DenseVector<This,TF> BaseType;
5135  typedef SubvectorTrait_<RT> ResultType;
5136  typedef TransposeType_<ResultType> TransposeType;
5137  typedef ElementType_<CPE> ElementType;
5138  typedef ReturnType_<CPE> ReturnType;
5139  typedef const ResultType CompositeType;
5140  //**********************************************************************************************
5141 
5142  //**Compilation flags***************************************************************************
5144  enum : bool { simdEnabled = false };
5145 
5147  enum : bool { smpAssignable = false };
5148  //**********************************************************************************************
5149 
5150  //**Constructor*********************************************************************************
5157  explicit inline Subvector( const CPE& vector, size_t index, size_t n ) noexcept
5158  : vector_( vector ) // The sparse vector/sparse vector cross product expression
5159  , offset_( index ) // The offset of the subvector within the cross product expression
5160  , size_ ( n ) // The size of the subvector
5161  {}
5162  //**********************************************************************************************
5163 
5164  //**Subscript operator**************************************************************************
5170  inline ReturnType operator[]( size_t index ) const {
5171  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
5172  return vector_[offset_+index];
5173  }
5174  //**********************************************************************************************
5175 
5176  //**At function*********************************************************************************
5183  inline ReturnType at( size_t index ) const {
5184  if( index >= size() ) {
5185  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
5186  }
5187  return (*this)[index];
5188  }
5189  //**********************************************************************************************
5190 
5191  //**Size function*******************************************************************************
5196  inline size_t size() const noexcept {
5197  return size_;
5198  }
5199  //**********************************************************************************************
5200 
5201  //**********************************************************************************************
5207  template< typename T >
5208  inline bool canAlias( const T* alias ) const noexcept {
5209  return vector_.canAlias( alias );
5210  }
5211  //**********************************************************************************************
5212 
5213  //**********************************************************************************************
5219  template< typename T >
5220  inline bool isAliased( const T* alias ) const {
5221  return vector_.isAliased( alias );
5222  }
5223  //**********************************************************************************************
5224 
5225  private:
5226  //**Member variables****************************************************************************
5229  CPE vector_;
5230  const size_t offset_;
5231  const size_t size_;
5232 
5233  //**********************************************************************************************
5234 
5235  //**Friend declarations*************************************************************************
5236  template< bool AF1, typename VT, bool AF2, bool TF2, bool DF2 >
5237  friend const Subvector<VT,AF1,TF2,DF2>
5238  subvector( const Subvector<VT,AF2,TF2,DF2>& sv, size_t index, size_t size );
5239 
5240  template< typename VT3, bool AF, bool TF2, bool DF2 >
5241  friend bool isIntact( const Subvector<VT3,AF,TF2,DF2>& sv ) noexcept;
5242 
5243  template< typename VT3, bool AF, bool TF2, bool DF2 >
5244  friend bool isSame( const Subvector<VT3,AF,TF2,DF2>& a, const Vector<VT3,TF2>& b ) noexcept;
5245 
5246  template< typename VT3, bool AF, bool TF2, bool DF2 >
5247  friend bool isSame( const Vector<VT3,TF2>& a, const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
5248 
5249  template< typename VT3, bool AF, bool TF2, bool DF2 >
5250  friend bool isSame( const Subvector<VT3,AF,TF2,DF2>& a, const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
5251 
5252  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
5253  friend bool tryAssign( const Subvector<VT3,AF,TF2,DF2>& lhs, const Vector<VT4,TF2>& rhs, size_t index );
5254 
5255  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
5256  friend bool tryAddAssign( const Subvector<VT2,AF,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
5257 
5258  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
5259  friend bool trySubAssign( const Subvector<VT2,AF,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs, size_t index );
5260 
5261  template< typename VT3, bool AF, bool TF2, bool DF2, typename VT4 >
5262  friend bool tryMultAssign( const Subvector<VT3,AF,TF2,DF2>& lhs, const Vector<VT4,TF2>& rhs, size_t index );
5263  //**********************************************************************************************
5264 };
5266 //*************************************************************************************************
5267 
5268 } // namespace blaze
5269 
5270 #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.
const DMatDMatMultExpr< T1, T2 > 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:7800
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:346
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:653
Header file for basic type definitions.
Header file for the View base class.
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:404
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:258
#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
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:188
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:2643
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
bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:366
Header file for the DenseVector base class.
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2636
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:442
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:723
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:384
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:298
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:232
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
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:2647
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.
Header file for the implementation of the Subvector base template.
Header file for the Not class template.
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:2640
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:254
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2641
const bool unaligned
Alignment flag for unaligned vectors and matrices.Via this flag it is possible to specify subvectors...
Definition: AlignmentFlag.h:64
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:2645
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 IsSparseVector type trait.
Header file for the HasSIMDMult type trait.
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2642
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:2646
Header file for the isDefault shim.
Header file for the HasSIMDSub type trait.
#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:2637
#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 AreSIMDCombinable type trait.
bool operator<(const NegativeAccuracy< A > &lhs, const T &rhs)
Less-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:328
Header file for the HasSIMDDiv type trait.
Header file for the alignment check function.
bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:249
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2638
bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:289
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:240
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2644
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.
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.