Blaze 3.9
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>
64#include <blaze/math/SIMD.h>
82#include <blaze/system/Inline.h>
87#include <blaze/util/Assert.h>
89#include <blaze/util/EnableIf.h>
90#include <blaze/util/mpl/If.h>
91#include <blaze/util/Types.h>
93
94
95namespace blaze {
96
97//=================================================================================================
98//
99// CLASS TEMPLATE SPECIALIZATION FOR UNALIGNED DENSE SUBVECTORS
100//
101//=================================================================================================
102
103//*************************************************************************************************
111template< typename VT // Type of the dense vector
112 , bool TF // Transpose flag
113 , size_t... CSAs > // Compile time subvector arguments
114class Subvector<VT,unaligned,TF,true,CSAs...>
115 : public View< DenseVector< Subvector<VT,unaligned,TF,true,CSAs...>, TF > >
116 , private SubvectorData<CSAs...>
117{
118 private:
119 //**Type definitions****************************************************************************
120 using DataType = SubvectorData<CSAs...>;
121 using Operand = If_t< IsExpression_v<VT>, VT, VT& >;
122 //**********************************************************************************************
123
124 public:
125 //**Type definitions****************************************************************************
127 using This = Subvector<VT,unaligned,TF,true,CSAs...>;
128
129 using BaseType = View< DenseVector<This,TF> >;
130 using ViewedType = VT;
131 using ResultType = SubvectorTrait_t<VT,CSAs...>;
132 using TransposeType = TransposeType_t<ResultType>;
133 using ElementType = ElementType_t<VT>;
134 using SIMDType = SIMDTrait_t<ElementType>;
135 using ReturnType = ReturnType_t<VT>;
136 using CompositeType = const Subvector&;
137
139 using ConstReference = ConstReference_t<VT>;
140
142 using Reference = If_t< IsConst_v<VT>, ConstReference, Reference_t<VT> >;
143
145 using ConstPointer = ConstPointer_t<VT>;
146
148 using Pointer = If_t< IsConst_v<VT> || !HasMutableDataAccess_v<VT>, ConstPointer, Pointer_t<VT> >;
149 //**********************************************************************************************
150
151 //**SubvectorIterator class definition**********************************************************
154 template< typename IteratorType > // Type of the dense vector iterator
155 class SubvectorIterator
156 {
157 public:
158 //**Type definitions*************************************************************************
160 using IteratorCategory = typename std::iterator_traits<IteratorType>::iterator_category;
161
163 using ValueType = typename std::iterator_traits<IteratorType>::value_type;
164
166 using PointerType = typename std::iterator_traits<IteratorType>::pointer;
167
169 using ReferenceType = typename std::iterator_traits<IteratorType>::reference;
170
172 using DifferenceType = typename std::iterator_traits<IteratorType>::difference_type;
173
174 // STL iterator requirements
175 using iterator_category = IteratorCategory;
176 using value_type = ValueType;
177 using pointer = PointerType;
178 using reference = ReferenceType;
179 using difference_type = DifferenceType;
180 //*******************************************************************************************
181
182 //**Constructor******************************************************************************
185 inline BLAZE_DEVICE_CALLABLE SubvectorIterator()
186 : iterator_ ( ) // Iterator to the current subvector element
187 , isAligned_( false ) // Memory alignment flag
188 {}
189 //*******************************************************************************************
190
191 //**Constructor******************************************************************************
197 inline BLAZE_DEVICE_CALLABLE SubvectorIterator( IteratorType iterator, bool isMemoryAligned )
198 : iterator_ ( iterator ) // Iterator to the current subvector element
199 , isAligned_( isMemoryAligned ) // Memory alignment flag
200 {}
201 //*******************************************************************************************
202
203 //**Constructor******************************************************************************
208 template< typename IteratorType2 >
209 inline BLAZE_DEVICE_CALLABLE SubvectorIterator( const SubvectorIterator<IteratorType2>& it )
210 : iterator_ ( it.base() ) // Iterator to the current subvector element
211 , isAligned_( it.isAligned() ) // Memory alignment flag
212 {}
213 //*******************************************************************************************
214
215 //**Addition assignment operator*************************************************************
221 inline BLAZE_DEVICE_CALLABLE SubvectorIterator& operator+=( size_t inc ) {
222 iterator_ += inc;
223 return *this;
224 }
225 //*******************************************************************************************
226
227 //**Subtraction assignment operator**********************************************************
233 inline BLAZE_DEVICE_CALLABLE SubvectorIterator& operator-=( size_t dec ) {
234 iterator_ -= dec;
235 return *this;
236 }
237 //*******************************************************************************************
238
239 //**Prefix increment operator****************************************************************
244 inline BLAZE_DEVICE_CALLABLE SubvectorIterator& operator++() {
245 ++iterator_;
246 return *this;
247 }
248 //*******************************************************************************************
249
250 //**Postfix increment operator***************************************************************
255 inline BLAZE_DEVICE_CALLABLE const SubvectorIterator operator++( int ) {
256 return SubvectorIterator( iterator_++, isAligned_ );
257 }
258 //*******************************************************************************************
259
260 //**Prefix decrement operator****************************************************************
265 inline BLAZE_DEVICE_CALLABLE SubvectorIterator& operator--() {
266 --iterator_;
267 return *this;
268 }
269 //*******************************************************************************************
270
271 //**Postfix decrement operator***************************************************************
276 inline BLAZE_DEVICE_CALLABLE const SubvectorIterator operator--( int ) {
277 return SubvectorIterator( iterator_--, isAligned_ );
278 }
279 //*******************************************************************************************
280
281 //**Element access operator******************************************************************
286 inline BLAZE_DEVICE_CALLABLE ReferenceType operator*() const {
287 return *iterator_;
288 }
289 //*******************************************************************************************
290
291 //**Element access operator******************************************************************
296 inline BLAZE_DEVICE_CALLABLE IteratorType operator->() const {
297 return iterator_;
298 }
299 //*******************************************************************************************
300
301 //**Load function****************************************************************************
311 inline SIMDType load() const {
312 if( isAligned_ ) {
313 return loada();
314 }
315 else {
316 return loadu();
317 }
318 }
319 //*******************************************************************************************
320
321 //**Loada function***************************************************************************
331 inline SIMDType loada() const {
332 return iterator_.loada();
333 }
334 //*******************************************************************************************
335
336 //**Loadu function***************************************************************************
346 inline SIMDType loadu() const {
347 return iterator_.loadu();
348 }
349 //*******************************************************************************************
350
351 //**Store function***************************************************************************
362 inline void store( const SIMDType& value ) const {
363 if( isAligned_ ) {
364 storea( value );
365 }
366 else {
367 storeu( value );
368 }
369 }
370 //*******************************************************************************************
371
372 //**Storea function**************************************************************************
383 inline void storea( const SIMDType& value ) const {
384 iterator_.storea( value );
385 }
386 //*******************************************************************************************
387
388 //**Storeu function**************************************************************************
399 inline void storeu( const SIMDType& value ) const {
400 iterator_.storeu( value );
401 }
402 //*******************************************************************************************
403
404 //**Stream function**************************************************************************
415 inline void stream( const SIMDType& value ) const {
416 iterator_.stream( value );
417 }
418 //*******************************************************************************************
419
420 //**Equality operator************************************************************************
426 inline BLAZE_DEVICE_CALLABLE bool operator==( const SubvectorIterator& rhs ) const {
427 return iterator_ == rhs.iterator_;
428 }
429 //*******************************************************************************************
430
431 //**Inequality operator**********************************************************************
437 inline BLAZE_DEVICE_CALLABLE bool operator!=( const SubvectorIterator& rhs ) const {
438 return iterator_ != rhs.iterator_;
439 }
440 //*******************************************************************************************
441
442 //**Less-than operator***********************************************************************
448 inline BLAZE_DEVICE_CALLABLE bool operator<( const SubvectorIterator& rhs ) const {
449 return iterator_ < rhs.iterator_;
450 }
451 //*******************************************************************************************
452
453 //**Greater-than operator********************************************************************
459 inline BLAZE_DEVICE_CALLABLE bool operator>( const SubvectorIterator& rhs ) const {
460 return iterator_ > rhs.iterator_;
461 }
462 //*******************************************************************************************
463
464 //**Less-or-equal-than operator**************************************************************
470 inline BLAZE_DEVICE_CALLABLE bool operator<=( const SubvectorIterator& rhs ) const {
471 return iterator_ <= rhs.iterator_;
472 }
473 //*******************************************************************************************
474
475 //**Greater-or-equal-than operator***********************************************************
481 inline BLAZE_DEVICE_CALLABLE bool operator>=( const SubvectorIterator& rhs ) const {
482 return iterator_ >= rhs.iterator_;
483 }
484 //*******************************************************************************************
485
486 //**Subtraction operator*********************************************************************
492 inline BLAZE_DEVICE_CALLABLE DifferenceType operator-( const SubvectorIterator& rhs ) const {
493 return iterator_ - rhs.iterator_;
494 }
495 //*******************************************************************************************
496
497 //**Addition operator************************************************************************
504 friend inline BLAZE_DEVICE_CALLABLE const SubvectorIterator operator+( const SubvectorIterator& it, size_t inc ) {
505 return SubvectorIterator( it.iterator_ + inc, it.isAligned_ );
506 }
507 //*******************************************************************************************
508
509 //**Addition operator************************************************************************
516 friend inline BLAZE_DEVICE_CALLABLE const SubvectorIterator operator+( size_t inc, const SubvectorIterator& it ) {
517 return SubvectorIterator( it.iterator_ + inc, it.isAligned_ );
518 }
519 //*******************************************************************************************
520
521 //**Subtraction operator*********************************************************************
528 friend inline BLAZE_DEVICE_CALLABLE const SubvectorIterator operator-( const SubvectorIterator& it, size_t dec ) {
529 return SubvectorIterator( it.iterator_ - dec, it.isAligned_ );
530 }
531 //*******************************************************************************************
532
533 //**Base function****************************************************************************
538 inline BLAZE_DEVICE_CALLABLE IteratorType base() const {
539 return iterator_;
540 }
541 //*******************************************************************************************
542
543 //**IsAligned function***********************************************************************
548 inline bool isAligned() const {
549 return isAligned_;
550 }
551 //*******************************************************************************************
552
553 private:
554 //**Member variables*************************************************************************
555 IteratorType iterator_;
556 bool isAligned_;
557 //*******************************************************************************************
558 };
559 //**********************************************************************************************
560
561 //**Type definitions****************************************************************************
563 using ConstIterator = SubvectorIterator< ConstIterator_t<VT> >;
564
566 using Iterator = If_t< IsConst_v<VT>, ConstIterator, SubvectorIterator< Iterator_t<VT> > >;
567 //**********************************************************************************************
568
569 //**Compilation flags***************************************************************************
571 static constexpr bool simdEnabled = VT::simdEnabled;
572
574 static constexpr bool smpAssignable = VT::smpAssignable;
575
577 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
578 //**********************************************************************************************
579
580 //**Constructors********************************************************************************
583 template< typename... RSAs >
584 explicit inline Subvector( VT& vector, RSAs... args );
585
586 Subvector( const Subvector& ) = default;
588 //**********************************************************************************************
589
590 //**Destructor**********************************************************************************
593 ~Subvector() = default;
595 //**********************************************************************************************
596
597 //**Data access functions***********************************************************************
600 inline Reference operator[]( size_t index );
601 inline ConstReference operator[]( size_t index ) const;
602 inline Reference at( size_t index );
603 inline ConstReference at( size_t index ) const;
604 inline Pointer data () noexcept;
605 inline ConstPointer data () const noexcept;
606 inline Iterator begin ();
607 inline ConstIterator begin () const;
608 inline ConstIterator cbegin() const;
609 inline Iterator end ();
610 inline ConstIterator end () const;
611 inline ConstIterator cend () const;
613 //**********************************************************************************************
614
615 //**Assignment operators************************************************************************
618 inline Subvector& operator= ( const ElementType& rhs );
619 inline Subvector& operator= ( initializer_list<ElementType> list );
620 inline Subvector& operator= ( const Subvector& rhs );
621 template< typename VT2 > inline Subvector& operator= ( const Vector<VT2,TF>& rhs );
622 template< typename VT2 > inline Subvector& operator+=( const Vector<VT2,TF>& rhs );
623 template< typename VT2 > inline Subvector& operator-=( const Vector<VT2,TF>& rhs );
624 template< typename VT2 > inline Subvector& operator*=( const Vector<VT2,TF>& rhs );
625 template< typename VT2 > inline Subvector& operator/=( const DenseVector<VT2,TF>& rhs );
626 template< typename VT2 > inline Subvector& operator%=( const Vector<VT2,TF>& rhs );
628 //**********************************************************************************************
629
630 //**Utility functions***************************************************************************
633 using DataType::offset;
634 using DataType::size;
635
636 inline VT& operand() noexcept;
637 inline const VT& operand() const noexcept;
638
639 inline size_t spacing() const noexcept;
640 inline size_t capacity() const noexcept;
641 inline size_t nonZeros() const;
642 inline void reset();
644 //**********************************************************************************************
645
646 //**Numeric functions***************************************************************************
649 template< typename Other > inline Subvector& scale( const Other& scalar );
651 //**********************************************************************************************
652
653 private:
654 //**********************************************************************************************
656 template< typename VT2 >
657 static constexpr bool VectorizedAssign_v =
658 ( useOptimizedKernels &&
659 simdEnabled && VT2::simdEnabled &&
660 IsSIMDCombinable_v< ElementType, ElementType_t<VT2> > );
661 //**********************************************************************************************
662
663 //**********************************************************************************************
665 template< typename VT2 >
666 static constexpr bool VectorizedAddAssign_v =
667 ( VectorizedAssign_v<VT2> &&
668 HasSIMDAdd_v< ElementType, ElementType_t<VT2> > );
669 //**********************************************************************************************
670
671 //**********************************************************************************************
673 template< typename VT2 >
674 static constexpr bool VectorizedSubAssign_v =
675 ( VectorizedAssign_v<VT2> &&
676 HasSIMDSub_v< ElementType, ElementType_t<VT2> > );
677 //**********************************************************************************************
678
679 //**********************************************************************************************
681 template< typename VT2 >
682 static constexpr bool VectorizedMultAssign_v =
683 ( VectorizedAssign_v<VT2> &&
684 HasSIMDMult_v< ElementType, ElementType_t<VT2> > );
685 //**********************************************************************************************
686
687 //**********************************************************************************************
689 template< typename VT2 >
690 static constexpr bool VectorizedDivAssign_v =
691 ( VectorizedAssign_v<VT2> &&
692 HasSIMDDiv_v< ElementType, ElementType_t<VT2> > );
693 //**********************************************************************************************
694
695 //**SIMD properties*****************************************************************************
697 static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
698 //**********************************************************************************************
699
700 public:
701 //**Expression template evaluation functions****************************************************
704 template< typename Other >
705 inline bool canAlias( const Other* alias ) const noexcept;
706
707 template< typename VT2, AlignmentFlag AF2, bool TF2, size_t... CSAs2 >
708 inline bool canAlias( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept;
709
710 template< typename Other >
711 inline bool isAliased( const Other* alias ) const noexcept;
712
713 template< typename VT2, AlignmentFlag AF2, bool TF2, size_t... CSAs2 >
714 inline bool isAliased( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept;
715
716 inline bool isAligned () const noexcept;
717 inline bool canSMPAssign() const noexcept;
718
719 BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
720 BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
721 BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
722
723 BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
724 BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
725 BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
726 BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
727
728 template< typename VT2 >
729 inline auto assign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedAssign_v<VT2> >;
730
731 template< typename VT2 >
732 inline auto assign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedAssign_v<VT2> >;
733
734 template< typename VT2 > inline void assign( const SparseVector<VT2,TF>& rhs );
735
736 template< typename VT2 >
737 inline auto addAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<VT2> >;
738
739 template< typename VT2 >
740 inline auto addAssign ( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<VT2> >;
741
742 template< typename VT2 > inline void addAssign( const SparseVector<VT2,TF>& rhs );
743
744 template< typename VT2 >
745 inline auto subAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<VT2> >;
746
747 template< typename VT2 >
748 inline auto subAssign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<VT2> >;
749
750 template< typename VT2 > inline void subAssign( const SparseVector<VT2,TF>& rhs );
751
752 template< typename VT2 >
753 inline auto multAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedMultAssign_v<VT2> >;
754
755 template< typename VT2 >
756 inline auto multAssign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedMultAssign_v<VT2> >;
757
758 template< typename VT2 > inline void multAssign( const SparseVector<VT2,TF>& rhs );
759
760 template< typename VT2 >
761 inline auto divAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedDivAssign_v<VT2> >;
762
763 template< typename VT2 >
764 inline auto divAssign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedDivAssign_v<VT2> >;
766 //**********************************************************************************************
767
768 private:
769 //**Member variables****************************************************************************
772 Operand vector_;
773 const bool isAligned_;
781 //**********************************************************************************************
782
783 //**Friend declarations*************************************************************************
784 template< typename VT2, AlignmentFlag AF2, bool TF2, bool DF2, size_t... CSAs2 > friend class Subvector;
785 //**********************************************************************************************
786
787 //**Compile time checks*************************************************************************
793 //**********************************************************************************************
794};
796//*************************************************************************************************
797
798
799
800
801//=================================================================================================
802//
803// CONSTRUCTORS
804//
805//=================================================================================================
806
807//*************************************************************************************************
821template< typename VT // Type of the dense vector
822 , bool TF // Transpose flag
823 , size_t... CSAs > // Compile time subvector arguments
824template< typename... RSAs > // Runtime subvector arguments
825inline Subvector<VT,unaligned,TF,true,CSAs...>::Subvector( VT& vector, RSAs... args )
826 : DataType ( args... ) // Base class initialization
827 , vector_ ( vector ) // The vector containing the subvector
828 , isAligned_( simdEnabled && IsContiguous_v<VT> &&
829 vector.data() != nullptr && checkAlignment( data() ) )
830{
831 if( isChecked( args... ) ) {
832 if( offset() + size() > vector.size() ) {
833 BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
834 }
835 }
836 else {
837 BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
838 }
839}
841//*************************************************************************************************
842
843
844
845
846//=================================================================================================
847//
848// DATA ACCESS FUNCTIONS
849//
850//=================================================================================================
851
852//*************************************************************************************************
862template< typename VT // Type of the dense vector
863 , bool TF // Transpose flag
864 , size_t... CSAs > // Compile time subvector arguments
865inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Reference
866 Subvector<VT,unaligned,TF,true,CSAs...>::operator[]( size_t index )
867{
868 BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
869 return vector_[offset()+index];
870}
872//*************************************************************************************************
873
874
875//*************************************************************************************************
885template< typename VT // Type of the dense vector
886 , bool TF // Transpose flag
887 , size_t... CSAs > // Compile time subvector arguments
888inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstReference
889 Subvector<VT,unaligned,TF,true,CSAs...>::operator[]( size_t index ) const
890{
891 BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
892 return const_cast<const VT&>( vector_ )[offset()+index];
893}
895//*************************************************************************************************
896
897
898//*************************************************************************************************
909template< typename VT // Type of the dense vector
910 , bool TF // Transpose flag
911 , size_t... CSAs > // Compile time subvector arguments
912inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Reference
913 Subvector<VT,unaligned,TF,true,CSAs...>::at( size_t index )
914{
915 if( index >= size() ) {
916 BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
917 }
918 return (*this)[index];
919}
921//*************************************************************************************************
922
923
924//*************************************************************************************************
935template< typename VT // Type of the dense vector
936 , bool TF // Transpose flag
937 , size_t... CSAs > // Compile time subvector arguments
938inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstReference
939 Subvector<VT,unaligned,TF,true,CSAs...>::at( size_t index ) const
940{
941 if( index >= size() ) {
942 BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
943 }
944 return (*this)[index];
945}
947//*************************************************************************************************
948
949
950//*************************************************************************************************
958template< typename VT // Type of the dense vector
959 , bool TF // Transpose flag
960 , size_t... CSAs > // Compile time subvector arguments
961inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Pointer
963{
964 return vector_.data() + offset();
965}
967//*************************************************************************************************
968
969
970//*************************************************************************************************
978template< typename VT // Type of the dense vector
979 , bool TF // Transpose flag
980 , size_t... CSAs > // Compile time subvector arguments
981inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstPointer
983{
984 return vector_.data() + offset();
985}
987//*************************************************************************************************
988
989
990//*************************************************************************************************
998template< typename VT // Type of the dense vector
999 , bool TF // Transpose flag
1000 , size_t... CSAs > // Compile time subvector arguments
1001inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Iterator
1003{
1004 return Iterator( vector_.begin() + offset(), isAligned_ );
1005}
1007//*************************************************************************************************
1008
1009
1010//*************************************************************************************************
1018template< typename VT // Type of the dense vector
1019 , bool TF // Transpose flag
1020 , size_t... CSAs > // Compile time subvector arguments
1021inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstIterator
1023{
1024 return ConstIterator( vector_.cbegin() + offset(), isAligned_ );
1025}
1027//*************************************************************************************************
1028
1029
1030//*************************************************************************************************
1038template< typename VT // Type of the dense vector
1039 , bool TF // Transpose flag
1040 , size_t... CSAs > // Compile time subvector arguments
1041inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstIterator
1043{
1044 return ConstIterator( vector_.cbegin() + offset(), isAligned_ );
1045}
1047//*************************************************************************************************
1048
1049
1050//*************************************************************************************************
1058template< typename VT // Type of the dense vector
1059 , bool TF // Transpose flag
1060 , size_t... CSAs > // Compile time subvector arguments
1061inline typename Subvector<VT,unaligned,TF,true,CSAs...>::Iterator
1063{
1064 return Iterator( vector_.begin() + offset() + size(), isAligned_ );
1065}
1067//*************************************************************************************************
1068
1069
1070//*************************************************************************************************
1078template< typename VT // Type of the dense vector
1079 , bool TF // Transpose flag
1080 , size_t... CSAs > // Compile time subvector arguments
1081inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstIterator
1083{
1084 return ConstIterator( vector_.cbegin() + offset() + size(), isAligned_ );
1085}
1087//*************************************************************************************************
1088
1089
1090//*************************************************************************************************
1098template< typename VT // Type of the dense vector
1099 , bool TF // Transpose flag
1100 , size_t... CSAs > // Compile time subvector arguments
1101inline typename Subvector<VT,unaligned,TF,true,CSAs...>::ConstIterator
1103{
1104 return ConstIterator( vector_.cbegin() + offset() + size(), isAligned_ );
1105}
1107//*************************************************************************************************
1108
1109
1110
1111
1112//=================================================================================================
1113//
1114// ASSIGNMENT OPERATORS
1115//
1116//=================================================================================================
1117
1118//*************************************************************************************************
1125template< typename VT // Type of the dense vector
1126 , bool TF // Transpose flag
1127 , size_t... CSAs > // Compile time subvector arguments
1128inline Subvector<VT,unaligned,TF,true,CSAs...>&
1129 Subvector<VT,unaligned,TF,true,CSAs...>::operator=( const ElementType& rhs )
1130{
1131 const size_t iend( offset() + size() );
1132 decltype(auto) left( derestrict( vector_ ) );
1133
1134 for( size_t i=offset(); i<iend; ++i ) {
1135 if( !IsRestricted_v<VT> || trySet( vector_, i, rhs ) )
1136 left[i] = rhs;
1137 }
1138
1139 return *this;
1140}
1142//*************************************************************************************************
1143
1144
1145//*************************************************************************************************
1161template< typename VT // Type of the dense vector
1162 , bool TF // Transpose flag
1163 , size_t... CSAs > // Compile time subvector arguments
1164inline Subvector<VT,unaligned,TF,true,CSAs...>&
1165 Subvector<VT,unaligned,TF,true,CSAs...>::operator=( initializer_list<ElementType> list )
1166{
1167 if( list.size() > size() ) {
1168 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to subvector" );
1169 }
1170
1171 if( IsRestricted_v<VT> ) {
1172 const InitializerVector<ElementType,TF> tmp( list, size() );
1173 if( !tryAssign( vector_, tmp, offset() ) ) {
1174 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1175 }
1176 }
1177
1178 decltype(auto) left( derestrict( *this ) );
1179
1180 std::fill( std::copy( list.begin(), list.end(), left.begin() ), left.end(), ElementType() );
1181
1182 BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1183
1184 return *this;
1185}
1187//*************************************************************************************************
1188
1189
1190//*************************************************************************************************
1202template< typename VT // Type of the dense vector
1203 , bool TF // Transpose flag
1204 , size_t... CSAs > // Compile time subvector arguments
1205inline Subvector<VT,unaligned,TF,true,CSAs...>&
1206 Subvector<VT,unaligned,TF,true,CSAs...>::operator=( const Subvector& rhs )
1207{
1210
1211 if( &rhs == this || ( &vector_ == &rhs.vector_ && offset() == rhs.offset() ) )
1212 return *this;
1213
1214 if( size() != rhs.size() ) {
1215 BLAZE_THROW_INVALID_ARGUMENT( "Subvector sizes do not match" );
1216 }
1217
1218 if( !tryAssign( vector_, rhs, offset() ) ) {
1219 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1220 }
1221
1222 decltype(auto) left( derestrict( *this ) );
1223
1224 if( rhs.canAlias( this ) ) {
1225 const ResultType tmp( rhs );
1226 smpAssign( left, tmp );
1227 }
1228 else {
1229 smpAssign( left, rhs );
1230 }
1231
1232 BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1233
1234 return *this;
1235}
1237//*************************************************************************************************
1238
1239
1240//*************************************************************************************************
1252template< typename VT // Type of the dense vector
1253 , bool TF // Transpose flag
1254 , size_t... CSAs > // Compile time subvector arguments
1255template< typename VT2 > // Type of the right-hand side vector
1256inline Subvector<VT,unaligned,TF,true,CSAs...>&
1257 Subvector<VT,unaligned,TF,true,CSAs...>::operator=( const Vector<VT2,TF>& rhs )
1258{
1261
1262 if( size() != (*rhs).size() ) {
1263 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1264 }
1265
1266 using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
1267 Right right( *rhs );
1268
1269 if( !tryAssign( vector_, right, offset() ) ) {
1270 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1271 }
1272
1273 decltype(auto) left( derestrict( *this ) );
1274
1275 if( IsReference_v<Right> && right.canAlias( this ) ) {
1276 const ResultType_t<VT2> tmp( right );
1277 smpAssign( left, tmp );
1278 }
1279 else {
1280 if( IsSparseVector_v<VT2> )
1281 reset();
1282 smpAssign( left, right );
1283 }
1284
1285 BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1286
1287 return *this;
1288}
1290//*************************************************************************************************
1291
1292
1293//*************************************************************************************************
1305template< typename VT // Type of the dense vector
1306 , bool TF // Transpose flag
1307 , size_t... CSAs > // Compile time subvector arguments
1308template< typename VT2 > // Type of the right-hand side vector
1309inline Subvector<VT,unaligned,TF,true,CSAs...>&
1310 Subvector<VT,unaligned,TF,true,CSAs...>::operator+=( const Vector<VT2,TF>& rhs )
1311{
1314
1315 if( size() != (*rhs).size() ) {
1316 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1317 }
1318
1319 using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
1320 Right right( *rhs );
1321
1322 if( !tryAddAssign( vector_, right, offset() ) ) {
1323 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1324 }
1325
1326 decltype(auto) left( derestrict( *this ) );
1327
1328 if( IsReference_v<Right> && right.canAlias( this ) ) {
1329 const ResultType_t<VT2> tmp( right );
1330 smpAddAssign( left, tmp );
1331 }
1332 else {
1333 smpAddAssign( left, right );
1334 }
1335
1336 BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1337
1338 return *this;
1339}
1341//*************************************************************************************************
1342
1343
1344//*************************************************************************************************
1356template< typename VT // Type of the dense vector
1357 , bool TF // Transpose flag
1358 , size_t... CSAs > // Compile time subvector arguments
1359template< typename VT2 > // Type of the right-hand side vector
1360inline Subvector<VT,unaligned,TF,true,CSAs...>&
1361 Subvector<VT,unaligned,TF,true,CSAs...>::operator-=( const Vector<VT2,TF>& rhs )
1362{
1365
1366 if( size() != (*rhs).size() ) {
1367 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1368 }
1369
1370 using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
1371 Right right( *rhs );
1372
1373 if( !trySubAssign( vector_, right, offset() ) ) {
1374 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1375 }
1376
1377 decltype(auto) left( derestrict( *this ) );
1378
1379 if( IsReference_v<Right> && right.canAlias( this ) ) {
1380 const ResultType_t<VT2> tmp( right );
1381 smpSubAssign( left, tmp );
1382 }
1383 else {
1384 smpSubAssign( left, right );
1385 }
1386
1387 BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1388
1389 return *this;
1390}
1392//*************************************************************************************************
1393
1394
1395//*************************************************************************************************
1408template< typename VT // Type of the dense vector
1409 , bool TF // Transpose flag
1410 , size_t... CSAs > // Compile time subvector arguments
1411template< typename VT2 > // Type of the right-hand side vector
1412inline Subvector<VT,unaligned,TF,true,CSAs...>&
1413 Subvector<VT,unaligned,TF,true,CSAs...>::operator*=( const Vector<VT2,TF>& rhs )
1414{
1417
1418 if( size() != (*rhs).size() ) {
1419 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1420 }
1421
1422 using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
1423 Right right( *rhs );
1424
1425 if( !tryMultAssign( vector_, right, offset() ) ) {
1426 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1427 }
1428
1429 decltype(auto) left( derestrict( *this ) );
1430
1431 if( IsReference_v<Right> && right.canAlias( this ) ) {
1432 const ResultType_t<VT2> tmp( right );
1433 smpMultAssign( left, tmp );
1434 }
1435 else {
1436 smpMultAssign( left, right );
1437 }
1438
1439 BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1440
1441 return *this;
1442}
1444//*************************************************************************************************
1445
1446
1447//*************************************************************************************************
1459template< typename VT // Type of the dense vector
1460 , bool TF // Transpose flag
1461 , size_t... CSAs > // Compile time subvector arguments
1462template< typename VT2 > // Type of the right-hand side dense vector
1463inline Subvector<VT,unaligned,TF,true,CSAs...>&
1464 Subvector<VT,unaligned,TF,true,CSAs...>::operator/=( const DenseVector<VT2,TF>& rhs )
1465{
1468
1469 if( size() != (*rhs).size() ) {
1470 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1471 }
1472
1473 using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
1474 Right right( *rhs );
1475
1476 if( !tryDivAssign( vector_, right, offset() ) ) {
1477 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1478 }
1479
1480 decltype(auto) left( derestrict( *this ) );
1481
1482 if( IsReference_v<Right> && right.canAlias( this ) ) {
1483 const ResultType_t<VT2> tmp( right );
1484 smpDivAssign( left, tmp );
1485 }
1486 else {
1487 smpDivAssign( left, right );
1488 }
1489
1490 BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1491
1492 return *this;
1493}
1495//*************************************************************************************************
1496
1497
1498//*************************************************************************************************
1511template< typename VT // Type of the dense vector
1512 , bool TF // Transpose flag
1513 , size_t... CSAs > // Compile time subvector arguments
1514template< typename VT2 > // Type of the right-hand side vector
1515inline Subvector<VT,unaligned,TF,true,CSAs...>&
1516 Subvector<VT,unaligned,TF,true,CSAs...>::operator%=( const Vector<VT2,TF>& rhs )
1517{
1518 using blaze::assign;
1519
1522
1523 using CrossType = CrossTrait_t< ResultType, ResultType_t<VT2> >;
1524
1528
1529 if( size() != 3UL || (*rhs).size() != 3UL ) {
1530 BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
1531 }
1532
1533 const CrossType tmp( *this % (*rhs) );
1534
1535 if( !tryAssign( vector_, tmp, offset() ) ) {
1536 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
1537 }
1538
1539 decltype(auto) left( derestrict( *this ) );
1540
1541 assign( left, tmp );
1542
1543 BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
1544
1545 return *this;
1546}
1548//*************************************************************************************************
1549
1550
1551
1552
1553//=================================================================================================
1554//
1555// UTILITY FUNCTIONS
1556//
1557//=================================================================================================
1558
1559//*************************************************************************************************
1565template< typename VT // Type of the dense vector
1566 , bool TF // Transpose flag
1567 , size_t... CSAs > // Compile time subvector arguments
1568inline VT& Subvector<VT,unaligned,TF,true,CSAs...>::operand() noexcept
1569{
1570 return vector_;
1571}
1573//*************************************************************************************************
1574
1575
1576//*************************************************************************************************
1582template< typename VT // Type of the dense vector
1583 , bool TF // Transpose flag
1584 , size_t... CSAs > // Compile time subvector arguments
1585inline const VT& Subvector<VT,unaligned,TF,true,CSAs...>::operand() const noexcept
1586{
1587 return vector_;
1588}
1590//*************************************************************************************************
1591
1592
1593//*************************************************************************************************
1602template< typename VT // Type of the dense vector
1603 , bool TF // Transpose flag
1604 , size_t... CSAs > // Compile time subvector arguments
1605inline size_t Subvector<VT,unaligned,TF,true,CSAs...>::spacing() const noexcept
1606{
1607 return vector_.spacing() - offset();
1608}
1610//*************************************************************************************************
1611
1612
1613//*************************************************************************************************
1619template< typename VT // Type of the dense vector
1620 , bool TF // Transpose flag
1621 , size_t... CSAs > // Compile time subvector arguments
1622inline size_t Subvector<VT,unaligned,TF,true,CSAs...>::capacity() const noexcept
1623{
1624 return vector_.capacity() - offset();
1625}
1627//*************************************************************************************************
1628
1629
1630//*************************************************************************************************
1639template< typename VT // Type of the dense vector
1640 , bool TF // Transpose flag
1641 , size_t... CSAs > // Compile time subvector arguments
1643{
1644 size_t nonzeros( 0 );
1645
1646 const size_t iend( offset() + size() );
1647 for( size_t i=offset(); i<iend; ++i ) {
1648 if( !isDefault( vector_[i] ) )
1649 ++nonzeros;
1650 }
1651
1652 return nonzeros;
1653}
1655//*************************************************************************************************
1656
1657
1658//*************************************************************************************************
1664template< typename VT // Type of the dense vector
1665 , bool TF // Transpose flag
1666 , size_t... CSAs > // Compile time subvector arguments
1668{
1669 using blaze::clear;
1670
1671 const size_t iend( offset() + size() );
1672 for( size_t i=offset(); i<iend; ++i )
1673 clear( vector_[i] );
1674}
1676//*************************************************************************************************
1677
1678
1679
1680
1681//=================================================================================================
1682//
1683// NUMERIC FUNCTIONS
1684//
1685//=================================================================================================
1686
1687//*************************************************************************************************
1698template< typename VT // Type of the dense vector
1699 , bool TF // Transpose flag
1700 , size_t... CSAs > // Compile time subvector arguments
1701template< typename Other > // Data type of the scalar value
1702inline Subvector<VT,unaligned,TF,true,CSAs...>&
1703 Subvector<VT,unaligned,TF,true,CSAs...>::scale( const Other& scalar )
1704{
1705 const size_t iend( offset() + size() );
1706 for( size_t i=offset(); i<iend; ++i )
1707 vector_[i] *= scalar;
1708 return *this;
1709}
1711//*************************************************************************************************
1712
1713
1714
1715
1716//=================================================================================================
1717//
1718// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1719//
1720//=================================================================================================
1721
1722//*************************************************************************************************
1733template< typename VT // Type of the dense vector
1734 , bool TF // Transpose flag
1735 , size_t... CSAs > // Compile time subvector arguments
1736template< typename Other > // Data type of the foreign expression
1737inline bool Subvector<VT,unaligned,TF,true,CSAs...>::canAlias( const Other* alias ) const noexcept
1738{
1739 return vector_.isAliased( &unview( *alias ) );
1740}
1742//*************************************************************************************************
1743
1744
1745//*************************************************************************************************
1756template< typename VT // Type of the dense vector
1757 , bool TF // Transpose flag
1758 , size_t... CSAs > // Compile time subvector arguments
1759template< typename VT2 // Data type of the foreign dense subvector
1760 , AlignmentFlag AF2 // Alignment flag of the foreign dense subvector
1761 , bool TF2 // Transpose flag of the foreign dense subvector
1762 , size_t... CSAs2 > // Compile time subvector arguments of the foreign dense subvector
1763inline bool
1764 Subvector<VT,unaligned,TF,true,CSAs...>::canAlias( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept
1765{
1766 return ( vector_.isAliased( &alias->vector_ ) &&
1767 ( offset() + size() > alias->offset() ) &&
1768 ( offset() < alias->offset() + alias->size() ) );
1769}
1771//*************************************************************************************************
1772
1773
1774//*************************************************************************************************
1785template< typename VT // Type of the dense vector
1786 , bool TF // Transpose flag
1787 , size_t... CSAs > // Compile time subvector arguments
1788template< typename Other > // Data type of the foreign expression
1789inline bool Subvector<VT,unaligned,TF,true,CSAs...>::isAliased( const Other* alias ) const noexcept
1790{
1791 return vector_.isAliased( &unview( *alias ) );
1792}
1794//*************************************************************************************************
1795
1796
1797//*************************************************************************************************
1808template< typename VT // Type of the dense vector
1809 , bool TF // Transpose flag
1810 , size_t... CSAs > // Compile time subvector arguments
1811template< typename VT2 // Data type of the foreign dense subvector
1812 , AlignmentFlag AF2 // Alignment flag of the foreign dense subvector
1813 , bool TF2 // Transpose flag of the foreign dense subvector
1814 , size_t... CSAs2 > // Compile time subvector arguments of the foreign dense subvector
1815inline bool
1816 Subvector<VT,unaligned,TF,true,CSAs...>::isAliased( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept
1817{
1818 return ( vector_.isAliased( &alias->vector_ ) &&
1819 ( offset() + size() > alias->offset() ) &&
1820 ( offset() < alias->offset() + alias->size() ) );
1821}
1823//*************************************************************************************************
1824
1825
1826//*************************************************************************************************
1836template< typename VT // Type of the dense vector
1837 , bool TF // Transpose flag
1838 , size_t... CSAs > // Compile time subvector arguments
1839inline bool Subvector<VT,unaligned,TF,true,CSAs...>::isAligned() const noexcept
1840{
1841 return isAligned_;
1842}
1844//*************************************************************************************************
1845
1846
1847//*************************************************************************************************
1858template< typename VT // Type of the dense vector
1859 , bool TF // Transpose flag
1860 , size_t... CSAs > // Compile time subvector arguments
1861inline bool Subvector<VT,unaligned,TF,true,CSAs...>::canSMPAssign() const noexcept
1862{
1863 return ( size() > SMP_DVECASSIGN_THRESHOLD );
1864}
1866//*************************************************************************************************
1867
1868
1869//*************************************************************************************************
1883template< typename VT // Type of the dense vector
1884 , bool TF // Transpose flag
1885 , size_t... CSAs > // Compile time subvector arguments
1886BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true,CSAs...>::SIMDType
1887 Subvector<VT,unaligned,TF,true,CSAs...>::load( size_t index ) const noexcept
1888{
1889 if( isAligned_ )
1890 return loada( index );
1891 else
1892 return loadu( index );
1893}
1895//*************************************************************************************************
1896
1897
1898//*************************************************************************************************
1912template< typename VT // Type of the dense vector
1913 , bool TF // Transpose flag
1914 , size_t... CSAs > // Compile time subvector arguments
1915BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true,CSAs...>::SIMDType
1916 Subvector<VT,unaligned,TF,true,CSAs...>::loada( size_t index ) const noexcept
1917{
1919
1920 BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
1921 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
1922 BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
1923
1924 return vector_.loada( offset()+index );
1925}
1927//*************************************************************************************************
1928
1929
1930//*************************************************************************************************
1944template< typename VT // Type of the dense vector
1945 , bool TF // Transpose flag
1946 , size_t... CSAs > // Compile time subvector arguments
1947BLAZE_ALWAYS_INLINE typename Subvector<VT,unaligned,TF,true,CSAs...>::SIMDType
1948 Subvector<VT,unaligned,TF,true,CSAs...>::loadu( size_t index ) const noexcept
1949{
1951
1952 BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
1953 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
1954
1955 return vector_.loadu( offset()+index );
1956}
1958//*************************************************************************************************
1959
1960
1961//*************************************************************************************************
1976template< typename VT // Type of the dense vector
1977 , bool TF // Transpose flag
1978 , size_t... CSAs > // Compile time subvector arguments
1980 Subvector<VT,unaligned,TF,true,CSAs...>::store( size_t index, const SIMDType& value ) noexcept
1981{
1982 if( isAligned_ )
1983 storea( index, value );
1984 else
1985 storeu( index, value );
1986}
1988//*************************************************************************************************
1989
1990
1991//*************************************************************************************************
2006template< typename VT // Type of the dense vector
2007 , bool TF // Transpose flag
2008 , size_t... CSAs > // Compile time subvector arguments
2010 Subvector<VT,unaligned,TF,true,CSAs...>::storea( size_t index, const SIMDType& value ) noexcept
2011{
2013
2014 BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
2015 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
2016 BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
2017
2018 vector_.storea( offset()+index, value );
2019}
2021//*************************************************************************************************
2022
2023
2024//*************************************************************************************************
2039template< typename VT // Type of the dense vector
2040 , bool TF // Transpose flag
2041 , size_t... CSAs > // Compile time subvector arguments
2043 Subvector<VT,unaligned,TF,true,CSAs...>::storeu( size_t index, const SIMDType& value ) noexcept
2044{
2046
2047 BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
2048 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
2049
2050 vector_.storeu( offset()+index, value );
2051}
2053//*************************************************************************************************
2054
2055
2056//*************************************************************************************************
2071template< typename VT // Type of the dense vector
2072 , bool TF // Transpose flag
2073 , size_t... CSAs > // Compile time subvector arguments
2075 Subvector<VT,unaligned,TF,true,CSAs...>::stream( size_t index, const SIMDType& value ) noexcept
2076{
2078
2079 BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
2080 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
2081 BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
2082
2083 if( isAligned_ )
2084 vector_.stream( offset()+index, value );
2085 else
2086 vector_.storeu( offset()+index, value );
2087}
2089//*************************************************************************************************
2090
2091
2092//*************************************************************************************************
2104template< typename VT // Type of the dense vector
2105 , bool TF // Transpose flag
2106 , size_t... CSAs > // Compile time subvector arguments
2107template< typename VT2 > // Type of the right-hand side dense vector
2108inline auto Subvector<VT,unaligned,TF,true,CSAs...>::assign( const DenseVector<VT2,TF>& rhs )
2109 -> DisableIf_t< VectorizedAssign_v<VT2> >
2110{
2111 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2112
2113 const size_t ipos( prevMultiple( size(), 2UL ) );
2114 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
2115
2116 for( size_t i=0UL; i<ipos; i+=2UL ) {
2117 vector_[offset()+i ] = (*rhs)[i ];
2118 vector_[offset()+i+1UL] = (*rhs)[i+1UL];
2119 }
2120 if( ipos < size() ) {
2121 vector_[offset()+ipos] = (*rhs)[ipos];
2122 }
2123}
2125//*************************************************************************************************
2126
2127
2128//*************************************************************************************************
2140template< typename VT // Type of the dense vector
2141 , bool TF // Transpose flag
2142 , size_t... CSAs > // Compile time subvector arguments
2143template< typename VT2 > // Type of the right-hand side dense vector
2144inline auto Subvector<VT,unaligned,TF,true,CSAs...>::assign( const DenseVector<VT2,TF>& rhs )
2145 -> EnableIf_t< VectorizedAssign_v<VT2> >
2146{
2148
2149 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2150
2151 const size_t ipos( prevMultiple( size(), SIMDSIZE ) );
2152 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
2153
2154 size_t i( 0UL );
2155 Iterator left( begin() );
2156 ConstIterator_t<VT2> right( (*rhs).begin() );
2157
2158 if( useStreaming && isAligned_ &&
2159 ( size() > ( cacheSize/( sizeof(ElementType) * 3UL ) ) ) &&
2160 !(*rhs).isAliased( this ) )
2161 {
2162 for( ; i<ipos; i+=SIMDSIZE ) {
2163 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2164 }
2165 for( ; i<size(); ++i ) {
2166 *left = *right;
2167 }
2168 }
2169 else
2170 {
2171 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2172 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2173 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2174 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2175 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2176 }
2177 for( ; i<ipos; i+=SIMDSIZE ) {
2178 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2179 }
2180 for( ; i<size(); ++i ) {
2181 *left = *right; ++left; ++right;
2182 }
2183 }
2184}
2186//*************************************************************************************************
2187
2188
2189//*************************************************************************************************
2201template< typename VT // Type of the dense vector
2202 , bool TF // Transpose flag
2203 , size_t... CSAs > // Compile time subvector arguments
2204template< typename VT2 > // Type of the right-hand side sparse vector
2205inline void Subvector<VT,unaligned,TF,true,CSAs...>::assign( const SparseVector<VT2,TF>& rhs )
2206{
2207 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2208
2209 for( ConstIterator_t<VT2> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
2210 vector_[offset()+element->index()] = element->value();
2211}
2213//*************************************************************************************************
2214
2215
2216//*************************************************************************************************
2228template< typename VT // Type of the dense vector
2229 , bool TF // Transpose flag
2230 , size_t... CSAs > // Compile time subvector arguments
2231template< typename VT2 > // Type of the right-hand side dense vector
2232inline auto Subvector<VT,unaligned,TF,true,CSAs...>::addAssign( const DenseVector<VT2,TF>& rhs )
2233 -> DisableIf_t< VectorizedAddAssign_v<VT2> >
2234{
2235 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2236
2237 const size_t ipos( prevMultiple( size(), 2UL ) );
2238 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
2239
2240 for( size_t i=0UL; i<ipos; i+=2UL ) {
2241 vector_[offset()+i ] += (*rhs)[i ];
2242 vector_[offset()+i+1UL] += (*rhs)[i+1UL];
2243 }
2244 if( ipos < size() ) {
2245 vector_[offset()+ipos] += (*rhs)[ipos];
2246 }
2247}
2249//*************************************************************************************************
2250
2251
2252//*************************************************************************************************
2264template< typename VT // Type of the dense vector
2265 , bool TF // Transpose flag
2266 , size_t... CSAs > // Compile time subvector arguments
2267template< typename VT2 > // Type of the right-hand side dense vector
2268inline auto Subvector<VT,unaligned,TF,true,CSAs...>::addAssign( const DenseVector<VT2,TF>& rhs )
2269 -> EnableIf_t< VectorizedAddAssign_v<VT2> >
2270{
2272
2273 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2274
2275 const size_t ipos( prevMultiple( size(), SIMDSIZE ) );
2276 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
2277
2278 size_t i( 0UL );
2279 Iterator left( begin() );
2280 ConstIterator_t<VT2> right( (*rhs).begin() );
2281
2282 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2283 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2284 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2285 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2286 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2287 }
2288 for( ; i<ipos; i+=SIMDSIZE ) {
2289 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2290 }
2291 for( ; i<size(); ++i ) {
2292 *left += *right; ++left; ++right;
2293 }
2294}
2296//*************************************************************************************************
2297
2298
2299//*************************************************************************************************
2311template< typename VT // Type of the dense vector
2312 , bool TF // Transpose flag
2313 , size_t... CSAs > // Compile time subvector arguments
2314template< typename VT2 > // Type of the right-hand side sparse vector
2315inline void Subvector<VT,unaligned,TF,true,CSAs...>::addAssign( const SparseVector<VT2,TF>& rhs )
2316{
2317 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2318
2319 for( ConstIterator_t<VT2> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
2320 vector_[offset()+element->index()] += element->value();
2321}
2323//*************************************************************************************************
2324
2325
2326//*************************************************************************************************
2338template< typename VT // Type of the dense vector
2339 , bool TF // Transpose flag
2340 , size_t... CSAs > // Compile time subvector arguments
2341template< typename VT2 > // Type of the right-hand side dense vector
2342inline auto Subvector<VT,unaligned,TF,true,CSAs...>::subAssign( const DenseVector<VT2,TF>& rhs )
2343 -> DisableIf_t< VectorizedSubAssign_v<VT2> >
2344{
2345 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2346
2347 const size_t ipos( prevMultiple( size(), 2UL ) );
2348 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
2349
2350 for( size_t i=0UL; i<ipos; i+=2UL ) {
2351 vector_[offset()+i ] -= (*rhs)[i ];
2352 vector_[offset()+i+1UL] -= (*rhs)[i+1UL];
2353 }
2354 if( ipos < size() ) {
2355 vector_[offset()+ipos] -= (*rhs)[ipos];
2356 }
2357}
2359//*************************************************************************************************
2360
2361
2362//*************************************************************************************************
2374template< typename VT // Type of the dense vector
2375 , bool TF // Transpose flag
2376 , size_t... CSAs > // Compile time subvector arguments
2377template< typename VT2 > // Type of the right-hand side dense vector
2378inline auto Subvector<VT,unaligned,TF,true,CSAs...>::subAssign( const DenseVector<VT2,TF>& rhs )
2379 -> EnableIf_t< VectorizedSubAssign_v<VT2> >
2380{
2382
2383 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2384
2385 const size_t ipos( prevMultiple( size(), SIMDSIZE ) );
2386 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
2387
2388 size_t i( 0UL );
2389 Iterator left( begin() );
2390 ConstIterator_t<VT2> right( (*rhs).begin() );
2391
2392 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2393 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2394 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2395 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2396 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2397 }
2398 for( ; i<ipos; i+=SIMDSIZE ) {
2399 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2400 }
2401 for( ; i<size(); ++i ) {
2402 *left -= *right; ++left; ++right;
2403 }
2404}
2406//*************************************************************************************************
2407
2408
2409//*************************************************************************************************
2421template< typename VT // Type of the dense vector
2422 , bool TF // Transpose flag
2423 , size_t... CSAs > // Compile time subvector arguments
2424template< typename VT2 > // Type of the right-hand side sparse vector
2425inline void Subvector<VT,unaligned,TF,true,CSAs...>::subAssign( const SparseVector<VT2,TF>& rhs )
2426{
2427 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2428
2429 for( ConstIterator_t<VT2> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
2430 vector_[offset()+element->index()] -= element->value();
2431}
2433//*************************************************************************************************
2434
2435
2436//*************************************************************************************************
2448template< typename VT // Type of the dense vector
2449 , bool TF // Transpose flag
2450 , size_t... CSAs > // Compile time subvector arguments
2451template< typename VT2 > // Type of the right-hand side dense vector
2452inline auto Subvector<VT,unaligned,TF,true,CSAs...>::multAssign( const DenseVector<VT2,TF>& rhs )
2453 -> DisableIf_t< VectorizedMultAssign_v<VT2> >
2454{
2455 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2456
2457 const size_t ipos( prevMultiple( size(), 2UL ) );
2458 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
2459
2460 for( size_t i=0UL; i<ipos; i+=2UL ) {
2461 vector_[offset()+i ] *= (*rhs)[i ];
2462 vector_[offset()+i+1UL] *= (*rhs)[i+1UL];
2463 }
2464 if( ipos < size() ) {
2465 vector_[offset()+ipos] *= (*rhs)[ipos];
2466 }
2467}
2469//*************************************************************************************************
2470
2471
2472//*************************************************************************************************
2484template< typename VT // Type of the dense vector
2485 , bool TF // Transpose flag
2486 , size_t... CSAs > // Compile time subvector arguments
2487template< typename VT2 > // Type of the right-hand side dense vector
2488inline auto Subvector<VT,unaligned,TF,true,CSAs...>::multAssign( const DenseVector<VT2,TF>& rhs )
2489 -> EnableIf_t< VectorizedMultAssign_v<VT2> >
2490{
2492
2493 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2494
2495 const size_t ipos( prevMultiple( size(), SIMDSIZE ) );
2496 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
2497
2498 size_t i( 0UL );
2499 Iterator left( begin() );
2500 ConstIterator_t<VT2> right( (*rhs).begin() );
2501
2502 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2503 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2504 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2505 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2506 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2507 }
2508 for( ; i<ipos; i+=SIMDSIZE ) {
2509 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2510 }
2511 for( ; i<size(); ++i ) {
2512 *left *= *right; ++left; ++right;
2513 }
2514}
2516//*************************************************************************************************
2517
2518
2519//*************************************************************************************************
2531template< typename VT // Type of the dense vector
2532 , bool TF // Transpose flag
2533 , size_t... CSAs > // Compile time subvector arguments
2534template< typename VT2 > // Type of the right-hand side sparse vector
2535inline void Subvector<VT,unaligned,TF,true,CSAs...>::multAssign( const SparseVector<VT2,TF>& rhs )
2536{
2537 using blaze::reset;
2538
2539 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2540
2541 size_t i( 0UL );
2542
2543 for( ConstIterator_t<VT2> element=(*rhs).begin(); element!=(*rhs).end(); ++element ) {
2544 const size_t index( element->index() );
2545 for( ; i<index; ++i )
2546 reset( vector_[offset()+i] );
2547 vector_[offset()+i] *= element->value();
2548 ++i;
2549 }
2550
2551 for( ; i<size(); ++i ) {
2552 reset( vector_[offset()+i] );
2553 }
2554}
2556//*************************************************************************************************
2557
2558
2559//*************************************************************************************************
2571template< typename VT // Type of the dense vector
2572 , bool TF // Transpose flag
2573 , size_t... CSAs > // Compile time subvector arguments
2574template< typename VT2 > // Type of the right-hand side dense vector
2575inline auto Subvector<VT,unaligned,TF,true,CSAs...>::divAssign( const DenseVector<VT2,TF>& rhs )
2576 -> DisableIf_t< VectorizedDivAssign_v<VT2> >
2577{
2578 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2579
2580 const size_t ipos( prevMultiple( size(), 2UL ) );
2581 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
2582
2583 for( size_t i=0UL; i<ipos; i+=2UL ) {
2584 vector_[offset()+i ] /= (*rhs)[i ];
2585 vector_[offset()+i+1UL] /= (*rhs)[i+1UL];
2586 }
2587 if( ipos < size() ) {
2588 vector_[offset()+ipos] /= (*rhs)[ipos];
2589 }
2590}
2592//*************************************************************************************************
2593
2594
2595//*************************************************************************************************
2607template< typename VT // Type of the dense vector
2608 , bool TF // Transpose flag
2609 , size_t... CSAs > // Compile time subvector arguments
2610template< typename VT2 > // Type of the right-hand side dense vector
2611inline auto Subvector<VT,unaligned,TF,true,CSAs...>::divAssign( const DenseVector<VT2,TF>& rhs )
2612 -> EnableIf_t< VectorizedDivAssign_v<VT2> >
2613{
2615
2616 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2617
2618 const size_t ipos( prevMultiple( size(), SIMDSIZE ) );
2619 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
2620
2621 size_t i( 0UL );
2622 Iterator left( begin() );
2623 ConstIterator_t<VT2> right( (*rhs).begin() );
2624
2625 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2626 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2627 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2628 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2629 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2630 }
2631 for( ; i<ipos; i+=SIMDSIZE ) {
2632 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2633 }
2634 for( ; i<size(); ++i ) {
2635 *left /= *right; ++left; ++right;
2636 }
2637}
2639//*************************************************************************************************
2640
2641
2642
2643
2644
2645
2646
2647
2648//=================================================================================================
2649//
2650// CLASS TEMPLATE SPECIALIZATION FOR ALIGNED DENSE SUBVECTORS
2651//
2652//=================================================================================================
2653
2654//*************************************************************************************************
2662template< typename VT // Type of the dense vector
2663 , bool TF // Transpose flag
2664 , size_t... CSAs > // Compile time subvector arguments
2665class Subvector<VT,aligned,TF,true,CSAs...>
2666 : public View< DenseVector< Subvector<VT,aligned,TF,true,CSAs...>, TF > >
2667 , private SubvectorData<CSAs...>
2668{
2669 private:
2670 //**Type definitions****************************************************************************
2671 using DataType = SubvectorData<CSAs...>;
2672 using Operand = If_t< IsExpression_v<VT>, VT, VT& >;
2673 //**********************************************************************************************
2674
2675 public:
2676 //**Type definitions****************************************************************************
2678 using This = Subvector<VT,aligned,TF,true,CSAs...>;
2679
2680 using BaseType = View< DenseVector<This,TF> >;
2681 using ViewedType = VT;
2682 using ResultType = SubvectorTrait_t<VT,CSAs...>;
2683 using TransposeType = TransposeType_t<ResultType>;
2684 using ElementType = ElementType_t<VT>;
2685 using SIMDType = SIMDTrait_t<ElementType>;
2686 using ReturnType = ReturnType_t<VT>;
2687 using CompositeType = const Subvector&;
2688
2690 using ConstReference = ConstReference_t<VT>;
2691
2693 using Reference = If_t< IsConst_v<VT>, ConstReference, Reference_t<VT> >;
2694
2696 using ConstPointer = ConstPointer_t<VT>;
2697
2699 using Pointer = If_t< IsConst_v<VT> || !HasMutableDataAccess_v<VT>, ConstPointer, Pointer_t<VT> >;
2700
2702 using ConstIterator = ConstIterator_t<VT>;
2703
2705 using Iterator = If_t< IsConst_v<VT>, ConstIterator, Iterator_t<VT> >;
2706 //**********************************************************************************************
2707
2708 //**Compilation flags***************************************************************************
2710 static constexpr bool simdEnabled = VT::simdEnabled;
2711
2713 static constexpr bool smpAssignable = VT::smpAssignable;
2714
2716 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
2717 //**********************************************************************************************
2718
2719 //**Constructors********************************************************************************
2722 template< typename... RSAs >
2723 explicit inline Subvector( VT& vector, RSAs... args );
2724
2725 Subvector( const Subvector& ) = default;
2727 //**********************************************************************************************
2728
2729 //**Destructor**********************************************************************************
2732 ~Subvector() = default;
2734 //**********************************************************************************************
2735
2736 //**Data access functions***********************************************************************
2739 inline Reference operator[]( size_t index );
2740 inline ConstReference operator[]( size_t index ) const;
2741 inline Reference at( size_t index );
2742 inline ConstReference at( size_t index ) const;
2743 inline Pointer data () noexcept;
2744 inline ConstPointer data () const noexcept;
2745 inline Iterator begin ();
2746 inline ConstIterator begin () const;
2747 inline ConstIterator cbegin() const;
2748 inline Iterator end ();
2749 inline ConstIterator end () const;
2750 inline ConstIterator cend () const;
2752 //**********************************************************************************************
2753
2754 //**Assignment operators************************************************************************
2757 inline Subvector& operator= ( const ElementType& rhs );
2758 inline Subvector& operator= ( initializer_list<ElementType> list );
2759 inline Subvector& operator= ( const Subvector& rhs );
2760 template< typename VT2 > inline Subvector& operator= ( const Vector<VT2,TF>& rhs );
2761 template< typename VT2 > inline Subvector& operator+=( const Vector<VT2,TF>& rhs );
2762 template< typename VT2 > inline Subvector& operator-=( const Vector<VT2,TF>& rhs );
2763 template< typename VT2 > inline Subvector& operator*=( const Vector<VT2,TF>& rhs );
2764 template< typename VT2 > inline Subvector& operator/=( const DenseVector<VT2,TF>& rhs );
2765 template< typename VT2 > inline Subvector& operator%=( const Vector<VT2,TF>& rhs );
2767 //**********************************************************************************************
2768
2769 //**Utility functions***************************************************************************
2772 using DataType::offset;
2773 using DataType::size;
2774
2775 inline VT& operand() noexcept;
2776 inline const VT& operand() const noexcept;
2777
2778 inline size_t spacing() const noexcept;
2779 inline size_t capacity() const noexcept;
2780 inline size_t nonZeros() const;
2781 inline void reset();
2783 //**********************************************************************************************
2784
2785 //**Numeric functions***************************************************************************
2788 template< typename Other > inline Subvector& scale( const Other& scalar );
2790 //**********************************************************************************************
2791
2792 private:
2793 //**********************************************************************************************
2795 template< typename VT2 >
2796 static constexpr bool VectorizedAssign_v =
2797 ( useOptimizedKernels &&
2798 simdEnabled && VT2::simdEnabled &&
2799 IsSIMDCombinable_v< ElementType, ElementType_t<VT2> > );
2800 //**********************************************************************************************
2801
2802 //**********************************************************************************************
2804 template< typename VT2 >
2805 static constexpr bool VectorizedAddAssign_v =
2806 ( VectorizedAssign_v<VT2> &&
2807 HasSIMDAdd_v< ElementType, ElementType_t<VT2> > );
2808 //**********************************************************************************************
2809
2810 //**********************************************************************************************
2812 template< typename VT2 >
2813 static constexpr bool VectorizedSubAssign_v =
2814 ( VectorizedAssign_v<VT2> &&
2815 HasSIMDSub_v< ElementType, ElementType_t<VT2> > );
2816 //**********************************************************************************************
2817
2818 //**********************************************************************************************
2820 template< typename VT2 >
2821 static constexpr bool VectorizedMultAssign_v =
2822 ( VectorizedAssign_v<VT2> &&
2823 HasSIMDMult_v< ElementType, ElementType_t<VT2> > );
2824 //**********************************************************************************************
2825
2826 //**********************************************************************************************
2828 template< typename VT2 >
2829 static constexpr bool VectorizedDivAssign_v =
2830 ( VectorizedAssign_v<VT2> &&
2831 HasSIMDDiv_v< ElementType, ElementType_t<VT2> > );
2832 //**********************************************************************************************
2833
2834 //**SIMD properties*****************************************************************************
2836 static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
2837 //**********************************************************************************************
2838
2839 public:
2840 //**Expression template evaluation functions****************************************************
2843 template< typename Other >
2844 inline bool canAlias( const Other* alias ) const noexcept;
2845
2846 template< typename VT2, AlignmentFlag AF2, bool TF2, size_t... CSAs2 >
2847 inline bool canAlias( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept;
2848
2849 template< typename Other >
2850 inline bool isAliased( const Other* alias ) const noexcept;
2851
2852 template< typename VT2, AlignmentFlag AF2, bool TF2, size_t... CSAs2 >
2853 inline bool isAliased( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept;
2854
2855 inline bool isAligned () const noexcept;
2856 inline bool canSMPAssign() const noexcept;
2857
2858 BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
2859 BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
2860 BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
2861
2862 BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
2863 BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
2864 BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
2865 BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
2866
2867 template< typename VT2 >
2868 inline auto assign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedAssign_v<VT2> >;
2869
2870 template< typename VT2 >
2871 inline auto assign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedAssign_v<VT2> >;
2872
2873 template< typename VT2 > inline void assign( const SparseVector<VT2,TF>& rhs );
2874
2875 template< typename VT2 >
2876 inline auto addAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<VT2> >;
2877
2878 template< typename VT2 >
2879 inline auto addAssign ( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<VT2> >;
2880
2881 template< typename VT2 > inline void addAssign( const SparseVector<VT2,TF>& rhs );
2882
2883 template< typename VT2 >
2884 inline auto subAssign ( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<VT2> >;
2885
2886 template< typename VT2 >
2887 inline auto subAssign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<VT2> >;
2888
2889 template< typename VT2 > inline void subAssign( const SparseVector<VT2,TF>& rhs );
2890
2891 template< typename VT2 >
2892 inline auto multAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedMultAssign_v<VT2> >;
2893
2894 template< typename VT2 >
2895 inline auto multAssign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedMultAssign_v<VT2> >;
2896
2897 template< typename VT2 > inline void multAssign( const SparseVector<VT2,TF>& rhs );
2898
2899 template< typename VT2 >
2900 inline auto divAssign( const DenseVector <VT2,TF>& rhs ) -> DisableIf_t< VectorizedDivAssign_v<VT2> >;
2901
2902 template< typename VT2 >
2903 inline auto divAssign( const DenseVector <VT2,TF>& rhs ) -> EnableIf_t< VectorizedDivAssign_v<VT2> >;
2905 //**********************************************************************************************
2906
2907 private:
2908 //**Member variables****************************************************************************
2911 Operand vector_;
2913 //**********************************************************************************************
2914
2915 //**Friend declarations*************************************************************************
2916 template< typename VT2, AlignmentFlag AF2, bool TF2, bool DF2, size_t... CSAs2 > friend class Subvector;
2917 //**********************************************************************************************
2918
2919 //**Compile time checks*************************************************************************
2925 //**********************************************************************************************
2926};
2928//*************************************************************************************************
2929
2930
2931
2932
2933//=================================================================================================
2934//
2935// CONSTRUCTORS
2936//
2937//=================================================================================================
2938
2939//*************************************************************************************************
2953template< typename VT // Type of the dense vector
2954 , bool TF // Transpose flag
2955 , size_t... CSAs > // Compile time subvector arguments
2956template< typename... RSAs > // Runtime subvector arguments
2957inline Subvector<VT,aligned,TF,true,CSAs...>::Subvector( VT& vector, RSAs... args )
2958 : DataType( args... ) // Base class initialization
2959 , vector_ ( vector ) // The vector containing the subvector
2960{
2961 if( isChecked( args... ) )
2962 {
2963 if( offset() + size() > vector.size() ) {
2964 BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
2965 }
2966
2967 if( simdEnabled && IsContiguous_v<VT> && !checkAlignment( data() ) ) {
2968 BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector alignment" );
2969 }
2970 }
2971 else
2972 {
2973 BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
2974 BLAZE_USER_ASSERT( !simdEnabled || !IsContiguous_v<VT> || checkAlignment( data() ), "Invalid subvector alignment" );
2975 }
2976}
2978//*************************************************************************************************
2979
2980
2981
2982
2983//=================================================================================================
2984//
2985// DATA ACCESS FUNCTIONS
2986//
2987//=================================================================================================
2988
2989//*************************************************************************************************
2996template< typename VT // Type of the dense vector
2997 , bool TF // Transpose flag
2998 , size_t... CSAs > // Compile time subvector arguments
2999inline typename Subvector<VT,aligned,TF,true,CSAs...>::Reference
3000 Subvector<VT,aligned,TF,true,CSAs...>::operator[]( size_t index )
3001{
3002 BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
3003 return vector_[offset()+index];
3004}
3006//*************************************************************************************************
3007
3008
3009//*************************************************************************************************
3016template< typename VT // Type of the dense vector
3017 , bool TF // Transpose flag
3018 , size_t... CSAs > // Compile time subvector arguments
3019inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstReference
3020 Subvector<VT,aligned,TF,true,CSAs...>::operator[]( size_t index ) const
3021{
3022 BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
3023 return const_cast<const VT&>( vector_ )[offset()+index];
3024}
3026//*************************************************************************************************
3027
3028
3029//*************************************************************************************************
3040template< typename VT // Type of the dense vector
3041 , bool TF // Transpose flag
3042 , size_t... CSAs > // Compile time subvector arguments
3043inline typename Subvector<VT,aligned,TF,true,CSAs...>::Reference
3044 Subvector<VT,aligned,TF,true,CSAs...>::at( size_t index )
3045{
3046 if( index >= size() ) {
3047 BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
3048 }
3049 return (*this)[index];
3050}
3052//*************************************************************************************************
3053
3054
3055//*************************************************************************************************
3066template< typename VT // Type of the dense vector
3067 , bool TF // Transpose flag
3068 , size_t... CSAs > // Compile time subvector arguments
3069inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstReference
3070 Subvector<VT,aligned,TF,true,CSAs...>::at( size_t index ) const
3071{
3072 if( index >= size() ) {
3073 BLAZE_THROW_OUT_OF_RANGE( "Invalid subvector access index" );
3074 }
3075 return (*this)[index];
3076}
3078//*************************************************************************************************
3079
3080
3081//*************************************************************************************************
3089template< typename VT // Type of the dense vector
3090 , bool TF // Transpose flag
3091 , size_t... CSAs > // Compile time subvector arguments
3092inline typename Subvector<VT,aligned,TF,true,CSAs...>::Pointer
3094{
3095 return vector_.data() + offset();
3096}
3098//*************************************************************************************************
3099
3100
3101//*************************************************************************************************
3109template< typename VT // Type of the dense vector
3110 , bool TF // Transpose flag
3111 , size_t... CSAs > // Compile time subvector arguments
3112inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstPointer
3114{
3115 return vector_.data() + offset();
3116}
3118//*************************************************************************************************
3119
3120
3121//*************************************************************************************************
3129template< typename VT // Type of the dense vector
3130 , bool TF // Transpose flag
3131 , size_t... CSAs > // Compile time subvector arguments
3132inline typename Subvector<VT,aligned,TF,true,CSAs...>::Iterator
3134{
3135 return ( vector_.begin() + offset() );
3136}
3138//*************************************************************************************************
3139
3140
3141//*************************************************************************************************
3149template< typename VT // Type of the dense vector
3150 , bool TF // Transpose flag
3151 , size_t... CSAs > // Compile time subvector arguments
3152inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstIterator
3154{
3155 return ( vector_.cbegin() + offset() );
3156}
3158//*************************************************************************************************
3159
3160
3161//*************************************************************************************************
3169template< typename VT // Type of the dense vector
3170 , bool TF // Transpose flag
3171 , size_t... CSAs > // Compile time subvector arguments
3172inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstIterator
3174{
3175 return ( vector_.cbegin() + offset() );
3176}
3178//*************************************************************************************************
3179
3180
3181//*************************************************************************************************
3189template< typename VT // Type of the dense vector
3190 , bool TF // Transpose flag
3191 , size_t... CSAs > // Compile time subvector arguments
3192inline typename Subvector<VT,aligned,TF,true,CSAs...>::Iterator
3194{
3195 return ( vector_.begin() + offset() + size() );
3196}
3198//*************************************************************************************************
3199
3200
3201//*************************************************************************************************
3209template< typename VT // Type of the dense vector
3210 , bool TF // Transpose flag
3211 , size_t... CSAs > // Compile time subvector arguments
3212inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstIterator
3214{
3215 return ( vector_.cbegin() + offset() + size() );
3216}
3218//*************************************************************************************************
3219
3220
3221//*************************************************************************************************
3229template< typename VT // Type of the dense vector
3230 , bool TF // Transpose flag
3231 , size_t... CSAs > // Compile time subvector arguments
3232inline typename Subvector<VT,aligned,TF,true,CSAs...>::ConstIterator
3234{
3235 return ( vector_.cbegin() + offset() + size() );
3236}
3238//*************************************************************************************************
3239
3240
3241
3242
3243//=================================================================================================
3244//
3245// ASSIGNMENT OPERATORS
3246//
3247//=================================================================================================
3248
3249//*************************************************************************************************
3256template< typename VT // Type of the dense vector
3257 , bool TF // Transpose flag
3258 , size_t... CSAs > // Compile time subvector arguments
3259inline Subvector<VT,aligned,TF,true,CSAs...>&
3260 Subvector<VT,aligned,TF,true,CSAs...>::operator=( const ElementType& rhs )
3261{
3262 const size_t iend( offset() + size() );
3263 decltype(auto) left( derestrict( vector_ ) );
3264
3265 for( size_t i=offset(); i<iend; ++i ) {
3266 if( !IsRestricted_v<VT> || trySet( vector_, i, rhs ) )
3267 left[i] = rhs;
3268 }
3269
3270 return *this;
3271}
3273//*************************************************************************************************
3274
3275
3276//*************************************************************************************************
3289template< typename VT // Type of the dense vector
3290 , bool TF // Transpose flag
3291 , size_t... CSAs > // Compile time subvector arguments
3292inline Subvector<VT,aligned,TF,true,CSAs...>&
3293 Subvector<VT,aligned,TF,true,CSAs...>::operator=( initializer_list<ElementType> list )
3294{
3295 if( list.size() > size() ) {
3296 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to subvector" );
3297 }
3298
3299 if( IsRestricted_v<VT> ) {
3300 const InitializerVector<ElementType,TF> tmp( list, size() );
3301 if( !tryAssign( vector_, tmp, offset() ) ) {
3302 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3303 }
3304 }
3305
3306 decltype(auto) left( derestrict( *this ) );
3307
3308 std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
3309
3310 BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3311
3312 return *this;
3313}
3315//*************************************************************************************************
3316
3317
3318//*************************************************************************************************
3330template< typename VT // Type of the dense vector
3331 , bool TF // Transpose flag
3332 , size_t... CSAs > // Compile time subvector arguments
3333inline Subvector<VT,aligned,TF,true,CSAs...>&
3334 Subvector<VT,aligned,TF,true,CSAs...>::operator=( const Subvector& rhs )
3335{
3338
3339 if( &rhs == this || ( &vector_ == &rhs.vector_ && offset() == rhs.offset() ) )
3340 return *this;
3341
3342 if( size() != rhs.size() ) {
3343 BLAZE_THROW_INVALID_ARGUMENT( "Subvector sizes do not match" );
3344 }
3345
3346 if( !tryAssign( vector_, rhs, offset() ) ) {
3347 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3348 }
3349
3350 decltype(auto) left( derestrict( *this ) );
3351
3352 if( rhs.canAlias( this ) ) {
3353 const ResultType tmp( *rhs );
3354 smpAssign( left, tmp );
3355 }
3356 else {
3357 smpAssign( left, rhs );
3358 }
3359
3360 BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3361
3362 return *this;
3363}
3365//*************************************************************************************************
3366
3367
3368//*************************************************************************************************
3380template< typename VT // Type of the dense vector
3381 , bool TF // Transpose flag
3382 , size_t... CSAs > // Compile time subvector arguments
3383template< typename VT2 > // Type of the right-hand side vector
3384inline Subvector<VT,aligned,TF,true,CSAs...>&
3385 Subvector<VT,aligned,TF,true,CSAs...>::operator=( const Vector<VT2,TF>& rhs )
3386{
3389
3390 if( size() != (*rhs).size() ) {
3391 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3392 }
3393
3394 using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
3395 Right right( *rhs );
3396
3397 if( !tryAssign( vector_, right, offset() ) ) {
3398 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3399 }
3400
3401 decltype(auto) left( derestrict( *this ) );
3402
3403 if( IsReference_v<Right> && right.canAlias( this ) ) {
3404 const ResultType_t<VT2> tmp( right );
3405 smpAssign( left, tmp );
3406 }
3407 else {
3408 if( IsSparseVector_v<VT2> )
3409 reset();
3410 smpAssign( left, right );
3411 }
3412
3413 BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3414
3415 return *this;
3416}
3418//*************************************************************************************************
3419
3420
3421//*************************************************************************************************
3433template< typename VT // Type of the dense vector
3434 , bool TF // Transpose flag
3435 , size_t... CSAs > // Compile time subvector arguments
3436template< typename VT2 > // Type of the right-hand side vector
3437inline Subvector<VT,aligned,TF,true,CSAs...>&
3438 Subvector<VT,aligned,TF,true,CSAs...>::operator+=( const Vector<VT2,TF>& rhs )
3439{
3442
3443 if( size() != (*rhs).size() ) {
3444 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3445 }
3446
3447 using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
3448 Right right( *rhs );
3449
3450 if( !tryAddAssign( vector_, right, offset() ) ) {
3451 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3452 }
3453
3454 decltype(auto) left( derestrict( *this ) );
3455
3456 if( IsReference_v<Right> && right.canAlias( this ) ) {
3457 const ResultType_t<VT2> tmp( right );
3458 smpAddAssign( left, tmp );
3459 }
3460 else {
3461 smpAddAssign( left, right );
3462 }
3463
3464 BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3465
3466 return *this;
3467}
3469//*************************************************************************************************
3470
3471
3472//*************************************************************************************************
3484template< typename VT // Type of the dense vector
3485 , bool TF // Transpose flag
3486 , size_t... CSAs > // Compile time subvector arguments
3487template< typename VT2 > // Type of the right-hand side vector
3488inline Subvector<VT,aligned,TF,true,CSAs...>&
3489 Subvector<VT,aligned,TF,true,CSAs...>::operator-=( const Vector<VT2,TF>& rhs )
3490{
3493
3494 if( size() != (*rhs).size() ) {
3495 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3496 }
3497
3498 using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
3499 Right right( *rhs );
3500
3501 if( !trySubAssign( vector_, right, offset() ) ) {
3502 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3503 }
3504
3505 decltype(auto) left( derestrict( *this ) );
3506
3507 if( IsReference_v<Right> && right.canAlias( this ) ) {
3508 const ResultType_t<VT2> tmp( right );
3509 smpSubAssign( left, tmp );
3510 }
3511 else {
3512 smpSubAssign( left, right );
3513 }
3514
3515 BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3516
3517 return *this;
3518}
3520//*************************************************************************************************
3521
3522
3523//*************************************************************************************************
3536template< typename VT // Type of the dense vector
3537 , bool TF // Transpose flag
3538 , size_t... CSAs > // Compile time subvector arguments
3539template< typename VT2 > // Type of the right-hand side vector
3540inline Subvector<VT,aligned,TF,true,CSAs...>&
3541 Subvector<VT,aligned,TF,true,CSAs...>::operator*=( const Vector<VT2,TF>& rhs )
3542{
3545
3546 if( size() != (*rhs).size() ) {
3547 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3548 }
3549
3550 using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
3551 Right right( *rhs );
3552
3553 if( !tryMultAssign( vector_, right, offset() ) ) {
3554 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3555 }
3556
3557 decltype(auto) left( derestrict( *this ) );
3558
3559 if( IsReference_v<Right> && right.canAlias( this ) ) {
3560 const ResultType_t<VT2> tmp( right );
3561 smpMultAssign( left, tmp );
3562 }
3563 else {
3564 smpMultAssign( left, right );
3565 }
3566
3567 BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3568
3569 return *this;
3570}
3572//*************************************************************************************************
3573
3574
3575//*************************************************************************************************
3587template< typename VT // Type of the dense vector
3588 , bool TF // Transpose flag
3589 , size_t... CSAs > // Compile time subvector arguments
3590template< typename VT2 > // Type of the right-hand side dense vector
3591inline Subvector<VT,aligned,TF,true,CSAs...>&
3592 Subvector<VT,aligned,TF,true,CSAs...>::operator/=( const DenseVector<VT2,TF>& rhs )
3593{
3596
3597 if( size() != (*rhs).size() ) {
3598 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3599 }
3600
3601 using Right = If_t< IsRestricted_v<VT>, CompositeType_t<VT2>, const VT2& >;
3602 Right right( *rhs );
3603
3604 if( !tryDivAssign( vector_, right, offset() ) ) {
3605 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3606 }
3607
3608 decltype(auto) left( derestrict( *this ) );
3609
3610 if( IsReference_v<Right> && right.canAlias( this ) ) {
3611 const ResultType_t<VT2> tmp( right );
3612 smpDivAssign( left, tmp );
3613 }
3614 else {
3615 smpDivAssign( left, right );
3616 }
3617
3618 BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3619
3620 return *this;
3621}
3623//*************************************************************************************************
3624
3625
3626//*************************************************************************************************
3639template< typename VT // Type of the dense vector
3640 , bool TF // Transpose flag
3641 , size_t... CSAs > // Compile time subvector arguments
3642template< typename VT2 > // Type of the right-hand side vector
3643inline Subvector<VT,aligned,TF,true,CSAs...>&
3644 Subvector<VT,aligned,TF,true,CSAs...>::operator%=( const Vector<VT2,TF>& rhs )
3645{
3646 using blaze::assign;
3647
3650
3651 using CrossType = CrossTrait_t< ResultType, ResultType_t<VT2> >;
3652
3656
3657 if( size() != 3UL || (*rhs).size() != 3UL ) {
3658 BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
3659 }
3660
3661 const CrossType tmp( *this % (*rhs) );
3662
3663 if( !tryAssign( vector_, tmp, offset() ) ) {
3664 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted vector" );
3665 }
3666
3667 decltype(auto) left( derestrict( *this ) );
3668
3669 assign( left, tmp );
3670
3671 BLAZE_INTERNAL_ASSERT( isIntact( vector_ ), "Invariant violation detected" );
3672
3673 return *this;
3674}
3676//*************************************************************************************************
3677
3678
3679
3680
3681//=================================================================================================
3682//
3683// UTILITY FUNCTIONS
3684//
3685//=================================================================================================
3686
3687//*************************************************************************************************
3693template< typename VT // Type of the dense vector
3694 , bool TF // Transpose flag
3695 , size_t... CSAs > // Compile time subvector arguments
3696inline VT& Subvector<VT,aligned,TF,true,CSAs...>::operand() noexcept
3697{
3698 return vector_;
3699}
3701//*************************************************************************************************
3702
3703
3704//*************************************************************************************************
3710template< typename VT // Type of the dense vector
3711 , bool TF // Transpose flag
3712 , size_t... CSAs > // Compile time subvector arguments
3713inline const VT& Subvector<VT,aligned,TF,true,CSAs...>::operand() const noexcept
3714{
3715 return vector_;
3716}
3718//*************************************************************************************************
3719
3720
3721//*************************************************************************************************
3730template< typename VT // Type of the dense vector
3731 , bool TF // Transpose flag
3732 , size_t... CSAs > // Compile time subvector arguments
3733inline size_t Subvector<VT,aligned,TF,true,CSAs...>::spacing() const noexcept
3734{
3735 return vector_.spacing() - offset();
3736}
3738//*************************************************************************************************
3739
3740
3741//*************************************************************************************************
3747template< typename VT // Type of the dense vector
3748 , bool TF // Transpose flag
3749 , size_t... CSAs > // Compile time subvector arguments
3750inline size_t Subvector<VT,aligned,TF,true,CSAs...>::capacity() const noexcept
3751{
3752 return vector_.capacity() - offset();
3753}
3755//*************************************************************************************************
3756
3757
3758//*************************************************************************************************
3767template< typename VT // Type of the dense vector
3768 , bool TF // Transpose flag
3769 , size_t... CSAs > // Compile time subvector arguments
3771{
3772 size_t nonzeros( 0 );
3773
3774 const size_t iend( offset() + size() );
3775 for( size_t i=offset(); i<iend; ++i ) {
3776 if( !isDefault( vector_[i] ) )
3777 ++nonzeros;
3778 }
3779
3780 return nonzeros;
3781}
3783//*************************************************************************************************
3784
3785
3786//*************************************************************************************************
3792template< typename VT // Type of the dense vector
3793 , bool TF // Transpose flag
3794 , size_t... CSAs > // Compile time subvector arguments
3796{
3797 using blaze::clear;
3798
3799 const size_t iend( offset() + size() );
3800 for( size_t i=offset(); i<iend; ++i )
3801 clear( vector_[i] );
3802}
3804//*************************************************************************************************
3805
3806
3807
3808
3809//=================================================================================================
3810//
3811// NUMERIC FUNCTIONS
3812//
3813//=================================================================================================
3814
3815//*************************************************************************************************
3826template< typename VT // Type of the dense vector
3827 , bool TF // Transpose flag
3828 , size_t... CSAs > // Compile time subvector arguments
3829template< typename Other > // Data type of the scalar value
3830inline Subvector<VT,aligned,TF,true,CSAs...>&
3831 Subvector<VT,aligned,TF,true,CSAs...>::scale( const Other& scalar )
3832{
3833 const size_t iend( offset() + size() );
3834 for( size_t i=offset(); i<iend; ++i )
3835 vector_[i] *= scalar;
3836 return *this;
3837}
3839//*************************************************************************************************
3840
3841
3842
3843
3844//=================================================================================================
3845//
3846// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3847//
3848//=================================================================================================
3849
3850//*************************************************************************************************
3861template< typename VT // Type of the dense vector
3862 , bool TF // Transpose flag
3863 , size_t... CSAs > // Compile time subvector arguments
3864template< typename Other > // Data type of the foreign expression
3865inline bool Subvector<VT,aligned,TF,true,CSAs...>::canAlias( const Other* alias ) const noexcept
3866{
3867 return vector_.isAliased( &unview( *alias ) );
3868}
3870//*************************************************************************************************
3871
3872
3873//*************************************************************************************************
3884template< typename VT // Type of the dense vector
3885 , bool TF // Transpose flag
3886 , size_t... CSAs > // Compile time subvector arguments
3887template< typename VT2 // Data type of the foreign dense subvector
3888 , AlignmentFlag AF2 // Alignment flag of the foreign dense subvector
3889 , bool TF2 // Transpose flag of the foreign dense subvector
3890 , size_t... CSAs2 > // Compile time subvector arguments of the foreign dense subvector
3891inline bool
3892 Subvector<VT,aligned,TF,true,CSAs...>::canAlias( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept
3893{
3894 return ( vector_.isAliased( &alias->vector_ ) &&
3895 ( offset() + size() > alias->offset() ) &&
3896 ( offset() < alias->offset() + alias->size() ) );
3897}
3899//*************************************************************************************************
3900
3901
3902//*************************************************************************************************
3913template< typename VT // Type of the dense vector
3914 , bool TF // Transpose flag
3915 , size_t... CSAs > // Compile time subvector arguments
3916template< typename Other > // Data type of the foreign expression
3917inline bool Subvector<VT,aligned,TF,true,CSAs...>::isAliased( const Other* alias ) const noexcept
3918{
3919 return vector_.isAliased( &unview( *alias ) );
3920}
3922//*************************************************************************************************
3923
3924
3925//*************************************************************************************************
3936template< typename VT // Type of the dense vector
3937 , bool TF // Transpose flag
3938 , size_t... CSAs > // Compile time subvector arguments
3939template< typename VT2 // Data type of the foreign dense subvector
3940 , AlignmentFlag AF2 // Alignment flag of the foreign dense subvector
3941 , bool TF2 // Transpose flag of the foreign dense subvector
3942 , size_t... CSAs2 > // Compile time subvector arguments of the foreign dense subvector
3943inline bool
3944 Subvector<VT,aligned,TF,true,CSAs...>::isAliased( const Subvector<VT2,AF2,TF2,true,CSAs2...>* alias ) const noexcept
3945{
3946 return ( vector_.isAliased( &alias->vector_ ) &&
3947 ( offset() + size() > alias->offset() ) &&
3948 ( offset() < alias->offset() + alias->size() ) );
3949}
3951//*************************************************************************************************
3952
3953
3954//*************************************************************************************************
3964template< typename VT // Type of the dense vector
3965 , bool TF // Transpose flag
3966 , size_t... CSAs > // Compile time subvector arguments
3967inline bool Subvector<VT,aligned,TF,true,CSAs...>::isAligned() const noexcept
3968{
3969 return true;
3970}
3972//*************************************************************************************************
3973
3974
3975//*************************************************************************************************
3986template< typename VT // Type of the dense vector
3987 , bool TF // Transpose flag
3988 , size_t... CSAs > // Compile time subvector arguments
3989inline bool Subvector<VT,aligned,TF,true,CSAs...>::canSMPAssign() const noexcept
3990{
3991 return ( size() > SMP_DVECASSIGN_THRESHOLD );
3992}
3994//*************************************************************************************************
3995
3996
3997//*************************************************************************************************
4011template< typename VT // Type of the dense vector
4012 , bool TF // Transpose flag
4013 , size_t... CSAs > // Compile time subvector arguments
4014BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true,CSAs...>::SIMDType
4015 Subvector<VT,aligned,TF,true,CSAs...>::load( size_t index ) const noexcept
4016{
4017 return loada( index );
4018}
4020//*************************************************************************************************
4021
4022
4023//*************************************************************************************************
4037template< typename VT // Type of the dense vector
4038 , bool TF // Transpose flag
4039 , size_t... CSAs > // Compile time subvector arguments
4040BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true,CSAs...>::SIMDType
4041 Subvector<VT,aligned,TF,true,CSAs...>::loada( size_t index ) const noexcept
4042{
4044
4045 BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4046 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4047 BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4048
4049 return vector_.loada( offset()+index );
4050}
4052//*************************************************************************************************
4053
4054
4055//*************************************************************************************************
4069template< typename VT // Type of the dense vector
4070 , bool TF // Transpose flag
4071 , size_t... CSAs > // Compile time subvector arguments
4072BLAZE_ALWAYS_INLINE typename Subvector<VT,aligned,TF,true,CSAs...>::SIMDType
4073 Subvector<VT,aligned,TF,true,CSAs...>::loadu( size_t index ) const noexcept
4074{
4076
4077 BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4078 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4079
4080 return vector_.loadu( offset()+index );
4081}
4083//*************************************************************************************************
4084
4085
4086//*************************************************************************************************
4101template< typename VT // Type of the dense vector
4102 , bool TF // Transpose flag
4103 , size_t... CSAs > // Compile time subvector arguments
4105 Subvector<VT,aligned,TF,true,CSAs...>::store( size_t index, const SIMDType& value ) noexcept
4106{
4107 storea( index, value );
4108}
4110//*************************************************************************************************
4111
4112
4113//*************************************************************************************************
4128template< typename VT // Type of the dense vector
4129 , bool TF // Transpose flag
4130 , size_t... CSAs > // Compile time subvector arguments
4132 Subvector<VT,aligned,TF,true,CSAs...>::storea( size_t index, const SIMDType& value ) noexcept
4133{
4135
4136 BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4137 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4138 BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4139
4140 vector_.storea( offset()+index, value );
4141}
4143//*************************************************************************************************
4144
4145
4146//*************************************************************************************************
4161template< typename VT // Type of the dense vector
4162 , bool TF // Transpose flag
4163 , size_t... CSAs > // Compile time subvector arguments
4165 Subvector<VT,aligned,TF,true,CSAs...>::storeu( size_t index, const SIMDType& value ) noexcept
4166{
4168
4169 BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4170 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4171
4172 vector_.storeu( offset()+index, value );
4173}
4175//*************************************************************************************************
4176
4177
4178//*************************************************************************************************
4193template< typename VT // Type of the dense vector
4194 , bool TF // Transpose flag
4195 , size_t... CSAs > // Compile time subvector arguments
4197 Subvector<VT,aligned,TF,true,CSAs...>::stream( size_t index, const SIMDType& value ) noexcept
4198{
4200
4201 BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
4202 BLAZE_INTERNAL_ASSERT( index + SIMDSIZE <= size(), "Invalid subvector access index" );
4203 BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL , "Invalid subvector access index" );
4204
4205 vector_.stream( offset()+index, value );
4206}
4208//*************************************************************************************************
4209
4210
4211//*************************************************************************************************
4223template< typename VT // Type of the dense vector
4224 , bool TF // Transpose flag
4225 , size_t... CSAs > // Compile time subvector arguments
4226template< typename VT2 > // Type of the right-hand side dense vector
4227inline auto Subvector<VT,aligned,TF,true,CSAs...>::assign( const DenseVector<VT2,TF>& rhs )
4228 -> DisableIf_t< VectorizedAssign_v<VT2> >
4229{
4230 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4231
4232 const size_t ipos( prevMultiple( size(), 2UL ) );
4233 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
4234
4235 for( size_t i=0UL; i<ipos; i+=2UL ) {
4236 vector_[offset()+i ] = (*rhs)[i ];
4237 vector_[offset()+i+1UL] = (*rhs)[i+1UL];
4238 }
4239 if( ipos < size() ) {
4240 vector_[offset()+ipos] = (*rhs)[ipos];
4241 }
4242}
4244//*************************************************************************************************
4245
4246
4247//*************************************************************************************************
4259template< typename VT // Type of the dense vector
4260 , bool TF // Transpose flag
4261 , size_t... CSAs > // Compile time subvector arguments
4262template< typename VT2 > // Type of the right-hand side dense vector
4263inline auto Subvector<VT,aligned,TF,true,CSAs...>::assign( const DenseVector<VT2,TF>& rhs )
4264 -> EnableIf_t< VectorizedAssign_v<VT2> >
4265{
4267
4268 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4269
4270 const size_t ipos( prevMultiple( size(), SIMDSIZE ) );
4271 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
4272
4273 size_t i( 0UL );
4274 Iterator left( begin() );
4275 ConstIterator_t<VT2> right( (*rhs).begin() );
4276
4277 if( useStreaming && size() > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(*rhs).isAliased( this ) )
4278 {
4279 for( ; i<ipos; i+=SIMDSIZE ) {
4280 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4281 }
4282 for( ; i<size(); ++i ) {
4283 *left = *right; ++left; ++right;
4284 }
4285 }
4286 else
4287 {
4288 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4289 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4290 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4291 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4292 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4293 }
4294 for( ; i<ipos; i+=SIMDSIZE ) {
4295 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4296 }
4297 for( ; i<size(); ++i ) {
4298 *left = *right; ++left; ++right;
4299 }
4300 }
4301}
4303//*************************************************************************************************
4304
4305
4306//*************************************************************************************************
4318template< typename VT // Type of the dense vector
4319 , bool TF // Transpose flag
4320 , size_t... CSAs > // Compile time subvector arguments
4321template< typename VT2 > // Type of the right-hand side sparse vector
4322inline void Subvector<VT,aligned,TF,true,CSAs...>::assign( const SparseVector<VT2,TF>& rhs )
4323{
4324 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4325
4326 for( ConstIterator_t<VT2> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
4327 vector_[offset()+element->index()] = element->value();
4328}
4330//*************************************************************************************************
4331
4332
4333//*************************************************************************************************
4345template< typename VT // Type of the dense vector
4346 , bool TF // Transpose flag
4347 , size_t... CSAs > // Compile time subvector arguments
4348template< typename VT2 > // Type of the right-hand side dense vector
4349inline auto Subvector<VT,aligned,TF,true,CSAs...>::addAssign( const DenseVector<VT2,TF>& rhs )
4350 -> DisableIf_t< VectorizedAddAssign_v<VT2> >
4351{
4352 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4353
4354 const size_t ipos( prevMultiple( size(), 2UL ) );
4355 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
4356
4357 for( size_t i=0UL; i<ipos; i+=2UL ) {
4358 vector_[offset()+i ] += (*rhs)[i ];
4359 vector_[offset()+i+1UL] += (*rhs)[i+1UL];
4360 }
4361 if( ipos < size() ) {
4362 vector_[offset()+ipos] += (*rhs)[ipos];
4363 }
4364}
4366//*************************************************************************************************
4367
4368
4369//*************************************************************************************************
4381template< typename VT // Type of the dense vector
4382 , bool TF // Transpose flag
4383 , size_t... CSAs > // Compile time subvector arguments
4384template< typename VT2 > // Type of the right-hand side dense vector
4385inline auto Subvector<VT,aligned,TF,true,CSAs...>::addAssign( const DenseVector<VT2,TF>& rhs )
4386 -> EnableIf_t< VectorizedAddAssign_v<VT2> >
4387{
4389
4390 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4391
4392 const size_t ipos( prevMultiple( size(), SIMDSIZE ) );
4393 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
4394
4395 size_t i( 0UL );
4396 Iterator left( begin() );
4397 ConstIterator_t<VT2> right( (*rhs).begin() );
4398
4399 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4400 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4401 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4402 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4403 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4404 }
4405 for( ; i<ipos; i+=SIMDSIZE ) {
4406 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4407 }
4408 for( ; i<size(); ++i ) {
4409 *left += *right; ++left; ++right;
4410 }
4411}
4413//*************************************************************************************************
4414
4415
4416//*************************************************************************************************
4428template< typename VT // Type of the dense vector
4429 , bool TF // Transpose flag
4430 , size_t... CSAs > // Compile time subvector arguments
4431template< typename VT2 > // Type of the right-hand side sparse vector
4432inline void Subvector<VT,aligned,TF,true,CSAs...>::addAssign( const SparseVector<VT2,TF>& rhs )
4433{
4434 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4435
4436 for( ConstIterator_t<VT2> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
4437 vector_[offset()+element->index()] += element->value();
4438}
4440//*************************************************************************************************
4441
4442
4443//*************************************************************************************************
4455template< typename VT // Type of the dense vector
4456 , bool TF // Transpose flag
4457 , size_t... CSAs > // Compile time subvector arguments
4458template< typename VT2 > // Type of the right-hand side dense vector
4459inline auto Subvector<VT,aligned,TF,true,CSAs...>::subAssign( const DenseVector<VT2,TF>& rhs )
4460 -> DisableIf_t< VectorizedSubAssign_v<VT2> >
4461{
4462 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4463
4464 const size_t ipos( prevMultiple( size(), 2UL ) );
4465 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
4466
4467 for( size_t i=0UL; i<ipos; i+=2UL ) {
4468 vector_[offset()+i ] -= (*rhs)[i ];
4469 vector_[offset()+i+1UL] -= (*rhs)[i+1UL];
4470 }
4471 if( ipos < size() ) {
4472 vector_[offset()+ipos] -= (*rhs)[ipos];
4473 }
4474}
4476//*************************************************************************************************
4477
4478
4479//*************************************************************************************************
4491template< typename VT // Type of the dense vector
4492 , bool TF // Transpose flag
4493 , size_t... CSAs > // Compile time subvector arguments
4494template< typename VT2 > // Type of the right-hand side dense vector
4495inline auto Subvector<VT,aligned,TF,true,CSAs...>::subAssign( const DenseVector<VT2,TF>& rhs )
4496 -> EnableIf_t< VectorizedSubAssign_v<VT2> >
4497{
4499
4500 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4501
4502 const size_t ipos( prevMultiple( size(), SIMDSIZE ) );
4503 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
4504
4505 size_t i( 0UL );
4506 Iterator left( begin() );
4507 ConstIterator_t<VT2> right( (*rhs).begin() );
4508
4509 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4510 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4511 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4512 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4513 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4514 }
4515 for( ; i<ipos; i+=SIMDSIZE ) {
4516 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4517 }
4518 for( ; i<size(); ++i ) {
4519 *left -= *right; ++left; ++right;
4520 }
4521}
4523//*************************************************************************************************
4524
4525
4526//*************************************************************************************************
4538template< typename VT // Type of the dense vector
4539 , bool TF // Transpose flag
4540 , size_t... CSAs > // Compile time subvector arguments
4541template< typename VT2 > // Type of the right-hand side sparse vector
4542inline void Subvector<VT,aligned,TF,true,CSAs...>::subAssign( const SparseVector<VT2,TF>& rhs )
4543{
4544 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4545
4546 for( ConstIterator_t<VT2> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
4547 vector_[offset()+element->index()] -= element->value();
4548}
4550//*************************************************************************************************
4551
4552
4553//*************************************************************************************************
4565template< typename VT // Type of the dense vector
4566 , bool TF // Transpose flag
4567 , size_t... CSAs > // Compile time subvector arguments
4568template< typename VT2 > // Type of the right-hand side dense vector
4569inline auto Subvector<VT,aligned,TF,true,CSAs...>::multAssign( const DenseVector<VT2,TF>& rhs )
4570 -> DisableIf_t< VectorizedMultAssign_v<VT2> >
4571{
4572 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4573
4574 const size_t ipos( prevMultiple( size(), 2UL ) );
4575 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
4576
4577 for( size_t i=0UL; i<ipos; i+=2UL ) {
4578 vector_[offset()+i ] *= (*rhs)[i ];
4579 vector_[offset()+i+1UL] *= (*rhs)[i+1UL];
4580 }
4581 if( ipos < size() ) {
4582 vector_[offset()+ipos] *= (*rhs)[ipos];
4583 }
4584}
4586//*************************************************************************************************
4587
4588
4589//*************************************************************************************************
4601template< typename VT // Type of the dense vector
4602 , bool TF // Transpose flag
4603 , size_t... CSAs > // Compile time subvector arguments
4604template< typename VT2 > // Type of the right-hand side dense vector
4605inline auto Subvector<VT,aligned,TF,true,CSAs...>::multAssign( const DenseVector<VT2,TF>& rhs )
4606 -> EnableIf_t< VectorizedMultAssign_v<VT2> >
4607{
4609
4610 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4611
4612 const size_t ipos( prevMultiple( size(), SIMDSIZE ) );
4613 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
4614
4615 size_t i( 0UL );
4616 Iterator left( begin() );
4617 ConstIterator_t<VT2> right( (*rhs).begin() );
4618
4619 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4620 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4621 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4622 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4623 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4624 }
4625 for( ; i<ipos; i+=SIMDSIZE ) {
4626 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4627 }
4628 for( ; i<size(); ++i ) {
4629 *left *= *right; ++left; ++right;
4630 }
4631}
4633//*************************************************************************************************
4634
4635
4636//*************************************************************************************************
4648template< typename VT // Type of the dense vector
4649 , bool TF // Transpose flag
4650 , size_t... CSAs > // Compile time subvector arguments
4651template< typename VT2 > // Type of the right-hand side sparse vector
4652inline void Subvector<VT,aligned,TF,true,CSAs...>::multAssign( const SparseVector<VT2,TF>& rhs )
4653{
4654 using blaze::reset;
4655
4656 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4657
4658 size_t i( 0UL );
4659
4660 for( ConstIterator_t<VT2> element=(*rhs).begin(); element!=(*rhs).end(); ++element ) {
4661 const size_t index( element->index() );
4662 for( ; i<index; ++i )
4663 reset( vector_[offset()+i] );
4664 vector_[offset()+i] *= element->value();
4665 ++i;
4666 }
4667
4668 for( ; i<size(); ++i ) {
4669 reset( vector_[offset()+i] );
4670 }
4671}
4673//*************************************************************************************************
4674
4675
4676//*************************************************************************************************
4688template< typename VT // Type of the dense vector
4689 , bool TF // Transpose flag
4690 , size_t... CSAs > // Compile time subvector arguments
4691template< typename VT2 > // Type of the right-hand side dense vector
4692inline auto Subvector<VT,aligned,TF,true,CSAs...>::divAssign( const DenseVector<VT2,TF>& rhs )
4693 -> DisableIf_t< VectorizedDivAssign_v<VT2> >
4694{
4695 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4696
4697 const size_t ipos( prevMultiple( size(), 2UL ) );
4698 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
4699
4700 for( size_t i=0UL; i<ipos; i+=2UL ) {
4701 vector_[offset()+i ] /= (*rhs)[i ];
4702 vector_[offset()+i+1UL] /= (*rhs)[i+1UL];
4703 }
4704 if( ipos < size() ) {
4705 vector_[offset()+ipos] /= (*rhs)[ipos];
4706 }
4707}
4709//*************************************************************************************************
4710
4711
4712//*************************************************************************************************
4724template< typename VT // Type of the dense vector
4725 , bool TF // Transpose flag
4726 , size_t... CSAs > // Compile time subvector arguments
4727template< typename VT2 > // Type of the right-hand side dense vector
4728inline auto Subvector<VT,aligned,TF,true,CSAs...>::divAssign( const DenseVector<VT2,TF>& rhs )
4729 -> EnableIf_t< VectorizedDivAssign_v<VT2> >
4730{
4732
4733 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4734
4735 const size_t ipos( prevMultiple( size(), SIMDSIZE ) );
4736 BLAZE_INTERNAL_ASSERT( ipos <= size(), "Invalid end calculation" );
4737
4738 size_t i( 0UL );
4739 Iterator left( begin() );
4740 ConstIterator_t<VT2> right( (*rhs).begin() );
4741
4742 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4743 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4744 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4745 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4746 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4747 }
4748 for( ; i<ipos; i+=SIMDSIZE ) {
4749 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4750 }
4751 for( ; i<size(); ++i ) {
4752 *left /= *right; ++left; ++right;
4753 }
4754}
4756//*************************************************************************************************
4757
4758
4759
4760
4761
4762
4763
4764
4765//=================================================================================================
4766//
4767// CLASS TEMPLATE SPECIALIZATION FOR DVECDVECCROSSEXPR
4768//
4769//=================================================================================================
4770
4771//*************************************************************************************************
4779template< typename VT1 // Type of the left-hand side dense vector
4780 , typename VT2 // Type of the right-hand side dense vector
4781 , bool TF // Transpose flag
4782 , size_t... CSAs > // Compile time subvector arguments
4783class Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >
4784 : public View< DenseVector< Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >, TF > >
4785 , private SubvectorData<CSAs...>
4786{
4787 private:
4788 //**Type definitions****************************************************************************
4789 using CPE = DVecDVecCrossExpr<VT1,VT2,TF>;
4790 using RT = ResultType_t<CPE>;
4791 using DataType = SubvectorData<CSAs...>;
4792 //**********************************************************************************************
4793
4794 public:
4795 //**Type definitions****************************************************************************
4797 using This = Subvector<CPE,unaligned,TF,true,CSAs...>;
4798
4799 using BaseType = View< DenseVector<This,TF> >;
4800 using ViewedType = CPE;
4801 using ResultType = SubvectorTrait_t<RT,CSAs...>;
4802 using TransposeType = TransposeType_t<ResultType>;
4803 using ElementType = ElementType_t<CPE>;
4804 using ReturnType = ReturnType_t<CPE>;
4805 using CompositeType = const ResultType;
4806 //**********************************************************************************************
4807
4808 //**Compilation flags***************************************************************************
4810 static constexpr bool simdEnabled = false;
4811
4813 static constexpr bool smpAssignable = false;
4814
4816 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
4817 //**********************************************************************************************
4818
4819 //**Constructor*********************************************************************************
4826 template< typename... RSAs > // Optional subvector arguments
4827 explicit inline Subvector( const CPE& vector, RSAs... args )
4828 : DataType( args... ) // Base class initialization
4829 , vector_ ( vector ) // The dense vector/dense vector cross product expression
4830 {
4831 if( isChecked( args... ) ) {
4832 if( offset() + size() > vector.size() ) {
4833 BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
4834 }
4835 }
4836 else {
4837 BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
4838 }
4839 }
4840 //**********************************************************************************************
4841
4842 //**Subscript operator**************************************************************************
4848 inline ReturnType operator[]( size_t index ) const {
4849 BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
4850 return vector_[offset()+index];
4851 }
4852 //**********************************************************************************************
4853
4854 //**At function*********************************************************************************
4861 inline ReturnType at( size_t index ) const {
4862 if( index >= size() ) {
4863 BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
4864 }
4865 return (*this)[index];
4866 }
4867 //**********************************************************************************************
4868
4869 //**********************************************************************************************
4870 using DataType::offset;
4871 using DataType::size;
4872 //**********************************************************************************************
4873
4874 //**Operand access******************************************************************************
4879 inline CPE operand() const noexcept {
4880 return vector_;
4881 }
4882 //**********************************************************************************************
4883
4884 //**********************************************************************************************
4890 template< typename T >
4891 inline bool canAlias( const T* alias ) const noexcept {
4892 return vector_.canAlias( &unview( *alias ) );
4893 }
4894 //**********************************************************************************************
4895
4896 //**********************************************************************************************
4902 template< typename T >
4903 inline bool isAliased( const T* alias ) const noexcept {
4904 return vector_.isAliased( &unview( *alias ) );
4905 }
4906 //**********************************************************************************************
4907
4908 private:
4909 //**Member variables****************************************************************************
4910 CPE vector_;
4911 //**********************************************************************************************
4912};
4914//*************************************************************************************************
4915
4916
4917
4918
4919
4920
4921
4922
4923//=================================================================================================
4924//
4925// CLASS TEMPLATE SPECIALIZATION FOR DVECSVECCROSSEXPR
4926//
4927//=================================================================================================
4928
4929//*************************************************************************************************
4937template< typename VT1 // Type of the left-hand side dense vector
4938 , typename VT2 // Type of the right-hand side sparse vector
4939 , bool TF // Transpose flag
4940 , size_t... CSAs > // Compile time subvector arguments
4941class Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >
4942 : public View< DenseVector< Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >, TF > >
4943 , private SubvectorData<CSAs...>
4944{
4945 private:
4946 //**Type definitions****************************************************************************
4947 using CPE = DVecSVecCrossExpr<VT1,VT2,TF>;
4948 using RT = ResultType_t<CPE>;
4949 using DataType = SubvectorData<CSAs...>;
4950 //**********************************************************************************************
4951
4952 public:
4953 //**Type definitions****************************************************************************
4955 using This = Subvector<CPE,unaligned,TF,true,CSAs...>;
4956
4957 using BaseType = View< DenseVector<This,TF> >;
4958 using ViewedType = CPE;
4959 using ResultType = SubvectorTrait_t<RT,CSAs...>;
4960 using TransposeType = TransposeType_t<ResultType>;
4961 using ElementType = ElementType_t<CPE>;
4962 using ReturnType = ReturnType_t<CPE>;
4963 using CompositeType = const ResultType;
4964 //**********************************************************************************************
4965
4966 //**Compilation flags***************************************************************************
4968 static constexpr bool simdEnabled = false;
4969
4971 static constexpr bool smpAssignable = false;
4972
4974 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
4975 //**********************************************************************************************
4976
4977 //**Constructor*********************************************************************************
4984 template< typename... RSAs > // Optional subvector arguments
4985 explicit inline Subvector( const CPE& vector, RSAs... args )
4986 : DataType( args... ) // Base class initialization
4987 , vector_ ( vector ) // The dense vector/sparse vector cross product expression
4988 {
4989 if( isChecked( args... ) ) {
4990 if( offset() + size() > vector.size() ) {
4991 BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
4992 }
4993 }
4994 else {
4995 BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
4996 }
4997 }
4998 //**********************************************************************************************
4999
5000 //**Subscript operator**************************************************************************
5006 inline ReturnType operator[]( size_t index ) const {
5007 BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
5008 return vector_[offset()+index];
5009 }
5010 //**********************************************************************************************
5011
5012 //**At function*********************************************************************************
5019 inline ReturnType at( size_t index ) const {
5020 if( index >= size() ) {
5021 BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
5022 }
5023 return (*this)[index];
5024 }
5025 //**********************************************************************************************
5026
5027 //**********************************************************************************************
5028 using DataType::offset;
5029 using DataType::size;
5030 //**********************************************************************************************
5031
5032 //**Operand access******************************************************************************
5037 inline CPE operand() const noexcept {
5038 return vector_;
5039 }
5040 //**********************************************************************************************
5041
5042 //**********************************************************************************************
5048 template< typename T >
5049 inline bool canAlias( const T* alias ) const noexcept {
5050 return vector_.canAlias( &unview( *alias ) );
5051 }
5052 //**********************************************************************************************
5053
5054 //**********************************************************************************************
5060 template< typename T >
5061 inline bool isAliased( const T* alias ) const noexcept {
5062 return vector_.isAliased( &unview( *alias ) );
5063 }
5064 //**********************************************************************************************
5065
5066 private:
5067 //**Member variables****************************************************************************
5068 CPE vector_;
5069 //**********************************************************************************************
5070};
5072//*************************************************************************************************
5073
5074
5075
5076
5077
5078
5079
5080
5081//=================================================================================================
5082//
5083// CLASS TEMPLATE SPECIALIZATION FOR SVECDVECCROSSEXPR
5084//
5085//=================================================================================================
5086
5087//*************************************************************************************************
5095template< typename VT1 // Type of the left-hand side sparse vector
5096 , typename VT2 // Type of the right-hand side dense vector
5097 , bool TF // Transpose flag
5098 , size_t... CSAs > // Compile time subvector arguments
5099class Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >
5100 : public View< DenseVector< Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >, TF > >
5101 , private SubvectorData<CSAs...>
5102{
5103 private:
5104 //**Type definitions****************************************************************************
5105 using CPE = SVecDVecCrossExpr<VT1,VT2,TF>;
5106 using RT = ResultType_t<CPE>;
5107 using DataType = SubvectorData<CSAs...>;
5108 //**********************************************************************************************
5109
5110 public:
5111 //**Type definitions****************************************************************************
5113 using This = Subvector<CPE,unaligned,TF,true,CSAs...>;
5114
5115 using BaseType = View< DenseVector<This,TF> >;
5116 using ViewedType = CPE;
5117 using ResultType = SubvectorTrait_t<RT,CSAs...>;
5118 using TransposeType = TransposeType_t<ResultType>;
5119 using ElementType = ElementType_t<CPE>;
5120 using ReturnType = ReturnType_t<CPE>;
5121 using CompositeType = const ResultType;
5122 //**********************************************************************************************
5123
5124 //**Compilation flags***************************************************************************
5126 static constexpr bool simdEnabled = false;
5127
5129 static constexpr bool smpAssignable = false;
5130
5132 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
5133 //**********************************************************************************************
5134
5135 //**Constructor*********************************************************************************
5142 template< typename... RSAs > // Optional subvector arguments
5143 explicit inline Subvector( const CPE& vector, RSAs... args )
5144 : DataType( args... ) // Base class initialization
5145 , vector_ ( vector ) // The sparse vector/dense vector cross product expression
5146 {
5147 if( isChecked( args... ) ) {
5148 if( offset() + size() > vector.size() ) {
5149 BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
5150 }
5151 }
5152 else {
5153 BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
5154 }
5155 }
5156 //**********************************************************************************************
5157
5158 //**Subscript operator**************************************************************************
5164 inline ReturnType operator[]( size_t index ) const {
5165 BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
5166 return vector_[offset()+index];
5167 }
5168 //**********************************************************************************************
5169
5170 //**At function*********************************************************************************
5177 inline ReturnType at( size_t index ) const {
5178 if( index >= size() ) {
5179 BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
5180 }
5181 return (*this)[index];
5182 }
5183 //**********************************************************************************************
5184
5185 //**********************************************************************************************
5186 using DataType::offset;
5187 using DataType::size;
5188 //**********************************************************************************************
5189
5190 //**Operand access******************************************************************************
5195 inline CPE operand() const noexcept {
5196 return vector_;
5197 }
5198 //**********************************************************************************************
5199
5200 //**********************************************************************************************
5206 template< typename T >
5207 inline bool canAlias( const T* alias ) const noexcept {
5208 return vector_.canAlias( &unview( *alias ) );
5209 }
5210 //**********************************************************************************************
5211
5212 //**********************************************************************************************
5218 template< typename T >
5219 inline bool isAliased( const T* alias ) const noexcept {
5220 return vector_.isAliased( &unview( *alias ) );
5221 }
5222 //**********************************************************************************************
5223
5224 private:
5225 //**Member variables****************************************************************************
5226 CPE vector_;
5227 //**********************************************************************************************
5228};
5230//*************************************************************************************************
5231
5232
5233
5234
5235
5236
5237
5238
5239//=================================================================================================
5240//
5241// CLASS TEMPLATE SPECIALIZATION FOR SVECSVECCROSSEXPR
5242//
5243//=================================================================================================
5244
5245//*************************************************************************************************
5253template< typename VT1 // Type of the left-hand side sparse vector
5254 , typename VT2 // Type of the right-hand side sparse vector
5255 , bool TF // Transpose flag
5256 , size_t... CSAs > // Compile time subvector arguments
5257class Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >
5258 : public View< DenseVector< Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true, CSAs... >, TF > >
5259 , private SubvectorData<CSAs...>
5260{
5261 private:
5262 //**Type definitions****************************************************************************
5263 using CPE = SVecSVecCrossExpr<VT1,VT2,TF>;
5264 using RT = ResultType_t<CPE>;
5265 using DataType = SubvectorData<CSAs...>;
5266 //**********************************************************************************************
5267
5268 public:
5269 //**Type definitions****************************************************************************
5271 using This = Subvector<CPE,unaligned,TF,true,CSAs...>;
5272
5273 using BaseType = View< DenseVector<This,TF> >;
5274 using ViewedType = CPE;
5275 using ResultType = SubvectorTrait_t<RT,CSAs...>;
5276 using TransposeType = TransposeType_t<ResultType>;
5277 using ElementType = ElementType_t<CPE>;
5278 using ReturnType = ReturnType_t<CPE>;
5279 using CompositeType = const ResultType;
5280 //**********************************************************************************************
5281
5282 //**Compilation flags***************************************************************************
5284 static constexpr bool simdEnabled = false;
5285
5287 static constexpr bool smpAssignable = false;
5288
5290 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
5291 //**********************************************************************************************
5292
5293 //**Constructor*********************************************************************************
5300 template< typename... RSAs > // Optional subvector arguments
5301 explicit inline Subvector( const CPE& vector, RSAs... args )
5302 : DataType( args... ) // Base class initialization
5303 , vector_ ( vector ) // The sparse vector/sparse vector cross product expression
5304 {
5305 if( isChecked( args... ) ) {
5306 if( offset() + size() > vector.size() ) {
5307 BLAZE_THROW_INVALID_ARGUMENT( "Invalid subvector specification" );
5308 }
5309 }
5310 else {
5311 BLAZE_USER_ASSERT( offset() + size() <= vector.size(), "Invalid subvector specification" );
5312 }
5313 }
5314 //**********************************************************************************************
5315
5316 //**Subscript operator**************************************************************************
5322 inline ReturnType operator[]( size_t index ) const {
5323 BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
5324 return vector_[offset()+index];
5325 }
5326 //**********************************************************************************************
5327
5328 //**At function*********************************************************************************
5335 inline ReturnType at( size_t index ) const {
5336 if( index >= size() ) {
5337 BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
5338 }
5339 return (*this)[index];
5340 }
5341 //**********************************************************************************************
5342
5343 //**********************************************************************************************
5344 using DataType::offset;
5345 using DataType::size;
5346 //**********************************************************************************************
5347
5348 //**Operand access******************************************************************************
5353 inline CPE operand() const noexcept {
5354 return vector_;
5355 }
5356 //**********************************************************************************************
5357
5358 //**********************************************************************************************
5364 template< typename T >
5365 inline bool canAlias( const T* alias ) const noexcept {
5366 return vector_.canAlias( &unview( *alias ) );
5367 }
5368 //**********************************************************************************************
5369
5370 //**********************************************************************************************
5376 template< typename T >
5377 inline bool isAliased( const T* alias ) const {
5378 return vector_.isAliased( &unview( *alias ) );
5379 }
5380 //**********************************************************************************************
5381
5382 private:
5383 //**Member variables****************************************************************************
5384 CPE vector_;
5385 //**********************************************************************************************
5386};
5388//*************************************************************************************************
5389
5390} // namespace blaze
5391
5392#endif
Header file for auxiliary alias declarations.
Header file for the alignment check function.
Header file for the alignment flag enumeration.
Header file for run time assertion macros.
Header file for the blaze::checked and blaze::unchecked instances.
Header file for the cross product trait.
constexpr 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:751
constexpr 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:719
Header file for the EnableIf class template.
Header file for the HasMutableDataAccess type trait.
Header file for the HasSIMDAdd type trait.
Header file for the HasSIMDDiv type trait.
Header file for the HasSIMDMult type trait.
Header file for the HasSIMDSub type trait.
Macro for CUDA compatibility.
Header file for the If class template.
Header file for the IsConst type trait.
Header file for the IsContiguous type trait.
Header file for the isDefault shim.
Header file for the IsExpression type trait class.
Header file for the IsRestricted type trait.
Header file for the IsSIMDCombinable type trait.
Header file for the IsSparseVector type trait.
Deactivation of problematic macros.
Header file for the prevMultiple shim.
Header file for all SIMD functionality.
Header file for the implementation of the SubvectorData class template.
Header file for the subvector trait.
Constraint on the data type.
Initializer list type of the Blaze library.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Header file for the implementation of a vector representation of an initializer list.
Header file for the Computation base class.
Header file for the CrossExpr base class.
Header file for the DenseVector base class.
Header file for the View base class.
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.
Definition: Vectorizable.h:61
auto operator/=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Division assignment operator for the division of a dense matrix by a scalar value ( ).
Definition: DenseMatrix.h:574
MT::ElementType * data(DenseMatrix< MT, SO > &dm) noexcept
Low-level data access to the dense matrix elements.
Definition: DenseMatrix.h:182
auto operator+=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Addition assignment operator for the addition of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:386
auto operator*=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:510
size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:265
decltype(auto) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:9640
auto operator-=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Subtraction assignment operator for the subtraction of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:448
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:207
bool isDefault(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the given diagonal matrix is in default state.
Definition: DiagonalMatrix.h:169
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.
Definition: RequiresEvaluation.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.
Definition: TransExpr.h:81
#define BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG(T, TF)
Constraint on the data type.
Definition: TransposeFlag.h:63
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.
Definition: Computation.h:81
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.
Definition: DenseVector.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBVECTOR_TYPE(T)
Constraint on the data type.
Definition: Subvector.h:81
typename SubvectorTrait< VT, CSAs... >::Type SubvectorTrait_t
Auxiliary alias declaration for the SubvectorTrait type trait.
Definition: SubvectorTrait.h:145
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.
Definition: HasSIMDSub.h:187
constexpr bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.
Definition: IsSIMDCombinable.h:137
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.
Definition: HasSIMDAdd.h:187
constexpr bool HasSIMDDiv_v
Auxiliary variable template for the HasSIMDDiv type trait.
Definition: HasSIMDDiv.h:173
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.
Definition: HasSIMDMult.h:188
constexpr bool IsContiguous_v
Auxiliary variable template for the IsContiguous type trait.
Definition: IsContiguous.h:144
BLAZE_ALWAYS_INLINE constexpr auto prevMultiple(T1 value, T2 factor) noexcept
Rounds down an integral value to the previous multiple of a given factor.
Definition: PrevMultiple.h:68
constexpr bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:370
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:253
AlignmentFlag
Alignment flag for (un-)aligned vectors and matrices.
Definition: AlignmentFlag.h:63
constexpr bool operator<(const NegativeAccuracy< A > &lhs, const T &rhs)
Less-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:332
constexpr bool operator>=(const NegativeAccuracy< A > &, const T &rhs)
Greater-or-equal-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:446
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:293
constexpr bool operator<=(const NegativeAccuracy< A > &, const T &rhs)
Less-or-equal-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:408
@ unaligned
Flag for unaligned vectors and matrices.
Definition: AlignmentFlag.h:64
@ aligned
Flag for aligned vectors and matrices.
Definition: AlignmentFlag.h:65
constexpr void clear(Matrix< MT, SO > &matrix)
Clearing the given matrix.
Definition: Matrix.h:960
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:628
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:730
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:562
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:692
constexpr void reset(Matrix< MT, SO > &matrix)
Resetting the given matrix.
Definition: Matrix.h:806
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:584
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:518
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:676
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.
Definition: Assert.h:117
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:78
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:75
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< 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:74
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:76
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:79
auto smpDivAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP division assignment of a vector to a dense vector.
Definition: DenseVector.h:221
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
auto smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP multiplication assignment of a vector to a dense vector.
Definition: DenseVector.h:192
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
#define BLAZE_DEVICE_CALLABLE
Conditional macro that sets host and device attributes when compiled with CUDA.
Definition: HostDevice.h:94
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:138
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.
Definition: Exception.h:331
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.
Definition: Exception.h:235
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
typename EnableIf<!Condition, T >::Type DisableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:175
constexpr bool isChecked(const Ts &... args)
Extracting blaze::Check arguments from a given list of arguments.
Definition: Check.h:225
Header file for the exception macros of the math module.
Header file for the extended initializer_list functionality.
Constraint on the data type.
Header file for all forward declarations for expression class templates.
Header file for the clear shim.
Header file for the reset shim.
Header file for the cache size of the target architecture.
System settings for the inline keywords.
System settings for performance optimizations.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
Header file for basic type definitions.
Header file for the implementation of the Subvector base template.