35 #ifndef _BLAZE_MATH_VIEWS_SUBVECTOR_DENSE_H_ 36 #define _BLAZE_MATH_VIEWS_SUBVECTOR_DENSE_H_ 106 template<
typename VT
109 :
public DenseVector< Subvector<VT,unaligned,TF,true>, TF >
115 typedef If_< IsExpression<VT>, VT, VT& > Operand;
120 typedef Subvector<VT,unaligned,TF,true>
This;
121 typedef DenseVector<This,TF>
BaseType;
125 typedef SIMDTrait_<ElementType> SIMDType;
136 typedef const ElementType* ConstPointer;
139 typedef If_< Or< IsConst<VT>, Not< HasMutableDataAccess<VT> > >, ConstPointer, ElementType* > Pointer;
145 template<
typename IteratorType >
146 class SubvectorIterator
151 typedef typename std::iterator_traits<IteratorType>::iterator_category IteratorCategory;
154 typedef typename std::iterator_traits<IteratorType>::value_type ValueType;
157 typedef typename std::iterator_traits<IteratorType>::pointer PointerType;
160 typedef typename std::iterator_traits<IteratorType>::reference ReferenceType;
163 typedef typename std::iterator_traits<IteratorType>::difference_type DifferenceType;
166 typedef IteratorCategory iterator_category;
167 typedef ValueType value_type;
168 typedef PointerType pointer;
169 typedef ReferenceType reference;
170 typedef DifferenceType difference_type;
176 inline SubvectorIterator()
178 , isAligned_( false )
188 inline SubvectorIterator( IteratorType iterator,
bool isMemoryAligned )
189 : iterator_ ( iterator )
190 , isAligned_( isMemoryAligned )
199 template<
typename IteratorType2 >
200 inline SubvectorIterator(
const SubvectorIterator<IteratorType2>& it )
201 : iterator_ ( it.base() )
202 , isAligned_( it.isAligned() )
212 inline SubvectorIterator&
operator+=(
size_t inc ) {
224 inline SubvectorIterator&
operator-=(
size_t dec ) {
235 inline SubvectorIterator& operator++() {
246 inline const SubvectorIterator operator++(
int ) {
247 return SubvectorIterator( iterator_++, isAligned_ );
256 inline SubvectorIterator& operator--() {
267 inline const SubvectorIterator operator--(
int ) {
268 return SubvectorIterator( iterator_--, isAligned_ );
292 inline SIMDType load()
const {
307 inline SIMDType
loada()
const {
308 return iterator_.loada();
322 inline SIMDType
loadu()
const {
324 return iterator_.loada();
327 return iterator_.loadu();
343 inline void store(
const SIMDType& value )
const {
359 inline void storea(
const SIMDType& value )
const {
360 iterator_.storea( value );
375 inline void storeu(
const SIMDType& value )
const {
377 iterator_.storea( value );
380 iterator_.storeu( value );
396 inline void stream(
const SIMDType& value )
const {
397 iterator_.stream( value );
407 inline bool operator==(
const SubvectorIterator& rhs )
const {
408 return iterator_ == rhs.iterator_;
418 inline bool operator!=(
const SubvectorIterator& rhs )
const {
419 return iterator_ != rhs.iterator_;
429 inline bool operator<(
const SubvectorIterator& rhs )
const {
430 return iterator_ < rhs.iterator_;
440 inline bool operator>(
const SubvectorIterator& rhs )
const {
441 return iterator_ > rhs.iterator_;
451 inline bool operator<=(
const SubvectorIterator& rhs )
const {
452 return iterator_ <= rhs.iterator_;
462 inline bool operator>=(
const SubvectorIterator& rhs )
const {
463 return iterator_ >= rhs.iterator_;
473 inline DifferenceType
operator-(
const SubvectorIterator& rhs )
const {
474 return iterator_ - rhs.iterator_;
485 friend inline const SubvectorIterator
operator+(
const SubvectorIterator& it,
size_t inc ) {
486 return SubvectorIterator( it.iterator_ + inc, it.isAligned_ );
497 friend inline const SubvectorIterator
operator+(
size_t inc,
const SubvectorIterator& it ) {
498 return SubvectorIterator( it.iterator_ + inc, it.isAligned_ );
509 friend inline const SubvectorIterator
operator-(
const SubvectorIterator& it,
size_t dec ) {
510 return SubvectorIterator( it.iterator_ - dec, it.isAligned_ );
519 inline IteratorType base()
const {
529 inline bool isAligned()
const {
536 IteratorType iterator_;
544 typedef SubvectorIterator< ConstIterator_<VT> >
ConstIterator;
552 enum :
bool { simdEnabled = VT::simdEnabled };
555 enum :
bool { smpAssignable = VT::smpAssignable };
561 explicit inline Subvector( Operand vector,
size_t index,
size_t n );
573 inline Reference operator[](
size_t index );
574 inline ConstReference operator[](
size_t index )
const;
575 inline Reference at(
size_t index );
576 inline ConstReference at(
size_t index )
const;
577 inline Pointer data () noexcept;
578 inline ConstPointer data () const noexcept;
579 inline Iterator
begin ();
580 inline ConstIterator begin () const;
581 inline ConstIterator
cbegin() const;
582 inline Iterator
end ();
583 inline ConstIterator end () const;
584 inline ConstIterator
cend () const;
591 inline Subvector& operator= ( const ElementType& rhs );
592 inline Subvector& operator= ( initializer_list<ElementType> list );
593 inline Subvector& operator= ( const Subvector& rhs );
594 template< typename VT2 > inline Subvector& operator= ( const Vector<VT2,TF>& rhs );
595 template< typename VT2 > inline Subvector& operator+=( const Vector<VT2,TF>& rhs );
596 template< typename VT2 > inline Subvector& operator-=( const Vector<VT2,TF>& rhs );
597 template< typename VT2 > inline Subvector& operator*=( const DenseVector<VT2,TF>& rhs );
598 template< typename VT2 > inline Subvector& operator*=( const SparseVector<VT2,TF>& rhs );
599 template< typename VT2 > inline Subvector& operator/=( const DenseVector<VT2,TF>& rhs );
601 template< typename Other >
602 inline
EnableIf_< IsNumeric<Other>, Subvector >& operator*=( Other rhs );
604 template< typename Other >
605 inline
EnableIf_< IsNumeric<Other>, Subvector >& operator/=( Other rhs );
612 inline
size_t size() const noexcept;
613 inline
size_t capacity() const noexcept;
622 template< typename Other > inline Subvector& scale( const Other& scalar );
629 template< typename VT2 >
630 struct VectorizedAssign {
632 simdEnabled && VT2::simdEnabled &&
633 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value };
639 template<
typename VT2 >
640 struct VectorizedAddAssign {
642 simdEnabled && VT2::simdEnabled &&
643 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
644 HasSIMDAdd< ElementType, ElementType_<VT2> >::value };
650 template<
typename VT2 >
651 struct VectorizedSubAssign {
653 simdEnabled && VT2::simdEnabled &&
654 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
655 HasSIMDSub< ElementType, ElementType_<VT2> >::value };
661 template<
typename VT2 >
662 struct VectorizedMultAssign {
664 simdEnabled && VT2::simdEnabled &&
665 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
666 HasSIMDMult< ElementType, ElementType_<VT2> >::value };
672 template<
typename VT2 >
673 struct VectorizedDivAssign {
675 simdEnabled && VT2::simdEnabled &&
676 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
677 HasSIMDDiv< ElementType, ElementType_<VT2> >::value };
690 template<
typename Other >
691 inline bool canAlias(
const Other* alias )
const noexcept;
693 template<
typename VT2,
bool AF2,
bool TF2 >
694 inline bool canAlias(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept;
696 template<
typename Other >
697 inline bool isAliased(
const Other* alias )
const noexcept;
699 template<
typename VT2,
bool AF2,
bool TF2 >
700 inline bool isAliased(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept;
702 inline bool isAligned () const noexcept;
703 inline
bool canSMPAssign() const noexcept;
714 template< typename VT2 >
715 inline
DisableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
717 template< typename VT2 >
718 inline
EnableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
720 template< typename VT2 > inline
void assign( const SparseVector<VT2,TF>& rhs );
722 template< typename VT2 >
723 inline
DisableIf_< VectorizedAddAssign<VT2> > addAssign( const DenseVector <VT2,TF>& rhs );
725 template< typename VT2 >
726 inline
EnableIf_< VectorizedAddAssign<VT2> > addAssign ( const DenseVector <VT2,TF>& rhs );
728 template< typename VT2 > inline
void addAssign( const SparseVector<VT2,TF>& rhs );
730 template< typename VT2 >
731 inline
DisableIf_< VectorizedSubAssign<VT2> > subAssign ( const DenseVector <VT2,TF>& rhs );
733 template< typename VT2 >
734 inline
EnableIf_< VectorizedSubAssign<VT2> > subAssign( const DenseVector <VT2,TF>& rhs );
736 template< typename VT2 > inline
void subAssign( const SparseVector<VT2,TF>& rhs );
738 template< typename VT2 >
739 inline
DisableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
741 template< typename VT2 >
742 inline
EnableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
744 template< typename VT2 > inline
void multAssign( const SparseVector<VT2,TF>& rhs );
746 template< typename VT2 >
747 inline
DisableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
749 template< typename VT2 >
750 inline
EnableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
759 const
size_t offset_;
761 const
bool isAligned_;
772 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 > friend class Subvector;
774 template<
bool AF1, typename VT2,
bool AF2,
bool TF2,
bool DF2 >
775 friend const Subvector<VT2,AF1,TF2,DF2>
776 subvector( const Subvector<VT2,AF2,TF2,DF2>& sv,
size_t index,
size_t size );
778 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
779 friend
bool isIntact( const Subvector<VT2,AF2,TF2,DF2>& sv ) noexcept;
781 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
782 friend
bool isSame( const Subvector<VT2,AF2,TF2,DF2>& a, const Vector<VT2,TF2>& b ) noexcept;
784 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
785 friend
bool isSame( const Vector<VT2,TF2>& a, const Subvector<VT2,AF2,TF2,DF2>& b ) noexcept;
787 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
788 friend
bool isSame( const Subvector<VT2,AF2,TF2,DF2>& a, const Subvector<VT2,AF2,TF2,DF2>& b ) noexcept;
790 template< typename VT2,
bool AF2,
bool TF2,
bool DF2, typename VT3 >
791 friend
bool tryAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs,
size_t index );
793 template< typename VT2,
bool AF2,
bool TF2,
bool DF2, typename VT3 >
794 friend
bool tryAddAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs,
size_t index );
796 template< typename VT2,
bool AF2,
bool TF2,
bool DF2, typename VT3 >
797 friend
bool trySubAssign( const Subvector<VT2,AF2,DF2,TF2>& lhs, const Vector<VT3,TF2>& rhs,
size_t index );
799 template< typename VT2,
bool AF2,
bool TF2,
bool DF2, typename VT3 >
800 friend
bool tryMultAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs,
size_t index );
802 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
803 friend
DerestrictTrait_< Subvector<VT2,AF2,TF2,DF2> > derestrict( Subvector<VT2,AF2,TF2,DF2>& sv );
839 template< typename VT
841 inline Subvector<VT,
unaligned,TF,true>::Subvector( Operand vector,
size_t index,
size_t n )
845 , isAligned_( simdEnabled && vector.data() !=
nullptr &&
checkAlignment( data() ) )
847 if( index + n > vector.size() ) {
873 template<
typename VT
876 Subvector<VT,unaligned,TF,true>::operator[](
size_t index )
879 return vector_[offset_+index];
895 template<
typename VT
898 Subvector<VT,unaligned,TF,true>::operator[](
size_t index )
const 901 return const_cast<const VT&
>( vector_ )[offset_+index];
918 template<
typename VT
921 Subvector<VT,unaligned,TF,true>::at(
size_t index )
923 if( index >=
size() ) {
926 return (*
this)[index];
943 template<
typename VT
946 Subvector<VT,unaligned,TF,true>::at(
size_t index )
const 948 if( index >=
size() ) {
951 return (*
this)[index];
965 template<
typename VT
967 inline typename Subvector<VT,unaligned,TF,true>::Pointer
968 Subvector<VT,unaligned,TF,true>::data() noexcept
970 return vector_.data() + offset_;
984 template<
typename VT
986 inline typename Subvector<VT,unaligned,TF,true>::ConstPointer
987 Subvector<VT,unaligned,TF,true>::data() const noexcept
989 return vector_.data() + offset_;
1003 template<
typename VT
1008 return Iterator( vector_.begin() + offset_, isAligned_ );
1022 template<
typename VT
1027 return ConstIterator( vector_.cbegin() + offset_, isAligned_ );
1041 template<
typename VT
1046 return ConstIterator( vector_.cbegin() + offset_, isAligned_ );
1060 template<
typename VT
1065 return Iterator( vector_.begin() + offset_ + size_, isAligned_ );
1079 template<
typename VT
1084 return ConstIterator( vector_.cbegin() + offset_ + size_, isAligned_ );
1098 template<
typename VT
1103 return ConstIterator( vector_.cbegin() + offset_ + size_, isAligned_ );
1124 template<
typename VT
1126 inline Subvector<VT,unaligned,TF,true>&
1127 Subvector<VT,unaligned,TF,true>::operator=(
const ElementType& rhs )
1129 const size_t iend( offset_ + size_ );
1131 for(
size_t i=offset_; i<iend; ++i )
1153 template<
typename VT
1155 inline Subvector<VT,unaligned,TF,true>&
1156 Subvector<VT,unaligned,TF,true>::operator=( initializer_list<ElementType> list )
1158 if( list.size() >
size() ) {
1184 template<
typename VT
1186 inline Subvector<VT,unaligned,TF,true>&
1187 Subvector<VT,unaligned,TF,true>::operator=(
const Subvector& rhs )
1192 if( &rhs ==
this || ( &vector_ == &rhs.vector_ && offset_ == rhs.offset_ ) )
1195 if(
size() != rhs.size() ) {
1199 if( !tryAssign( vector_, rhs, offset_ ) ) {
1203 DerestrictTrait_<This> left( derestrict( *
this ) );
1205 if( rhs.canAlias( &vector_ ) ) {
1206 const ResultType tmp( rhs );
1233 template<
typename VT
1235 template<
typename VT2 >
1236 inline Subvector<VT,unaligned,TF,true>&
1237 Subvector<VT,unaligned,TF,true>::operator=(
const Vector<VT2,TF>& rhs )
1246 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
1247 Right right( ~rhs );
1249 if( !tryAssign( vector_, right, offset_ ) ) {
1253 DerestrictTrait_<This> left( derestrict( *
this ) );
1255 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1256 const ResultType_<VT2> tmp( right );
1260 if( IsSparseVector<VT2>::value )
1285 template<
typename VT
1287 template<
typename VT2 >
1288 inline Subvector<VT,unaligned,TF,true>&
1298 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
1299 Right right( ~rhs );
1301 if( !tryAddAssign( vector_, right, offset_ ) ) {
1305 DerestrictTrait_<This> left( derestrict( *
this ) );
1307 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1308 const ResultType_<VT2> tmp( right );
1335 template<
typename VT
1337 template<
typename VT2 >
1338 inline Subvector<VT,unaligned,TF,true>&
1348 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
1349 Right right( ~rhs );
1351 if( !trySubAssign( vector_, right, offset_ ) ) {
1355 DerestrictTrait_<This> left( derestrict( *
this ) );
1357 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1358 const ResultType_<VT2> tmp( right );
1386 template<
typename VT
1388 template<
typename VT2 >
1389 inline Subvector<VT,unaligned,TF,true>&
1399 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
1400 Right right( ~rhs );
1402 if( !tryMultAssign( vector_, right, offset_ ) ) {
1406 DerestrictTrait_<This> left( derestrict( *
this ) );
1408 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1409 const ResultType_<VT2> tmp( right );
1437 template<
typename VT
1439 template<
typename VT2 >
1440 inline Subvector<VT,unaligned,TF,true>&
1450 const ResultType tmp( *
this * (~rhs) );
1452 if( !tryAssign( vector_, tmp, offset_ ) ) {
1456 DerestrictTrait_<This> left( derestrict( *
this ) );
1480 template<
typename VT
1482 template<
typename VT2 >
1483 inline Subvector<VT,unaligned,TF,true>&
1493 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
1494 Right right( ~rhs );
1496 if( !tryDivAssign( vector_, right, offset_ ) ) {
1500 DerestrictTrait_<This> left( derestrict( *
this ) );
1502 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1503 const ResultType_<VT2> tmp( right );
1526 template<
typename VT
1528 template<
typename Other >
1529 inline EnableIf_< IsNumeric<Other>, Subvector<VT,unaligned,TF,true> >&
1532 DerestrictTrait_<This> left( derestrict( *
this ) );
1551 template<
typename VT
1553 template<
typename Other >
1554 inline EnableIf_< IsNumeric<Other>, Subvector<VT,unaligned,TF,true> >&
1559 DerestrictTrait_<This> left( derestrict( *
this ) );
1582 template<
typename VT
1598 template<
typename VT
1602 return vector_.capacity() - offset_;
1617 template<
typename VT
1621 size_t nonzeros( 0 );
1623 const size_t iend( offset_ + size_ );
1624 for(
size_t i=offset_; i<iend; ++i ) {
1641 template<
typename VT
1647 const size_t iend( offset_ + size_ );
1648 for(
size_t i=offset_; i<iend; ++i )
1649 clear( vector_[i] );
1670 template<
typename VT
1672 template<
typename Other >
1673 inline Subvector<VT,unaligned,TF,true>&
1674 Subvector<VT,unaligned,TF,true>::scale(
const Other& scalar )
1676 const size_t iend( offset_ + size_ );
1677 for(
size_t i=offset_; i<iend; ++i )
1678 vector_[i] *= scalar;
1704 template<
typename VT
1706 template<
typename Other >
1707 inline bool Subvector<VT,unaligned,TF,true>::canAlias(
const Other* alias )
const noexcept
1709 return vector_.isAliased( alias );
1726 template<
typename VT
1728 template<
typename VT2
1731 inline bool Subvector<VT,unaligned,TF,true>::canAlias(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept
1733 return ( vector_.isAliased( &alias->vector_ ) &&
1734 ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
1751 template<
typename VT
1753 template<
typename Other >
1754 inline bool Subvector<VT,unaligned,TF,true>::isAliased(
const Other* alias )
const noexcept
1756 return vector_.isAliased( alias );
1773 template<
typename VT
1775 template<
typename VT2
1778 inline bool Subvector<VT,unaligned,TF,true>::isAliased(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept
1780 return ( vector_.isAliased( &alias->vector_ ) &&
1781 ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
1797 template<
typename VT
1799 inline bool Subvector<VT,unaligned,TF,true>::isAligned() const noexcept
1818 template<
typename VT
1820 inline bool Subvector<VT,unaligned,TF,true>::canSMPAssign() const noexcept
1822 return (
size() > SMP_DVECASSIGN_THRESHOLD );
1842 template<
typename VT
1845 Subvector<VT,unaligned,TF,true>::load(
size_t index )
const noexcept
1848 return loada( index );
1850 return loadu( index );
1870 template<
typename VT
1881 return vector_.loada( offset_+index );
1901 template<
typename VT
1912 return vector_.loadu( offset_+index );
1933 template<
typename VT
1936 Subvector<VT,unaligned,TF,true>::store(
size_t index,
const SIMDType& value ) noexcept
1962 template<
typename VT
1973 vector_.storea( offset_+index, value );
1994 template<
typename VT
2005 vector_.storeu( offset_+index, value );
2026 template<
typename VT
2038 vector_.stream( offset_+index, value );
2040 vector_.storeu( offset_+index, value );
2058 template<
typename VT
2060 template<
typename VT2 >
2061 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
2062 Subvector<VT,unaligned,TF,true>::assign(
const DenseVector<VT2,TF>& rhs )
2066 const size_t ipos(
size() &
size_t(-2) );
2067 for(
size_t i=0UL; i<ipos; i+=2UL ) {
2068 vector_[offset_+i ] = (~rhs)[i ];
2069 vector_[offset_+i+1UL] = (~rhs)[i+1UL];
2071 if( ipos <
size() ) {
2072 vector_[offset_+ipos] = (~rhs)[ipos];
2091 template<
typename VT
2093 template<
typename VT2 >
2094 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
2095 Subvector<VT,unaligned,TF,true>::assign(
const DenseVector<VT2,TF>& rhs )
2101 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
2105 Iterator left(
begin() );
2106 ConstIterator_<VT2> right( (~rhs).
begin() );
2109 ( size_ > (
cacheSize/(
sizeof(ElementType) * 3UL ) ) ) &&
2110 !(~rhs).isAliased( &vector_ ) )
2112 for( ; i<ipos; i+=SIMDSIZE ) {
2113 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2115 for( ; i<size_; ++i ) {
2121 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2122 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2123 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2124 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2125 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2127 for( ; i<ipos; i+=SIMDSIZE ) {
2128 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2130 for( ; i<size_; ++i ) {
2131 *left = *right; ++left; ++right;
2151 template<
typename VT
2153 template<
typename VT2 >
2154 inline void Subvector<VT,unaligned,TF,true>::assign(
const SparseVector<VT2,TF>& rhs )
2158 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
2159 vector_[offset_+element->index()] = element->value();
2177 template<
typename VT
2179 template<
typename VT2 >
2180 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
2181 Subvector<VT,unaligned,TF,true>::addAssign(
const DenseVector<VT2,TF>& rhs )
2185 const size_t ipos(
size() &
size_t(-2) );
2186 for(
size_t i=0UL; i<ipos; i+=2UL ) {
2187 vector_[offset_+i ] += (~rhs)[i ];
2188 vector_[offset_+i+1UL] += (~rhs)[i+1UL];
2190 if( ipos <
size() ) {
2191 vector_[offset_+ipos] += (~rhs)[ipos];
2210 template<
typename VT
2212 template<
typename VT2 >
2213 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
2214 Subvector<VT,unaligned,TF,true>::addAssign(
const DenseVector<VT2,TF>& rhs )
2220 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
2224 Iterator left(
begin() );
2225 ConstIterator_<VT2> right( (~rhs).
begin() );
2227 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2228 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2229 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2230 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2231 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2233 for( ; i<ipos; i+=SIMDSIZE ) {
2234 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2236 for( ; i<size_; ++i ) {
2237 *left += *right; ++left; ++right;
2256 template<
typename VT
2258 template<
typename VT2 >
2259 inline void Subvector<VT,unaligned,TF,true>::addAssign(
const SparseVector<VT2,TF>& rhs )
2263 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
2264 vector_[offset_+element->index()] += element->value();
2282 template<
typename VT
2284 template<
typename VT2 >
2285 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
2286 Subvector<VT,unaligned,TF,true>::subAssign(
const DenseVector<VT2,TF>& rhs )
2290 const size_t ipos(
size() &
size_t(-2) );
2291 for(
size_t i=0UL; i<ipos; i+=2UL ) {
2292 vector_[offset_+i ] -= (~rhs)[i ];
2293 vector_[offset_+i+1UL] -= (~rhs)[i+1UL];
2295 if( ipos <
size() ) {
2296 vector_[offset_+ipos] -= (~rhs)[ipos];
2315 template<
typename VT
2317 template<
typename VT2 >
2318 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
2319 Subvector<VT,unaligned,TF,true>::subAssign(
const DenseVector<VT2,TF>& rhs )
2325 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
2329 Iterator left(
begin() );
2330 ConstIterator_<VT2> right( (~rhs).
begin() );
2332 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2333 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2334 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2335 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2336 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2338 for( ; i<ipos; i+=SIMDSIZE ) {
2339 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2341 for( ; i<size_; ++i ) {
2342 *left -= *right; ++left; ++right;
2361 template<
typename VT
2363 template<
typename VT2 >
2364 inline void Subvector<VT,unaligned,TF,true>::subAssign(
const SparseVector<VT2,TF>& rhs )
2368 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
2369 vector_[offset_+element->index()] -= element->value();
2387 template<
typename VT
2389 template<
typename VT2 >
2390 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
2391 Subvector<VT,unaligned,TF,true>::multAssign(
const DenseVector<VT2,TF>& rhs )
2395 const size_t ipos(
size() &
size_t(-2) );
2396 for(
size_t i=0UL; i<ipos; i+=2UL ) {
2397 vector_[offset_+i ] *= (~rhs)[i ];
2398 vector_[offset_+i+1UL] *= (~rhs)[i+1UL];
2400 if( ipos <
size() ) {
2401 vector_[offset_+ipos] *= (~rhs)[ipos];
2420 template<
typename VT
2422 template<
typename VT2 >
2423 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
2424 Subvector<VT,unaligned,TF,true>::multAssign(
const DenseVector<VT2,TF>& rhs )
2430 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
2434 Iterator left(
begin() );
2435 ConstIterator_<VT2> right( (~rhs).
begin() );
2437 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2438 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2439 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2440 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2441 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2443 for( ; i<ipos; i+=SIMDSIZE ) {
2444 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2446 for( ; i<size_; ++i ) {
2447 *left *= *right; ++left; ++right;
2466 template<
typename VT
2468 template<
typename VT2 >
2469 inline void Subvector<VT,unaligned,TF,true>::multAssign(
const SparseVector<VT2,TF>& rhs )
2473 const ResultType tmp(
serial( *
this ) );
2477 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
2478 vector_[offset_+element->index()] = tmp[element->index()] * element->value();
2496 template<
typename VT
2498 template<
typename VT2 >
2499 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
2500 Subvector<VT,unaligned,TF,true>::divAssign(
const DenseVector<VT2,TF>& rhs )
2504 const size_t ipos(
size() &
size_t(-2) );
2505 for(
size_t i=0UL; i<ipos; i+=2UL ) {
2506 vector_[offset_+i ] /= (~rhs)[i ];
2507 vector_[offset_+i+1UL] /= (~rhs)[i+1UL];
2509 if( ipos <
size() ) {
2510 vector_[offset_+ipos] /= (~rhs)[ipos];
2529 template<
typename VT
2531 template<
typename VT2 >
2532 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
2533 Subvector<VT,unaligned,TF,true>::divAssign(
const DenseVector<VT2,TF>& rhs )
2539 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
2543 Iterator left(
begin() );
2544 ConstIterator_<VT2> right( (~rhs).
begin() );
2546 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2547 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2548 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2549 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2550 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2552 for( ; i<ipos; i+=SIMDSIZE ) {
2553 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2555 for( ; i<size_; ++i ) {
2556 *left /= *right; ++left; ++right;
2583 template<
typename VT
2585 class Subvector<VT,
aligned,TF,true>
2586 :
public DenseVector< Subvector<VT,aligned,TF,true>, TF >
2592 typedef If_< IsExpression<VT>, VT, VT& > Operand;
2597 typedef Subvector<VT,aligned,TF,true>
This;
2598 typedef DenseVector<This,TF>
BaseType;
2602 typedef SIMDTrait_<ElementType> SIMDType;
2613 typedef const ElementType* ConstPointer;
2616 typedef If_< Or< IsConst<VT>, Not< HasMutableDataAccess<VT> > >, ConstPointer, ElementType* > Pointer;
2627 enum :
bool { simdEnabled = VT::simdEnabled };
2630 enum :
bool { smpAssignable = VT::smpAssignable };
2636 explicit inline Subvector( Operand vector,
size_t index,
size_t n );
2648 inline Reference operator[](
size_t index );
2649 inline ConstReference operator[](
size_t index )
const;
2650 inline Reference at(
size_t index );
2651 inline ConstReference at(
size_t index )
const;
2652 inline Pointer data () noexcept;
2653 inline ConstPointer data () const noexcept;
2654 inline Iterator
begin ();
2655 inline ConstIterator begin () const;
2656 inline ConstIterator
cbegin() const;
2657 inline Iterator
end ();
2658 inline ConstIterator end () const;
2659 inline ConstIterator
cend () const;
2666 inline Subvector& operator= ( const ElementType& rhs );
2667 inline Subvector& operator= ( initializer_list<ElementType> list );
2668 inline Subvector& operator= ( const Subvector& rhs );
2669 template< typename VT2 > inline Subvector& operator= ( const Vector<VT2,TF>& rhs );
2670 template< typename VT2 > inline Subvector& operator+=( const Vector<VT2,TF>& rhs );
2671 template< typename VT2 > inline Subvector& operator-=( const Vector<VT2,TF>& rhs );
2672 template< typename VT2 > inline Subvector& operator*=( const DenseVector<VT2,TF>& rhs );
2673 template< typename VT2 > inline Subvector& operator*=( const SparseVector<VT2,TF>& rhs );
2674 template< typename VT2 > inline Subvector& operator/=( const DenseVector<VT2,TF>& rhs );
2676 template< typename Other >
2677 inline
EnableIf_< IsNumeric<Other>, Subvector >& operator*=( Other rhs );
2679 template< typename Other >
2680 inline
EnableIf_< IsNumeric<Other>, Subvector >& operator/=( Other rhs );
2687 inline
size_t size() const noexcept;
2688 inline
size_t capacity() const noexcept;
2690 inline
void reset();
2697 template< typename Other > inline Subvector& scale( const Other& scalar );
2704 template< typename VT2 >
2705 struct VectorizedAssign {
2707 simdEnabled && VT2::simdEnabled &&
2708 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value };
2714 template<
typename VT2 >
2715 struct VectorizedAddAssign {
2717 simdEnabled && VT2::simdEnabled &&
2718 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2719 HasSIMDAdd< ElementType, ElementType_<VT2> >::value };
2725 template<
typename VT2 >
2726 struct VectorizedSubAssign {
2728 simdEnabled && VT2::simdEnabled &&
2729 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2730 HasSIMDSub< ElementType, ElementType_<VT2> >::value };
2736 template<
typename VT2 >
2737 struct VectorizedMultAssign {
2739 simdEnabled && VT2::simdEnabled &&
2740 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2741 HasSIMDMult< ElementType, ElementType_<VT2> >::value };
2747 template<
typename VT2 >
2748 struct VectorizedDivAssign {
2750 simdEnabled && VT2::simdEnabled &&
2751 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2752 HasSIMDDiv< ElementType, ElementType_<VT2> >::value };
2765 template<
typename Other >
2766 inline bool canAlias(
const Other* alias )
const noexcept;
2768 template<
typename VT2,
bool AF2,
bool TF2 >
2769 inline bool canAlias(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept;
2771 template<
typename Other >
2772 inline bool isAliased(
const Other* alias )
const noexcept;
2774 template<
typename VT2,
bool AF2,
bool TF2 >
2775 inline bool isAliased(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept;
2777 inline bool isAligned () const noexcept;
2778 inline
bool canSMPAssign() const noexcept;
2789 template< typename VT2 >
2790 inline
DisableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
2792 template< typename VT2 >
2793 inline
EnableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
2795 template< typename VT2 > inline
void assign( const SparseVector<VT2,TF>& rhs );
2797 template< typename VT2 >
2798 inline
DisableIf_< VectorizedAddAssign<VT2> > addAssign( const DenseVector <VT2,TF>& rhs );
2800 template< typename VT2 >
2801 inline
EnableIf_< VectorizedAddAssign<VT2> > addAssign ( const DenseVector <VT2,TF>& rhs );
2803 template< typename VT2 > inline
void addAssign( const SparseVector<VT2,TF>& rhs );
2805 template< typename VT2 >
2806 inline
DisableIf_< VectorizedSubAssign<VT2> > subAssign ( const DenseVector <VT2,TF>& rhs );
2808 template< typename VT2 >
2809 inline
EnableIf_< VectorizedSubAssign<VT2> > subAssign( const DenseVector <VT2,TF>& rhs );
2811 template< typename VT2 > inline
void subAssign( const SparseVector<VT2,TF>& rhs );
2813 template< typename VT2 >
2814 inline
DisableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
2816 template< typename VT2 >
2817 inline
EnableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
2819 template< typename VT2 > inline
void multAssign( const SparseVector<VT2,TF>& rhs );
2821 template< typename VT2 >
2822 inline
DisableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
2824 template< typename VT2 >
2825 inline
EnableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
2834 const
size_t offset_;
2840 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 > friend class Subvector;
2842 template<
bool AF1, typename VT2,
bool AF2,
bool TF2,
bool DF2 >
2843 friend const Subvector<VT2,AF1,TF2,DF2>
2844 subvector( const Subvector<VT2,AF2,TF2,DF2>& sv,
size_t index,
size_t size );
2846 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
2847 friend
bool isIntact( const Subvector<VT2,AF2,TF2,DF2>& sv ) noexcept;
2849 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
2850 friend
bool isSame( const Subvector<VT2,AF2,TF2,DF2>& a, const Vector<VT2,TF2>& b ) noexcept;
2852 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
2853 friend
bool isSame( const Vector<VT2,TF2>& a, const Subvector<VT2,AF2,TF2,DF2>& b ) noexcept;
2855 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
2856 friend
bool isSame( const Subvector<VT2,AF2,TF2,DF2>& a, const Subvector<VT2,AF2,TF2,DF2>& b ) noexcept;
2858 template< typename VT2,
bool AF2,
bool TF2,
bool DF2, typename VT3 >
2859 friend
bool tryAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs,
size_t index );
2861 template< typename VT2,
bool AF2,
bool TF2,
bool DF2, typename VT3 >
2862 friend
bool tryAddAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs,
size_t index );
2864 template< typename VT2,
bool AF2,
bool TF2,
bool DF2, typename VT3 >
2865 friend
bool trySubAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs,
size_t index );
2867 template< typename VT2,
bool AF2,
bool TF2,
bool DF2, typename VT3 >
2868 friend
bool tryMultAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs,
size_t index );
2870 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
2871 friend
DerestrictTrait_< Subvector<VT2,AF2,TF2,DF2> > derestrict( Subvector<VT2,AF2,TF2,DF2>& sv );
2907 template< typename VT
2909 inline Subvector<VT,
aligned,TF,true>::Subvector( Operand vector,
size_t index,
size_t n )
2914 if( index + n > vector.size() ) {
2918 if( simdEnabled && vector_.data() !=
nullptr && !
checkAlignment( data() ) ) {
2941 template<
typename VT
2944 Subvector<VT,aligned,TF,true>::operator[](
size_t index )
2947 return vector_[offset_+index];
2960 template<
typename VT
2963 Subvector<VT,aligned,TF,true>::operator[](
size_t index )
const 2966 return const_cast<const VT&
>( vector_ )[offset_+index];
2983 template<
typename VT
2986 Subvector<VT,aligned,TF,true>::at(
size_t index )
2988 if( index >=
size() ) {
2991 return (*
this)[index];
3008 template<
typename VT
3011 Subvector<VT,aligned,TF,true>::at(
size_t index )
const 3013 if( index >=
size() ) {
3016 return (*
this)[index];
3030 template<
typename VT
3032 inline typename Subvector<VT,aligned,TF,true>::Pointer Subvector<VT,aligned,TF,true>::data() noexcept
3034 return vector_.data() + offset_;
3048 template<
typename VT
3050 inline typename Subvector<VT,aligned,TF,true>::ConstPointer
3051 Subvector<VT,aligned,TF,true>::data() const noexcept
3053 return vector_.data() + offset_;
3067 template<
typename VT
3071 return ( vector_.begin() + offset_ );
3085 template<
typename VT
3090 return ( vector_.cbegin() + offset_ );
3104 template<
typename VT
3109 return ( vector_.cbegin() + offset_ );
3123 template<
typename VT
3127 return ( vector_.begin() + offset_ + size_ );
3141 template<
typename VT
3146 return ( vector_.cbegin() + offset_ + size_ );
3160 template<
typename VT
3165 return ( vector_.cbegin() + offset_ + size_ );
3186 template<
typename VT
3188 inline Subvector<VT,aligned,TF,true>&
3189 Subvector<VT,aligned,TF,true>::operator=(
const ElementType& rhs )
3191 const size_t iend( offset_ + size_ );
3193 for(
size_t i=offset_; i<iend; ++i )
3215 template<
typename VT
3217 inline Subvector<VT,aligned,TF,true>&
3218 Subvector<VT,aligned,TF,true>::operator=( initializer_list<ElementType> list )
3220 if( list.size() >
size() ) {
3246 template<
typename VT
3248 inline Subvector<VT,aligned,TF,true>&
3249 Subvector<VT,aligned,TF,true>::operator=(
const Subvector& rhs )
3254 if( &rhs ==
this || ( &vector_ == &rhs.vector_ && offset_ == rhs.offset_ ) )
3257 if(
size() != rhs.size() ) {
3261 if( !tryAssign( vector_, rhs, offset_ ) ) {
3265 DerestrictTrait_<This> left( derestrict( *
this ) );
3267 if( rhs.canAlias( &vector_ ) ) {
3268 const ResultType tmp( ~rhs );
3295 template<
typename VT
3297 template<
typename VT2 >
3298 inline Subvector<VT,aligned,TF,true>&
3299 Subvector<VT,aligned,TF,true>::operator=(
const Vector<VT2,TF>& rhs )
3308 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
3309 Right right( ~rhs );
3311 if( !tryAssign( vector_, right, offset_ ) ) {
3315 DerestrictTrait_<This> left( derestrict( *
this ) );
3317 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3318 const ResultType_<VT2> tmp( right );
3322 if( IsSparseVector<VT2>::value )
3347 template<
typename VT
3349 template<
typename VT2 >
3350 inline Subvector<VT,aligned,TF,true>&
3360 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
3361 Right right( ~rhs );
3363 if( !tryAddAssign( vector_, right, offset_ ) ) {
3367 DerestrictTrait_<This> left( derestrict( *
this ) );
3369 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3370 const ResultType_<VT2> tmp( right );
3397 template<
typename VT
3399 template<
typename VT2 >
3400 inline Subvector<VT,aligned,TF,true>&
3410 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
3411 Right right( ~rhs );
3413 if( !trySubAssign( vector_, right, offset_ ) ) {
3417 DerestrictTrait_<This> left( derestrict( *
this ) );
3419 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3420 const ResultType_<VT2> tmp( right );
3448 template<
typename VT
3450 template<
typename VT2 >
3451 inline Subvector<VT,aligned,TF,true>&
3461 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
3462 Right right( ~rhs );
3464 if( !tryMultAssign( vector_, right, offset_ ) ) {
3468 DerestrictTrait_<This> left( derestrict( *
this ) );
3470 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3471 const ResultType_<VT2> tmp( right );
3499 template<
typename VT
3501 template<
typename VT2 >
3502 inline Subvector<VT,aligned,TF,true>&
3512 const ResultType tmp( *
this * (~rhs) );
3514 if( !tryAssign( vector_, tmp, offset_ ) ) {
3518 DerestrictTrait_<This> left( derestrict( *
this ) );
3542 template<
typename VT
3544 template<
typename VT2 >
3545 inline Subvector<VT,aligned,TF,true>&
3555 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
3556 Right right( ~rhs );
3558 if( !tryDivAssign( vector_, right, offset_ ) ) {
3562 DerestrictTrait_<This> left( derestrict( *
this ) );
3564 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3565 const ResultType_<VT2> tmp( right );
3588 template<
typename VT
3590 template<
typename Other >
3591 inline EnableIf_< IsNumeric<Other>, Subvector<VT,aligned,TF,true> >&
3594 DerestrictTrait_<This> left( derestrict( *
this ) );
3613 template<
typename VT
3615 template<
typename Other >
3616 inline EnableIf_< IsNumeric<Other>, Subvector<VT,aligned,TF,true> >&
3621 DerestrictTrait_<This> left( derestrict( *
this ) );
3644 template<
typename VT
3660 template<
typename VT
3664 return vector_.capacity() - offset_;
3679 template<
typename VT
3683 size_t nonzeros( 0 );
3685 const size_t iend( offset_ + size_ );
3686 for(
size_t i=offset_; i<iend; ++i ) {
3703 template<
typename VT
3709 const size_t iend( offset_ + size_ );
3710 for(
size_t i=offset_; i<iend; ++i )
3711 clear( vector_[i] );
3732 template<
typename VT
3734 template<
typename Other >
3735 inline Subvector<VT,aligned,TF,true>& Subvector<VT,aligned,TF,true>::scale(
const Other& scalar )
3737 const size_t iend( offset_ + size_ );
3738 for(
size_t i=offset_; i<iend; ++i )
3739 vector_[i] *= scalar;
3765 template<
typename VT
3767 template<
typename Other >
3768 inline bool Subvector<VT,aligned,TF,true>::canAlias(
const Other* alias )
const noexcept
3770 return vector_.isAliased( alias );
3787 template<
typename VT
3789 template<
typename VT2
3792 inline bool Subvector<VT,aligned,TF,true>::canAlias(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept
3794 return ( vector_.isAliased( &alias->vector_ ) &&
3795 ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
3812 template<
typename VT
3814 template<
typename Other >
3815 inline bool Subvector<VT,aligned,TF,true>::isAliased(
const Other* alias )
const noexcept
3817 return vector_.isAliased( alias );
3834 template<
typename VT
3836 template<
typename VT2
3839 inline bool Subvector<VT,aligned,TF,true>::isAliased(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept
3841 return ( vector_.isAliased( &alias->vector_ ) &&
3842 ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
3858 template<
typename VT
3860 inline bool Subvector<VT,aligned,TF,true>::isAligned() const noexcept
3879 template<
typename VT
3881 inline bool Subvector<VT,aligned,TF,true>::canSMPAssign() const noexcept
3883 return (
size() > SMP_DVECASSIGN_THRESHOLD );
3903 template<
typename VT
3906 Subvector<VT,aligned,TF,true>::load(
size_t index )
const noexcept
3908 return loada( index );
3928 template<
typename VT
3939 return vector_.loada( offset_+index );
3959 template<
typename VT
3970 return vector_.loadu( offset_+index );
3991 template<
typename VT
3994 Subvector<VT,aligned,TF,true>::store(
size_t index,
const SIMDType& value ) noexcept
4017 template<
typename VT
4028 vector_.storea( offset_+index, value );
4049 template<
typename VT
4060 vector_.storeu( offset_+index, value );
4081 template<
typename VT
4092 vector_.stream( offset_+index, value );
4110 template<
typename VT
4112 template<
typename VT2 >
4113 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
4114 Subvector<VT,aligned,TF,true>::assign(
const DenseVector<VT2,TF>& rhs )
4118 const size_t ipos(
size() &
size_t(-2) );
4119 for(
size_t i=0UL; i<ipos; i+=2UL ) {
4120 vector_[offset_+i ] = (~rhs)[i ];
4121 vector_[offset_+i+1UL] = (~rhs)[i+1UL];
4123 if( ipos <
size() ) {
4124 vector_[offset_+ipos] = (~rhs)[ipos];
4143 template<
typename VT
4145 template<
typename VT2 >
4146 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
4147 Subvector<VT,aligned,TF,true>::assign(
const DenseVector<VT2,TF>& rhs )
4153 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
4157 Iterator left(
begin() );
4158 ConstIterator_<VT2> right( (~rhs).
begin() );
4160 if(
useStreaming && size_ > (
cacheSize/(
sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( &vector_ ) )
4162 for( ; i<ipos; i+=SIMDSIZE ) {
4163 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4165 for( ; i<size_; ++i ) {
4166 *left = *right; ++left; ++right;
4171 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4172 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4173 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4174 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4175 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4177 for( ; i<ipos; i+=SIMDSIZE ) {
4178 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4180 for( ; i<size_; ++i ) {
4181 *left = *right; ++left; ++right;
4201 template<
typename VT
4203 template<
typename VT2 >
4204 inline void Subvector<VT,aligned,TF,true>::assign(
const SparseVector<VT2,TF>& rhs )
4208 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
4209 vector_[offset_+element->index()] = element->value();
4227 template<
typename VT
4229 template<
typename VT2 >
4230 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
4231 Subvector<VT,aligned,TF,true>::addAssign(
const DenseVector<VT2,TF>& rhs )
4235 const size_t ipos(
size() &
size_t(-2) );
4236 for(
size_t i=0UL; i<ipos; i+=2UL ) {
4237 vector_[offset_+i ] += (~rhs)[i ];
4238 vector_[offset_+i+1UL] += (~rhs)[i+1UL];
4240 if( ipos <
size() ) {
4241 vector_[offset_+ipos] += (~rhs)[ipos];
4260 template<
typename VT
4262 template<
typename VT2 >
4263 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
4264 Subvector<VT,aligned,TF,true>::addAssign(
const DenseVector<VT2,TF>& rhs )
4270 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
4274 Iterator left(
begin() );
4275 ConstIterator_<VT2> right( (~rhs).
begin() );
4277 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4278 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4279 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4280 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4281 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4283 for( ; i<ipos; i+=SIMDSIZE ) {
4284 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4286 for( ; i<size_; ++i ) {
4287 *left += *right; ++left; ++right;
4306 template<
typename VT
4308 template<
typename VT2 >
4309 inline void Subvector<VT,aligned,TF,true>::addAssign(
const SparseVector<VT2,TF>& rhs )
4313 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
4314 vector_[offset_+element->index()] += element->value();
4332 template<
typename VT
4334 template<
typename VT2 >
4335 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
4336 Subvector<VT,aligned,TF,true>::subAssign(
const DenseVector<VT2,TF>& rhs )
4340 const size_t ipos(
size() &
size_t(-2) );
4341 for(
size_t i=0UL; i<ipos; i+=2UL ) {
4342 vector_[offset_+i ] -= (~rhs)[i ];
4343 vector_[offset_+i+1UL] -= (~rhs)[i+1UL];
4345 if( ipos <
size() ) {
4346 vector_[offset_+ipos] -= (~rhs)[ipos];
4365 template<
typename VT
4367 template<
typename VT2 >
4368 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
4369 Subvector<VT,aligned,TF,true>::subAssign(
const DenseVector<VT2,TF>& rhs )
4375 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
4379 Iterator left(
begin() );
4380 ConstIterator_<VT2> right( (~rhs).
begin() );
4382 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4383 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4384 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4385 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4386 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4388 for( ; i<ipos; i+=SIMDSIZE ) {
4389 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4391 for( ; i<size_; ++i ) {
4392 *left -= *right; ++left; ++right;
4411 template<
typename VT
4413 template<
typename VT2 >
4414 inline void Subvector<VT,aligned,TF,true>::subAssign(
const SparseVector<VT2,TF>& rhs )
4418 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
4419 vector_[offset_+element->index()] -= element->value();
4437 template<
typename VT
4439 template<
typename VT2 >
4440 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
4441 Subvector<VT,aligned,TF,true>::multAssign(
const DenseVector<VT2,TF>& rhs )
4445 const size_t ipos(
size() &
size_t(-2) );
4446 for(
size_t i=0UL; i<ipos; i+=2UL ) {
4447 vector_[offset_+i ] *= (~rhs)[i ];
4448 vector_[offset_+i+1UL] *= (~rhs)[i+1UL];
4450 if( ipos <
size() ) {
4451 vector_[offset_+ipos] *= (~rhs)[ipos];
4470 template<
typename VT
4472 template<
typename VT2 >
4473 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
4474 Subvector<VT,aligned,TF,true>::multAssign(
const DenseVector<VT2,TF>& rhs )
4480 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
4484 Iterator left(
begin() );
4485 ConstIterator_<VT2> right( (~rhs).
begin() );
4487 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4488 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4489 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4490 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4491 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4493 for( ; i<ipos; i+=SIMDSIZE ) {
4494 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4496 for( ; i<size_; ++i ) {
4497 *left *= *right; ++left; ++right;
4516 template<
typename VT
4518 template<
typename VT2 >
4519 inline void Subvector<VT,aligned,TF,true>::multAssign(
const SparseVector<VT2,TF>& rhs )
4523 const ResultType tmp(
serial( *
this ) );
4527 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
4528 vector_[offset_+element->index()] = tmp[element->index()] * element->value();
4546 template<
typename VT
4548 template<
typename VT2 >
4549 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
4550 Subvector<VT,aligned,TF,true>::divAssign(
const DenseVector<VT2,TF>& rhs )
4554 const size_t ipos(
size() &
size_t(-2) );
4555 for(
size_t i=0UL; i<ipos; i+=2UL ) {
4556 vector_[offset_+i ] /= (~rhs)[i ];
4557 vector_[offset_+i+1UL] /= (~rhs)[i+1UL];
4559 if( ipos <
size() ) {
4560 vector_[offset_+ipos] /= (~rhs)[ipos];
4579 template<
typename VT
4581 template<
typename VT2 >
4582 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
4583 Subvector<VT,aligned,TF,true>::divAssign(
const DenseVector<VT2,TF>& rhs )
4589 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
4593 Iterator left(
begin() );
4594 ConstIterator_<VT2> right( (~rhs).
begin() );
4596 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4597 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4598 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4599 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4600 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4602 for( ; i<ipos; i+=SIMDSIZE ) {
4603 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4605 for( ; i<size_; ++i ) {
4606 *left /= *right; ++left; ++right;
4633 template<
typename VT1
4636 class Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
4637 :
public DenseVector< Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF >
4642 typedef DVecDVecCrossExpr<VT1,VT2,TF> CPE;
4643 typedef ResultType_<CPE> RT;
4648 typedef Subvector<CPE,unaligned,TF,true>
This;
4649 typedef DenseVector<This,TF>
BaseType;
4659 enum :
bool { simdEnabled =
false };
4662 enum :
bool { smpAssignable =
false };
4672 explicit inline Subvector(
const CPE& vector,
size_t index,
size_t n ) noexcept
4685 inline ReturnType operator[](
size_t index )
const {
4687 return vector_[offset_+index];
4698 inline ReturnType at(
size_t index )
const {
4699 if( index >=
size() ) {
4702 return (*
this)[index];
4711 inline size_t size() const noexcept {
4722 template<
typename T >
4723 inline bool canAlias(
const T* alias )
const noexcept {
4724 return vector_.canAlias( alias );
4734 template<
typename T >
4735 inline bool isAliased(
const T* alias )
const noexcept {
4736 return vector_.isAliased( alias );
4745 const size_t offset_;
4751 template<
bool AF1,
typename VT,
bool AF2,
bool TF2,
bool DF2 >
4752 friend const Subvector<VT,AF1,TF2,DF2>
4753 subvector(
const Subvector<VT,AF2,TF2,DF2>& sv,
size_t index,
size_t size );
4755 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
4756 friend bool isIntact(
const Subvector<VT3,AF,TF2,DF2>& sv ) noexcept;
4758 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
4759 friend bool isSame(
const Subvector<VT3,AF,TF2,DF2>& a,
const Vector<VT3,TF2>& b ) noexcept;
4761 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
4762 friend bool isSame(
const Vector<VT3,TF2>& a,
const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
4764 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
4765 friend bool isSame(
const Subvector<VT3,AF,TF2,DF2>& a,
const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
4767 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
4768 friend bool tryAssign(
const Subvector<VT3,AF,TF2,DF2>& lhs,
const Vector<VT4,TF2>& rhs,
size_t index );
4770 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
4771 friend bool tryAddAssign(
const Subvector<VT2,AF,TF2,DF2>& lhs,
const Vector<VT3,TF2>& rhs,
size_t index );
4773 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
4774 friend bool trySubAssign(
const Subvector<VT2,AF,TF2,DF2>& lhs,
const Vector<VT3,TF2>& rhs,
size_t index );
4776 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
4777 friend bool tryMultAssign(
const Subvector<VT3,AF,TF2,DF2>& lhs,
const Vector<VT4,TF2>& rhs,
size_t index );
4804 template<
typename VT1
4807 class Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
4808 :
public DenseVector< Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF >
4813 typedef DVecSVecCrossExpr<VT1,VT2,TF> CPE;
4814 typedef ResultType_<CPE> RT;
4819 typedef Subvector<CPE,unaligned,TF,true>
This;
4820 typedef DenseVector<This,TF>
BaseType;
4830 enum :
bool { simdEnabled =
false };
4833 enum :
bool { smpAssignable =
false };
4843 explicit inline Subvector(
const CPE& vector,
size_t index,
size_t n ) noexcept
4856 inline ReturnType operator[](
size_t index )
const {
4858 return vector_[offset_+index];
4869 inline ReturnType at(
size_t index )
const {
4870 if( index >=
size() ) {
4873 return (*
this)[index];
4882 inline size_t size() const noexcept {
4893 template<
typename T >
4894 inline bool canAlias(
const T* alias )
const noexcept {
4895 return vector_.canAlias( alias );
4905 template<
typename T >
4906 inline bool isAliased(
const T* alias )
const noexcept {
4907 return vector_.isAliased( alias );
4916 const size_t offset_;
4922 template<
bool AF1,
typename VT,
bool AF2,
bool TF2,
bool DF2 >
4923 friend const Subvector<VT,AF1,TF2,DF2>
4924 subvector(
const Subvector<VT,AF2,TF2,DF2>& sv,
size_t index,
size_t size );
4926 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
4927 friend bool isIntact(
const Subvector<VT3,AF,TF2,DF2>& sv ) noexcept;
4929 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
4930 friend bool isSame(
const Subvector<VT3,AF,TF2,DF2>& a,
const Vector<VT3,TF2>& b ) noexcept;
4932 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
4933 friend bool isSame(
const Vector<VT3,TF2>& a,
const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
4935 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
4936 friend bool isSame(
const Subvector<VT3,AF,TF2,DF2>& a,
const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
4938 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
4939 friend bool tryAssign(
const Subvector<VT3,AF,TF2,DF2>& lhs,
const Vector<VT4,TF2>& rhs,
size_t index );
4941 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
4942 friend bool tryAddAssign(
const Subvector<VT2,AF,TF2,DF2>& lhs,
const Vector<VT3,TF2>& rhs,
size_t index );
4944 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
4945 friend bool trySubAssign(
const Subvector<VT2,AF,TF2,DF2>& lhs,
const Vector<VT3,TF2>& rhs,
size_t index );
4947 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
4948 friend bool tryMultAssign(
const Subvector<VT3,AF,TF2,DF2>& lhs,
const Vector<VT4,TF2>& rhs,
size_t index );
4975 template<
typename VT1
4978 class Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
4979 :
public DenseVector< Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF >
4984 typedef SVecDVecCrossExpr<VT1,VT2,TF> CPE;
4985 typedef ResultType_<CPE> RT;
4990 typedef Subvector<CPE,unaligned,TF,true>
This;
4991 typedef DenseVector<This,TF>
BaseType;
5001 enum :
bool { simdEnabled =
false };
5004 enum :
bool { smpAssignable =
false };
5014 explicit inline Subvector(
const CPE& vector,
size_t index,
size_t n ) noexcept
5027 inline ReturnType operator[](
size_t index )
const {
5029 return vector_[offset_+index];
5040 inline ReturnType at(
size_t index )
const {
5041 if( index >=
size() ) {
5044 return (*
this)[index];
5053 inline size_t size() const noexcept {
5064 template<
typename T >
5065 inline bool canAlias(
const T* alias )
const noexcept {
5066 return vector_.canAlias( alias );
5076 template<
typename T >
5077 inline bool isAliased(
const T* alias )
const noexcept {
5078 return vector_.isAliased( alias );
5087 const size_t offset_;
5093 template<
bool AF1,
typename VT,
bool AF2,
bool TF2,
bool DF2 >
5094 friend const Subvector<VT,AF1,TF2,DF2>
5095 subvector(
const Subvector<VT,AF2,TF2,DF2>& sv,
size_t index,
size_t size );
5097 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
5098 friend bool isIntact(
const Subvector<VT3,AF,TF2,DF2>& sv ) noexcept;
5100 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
5101 friend bool isSame(
const Subvector<VT3,AF,TF2,DF2>& a,
const Vector<VT3,TF2>& b ) noexcept;
5103 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
5104 friend bool isSame(
const Vector<VT3,TF2>& a,
const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
5106 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
5107 friend bool isSame(
const Subvector<VT3,AF,TF2,DF2>& a,
const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
5109 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
5110 friend bool tryAssign(
const Subvector<VT3,AF,TF2,DF2>& lhs,
const Vector<VT4,TF2>& rhs,
size_t index );
5112 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
5113 friend bool tryAddAssign(
const Subvector<VT2,AF,TF2,DF2>& lhs,
const Vector<VT3,TF2>& rhs,
size_t index );
5115 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
5116 friend bool trySubAssign(
const Subvector<VT2,AF,TF2,DF2>& lhs,
const Vector<VT3,TF2>& rhs,
size_t index );
5118 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
5119 friend bool tryMultAssign(
const Subvector<VT3,AF,TF2,DF2>& lhs,
const Vector<VT4,TF2>& rhs,
size_t index );
5146 template<
typename VT1
5149 class Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
5150 :
public DenseVector< Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF >
5155 typedef SVecSVecCrossExpr<VT1,VT2,TF> CPE;
5156 typedef ResultType_<CPE> RT;
5161 typedef Subvector<CPE,unaligned,TF,true>
This;
5162 typedef DenseVector<This,TF>
BaseType;
5172 enum :
bool { simdEnabled =
false };
5175 enum :
bool { smpAssignable =
false };
5185 explicit inline Subvector(
const CPE& vector,
size_t index,
size_t n ) noexcept
5198 inline ReturnType operator[](
size_t index )
const {
5200 return vector_[offset_+index];
5211 inline ReturnType at(
size_t index )
const {
5212 if( index >=
size() ) {
5215 return (*
this)[index];
5224 inline size_t size() const noexcept {
5235 template<
typename T >
5236 inline bool canAlias(
const T* alias )
const noexcept {
5237 return vector_.canAlias( alias );
5247 template<
typename T >
5248 inline bool isAliased(
const T* alias )
const {
5249 return vector_.isAliased( alias );
5258 const size_t offset_;
5264 template<
bool AF1,
typename VT,
bool AF2,
bool TF2,
bool DF2 >
5265 friend const Subvector<VT,AF1,TF2,DF2>
5266 subvector(
const Subvector<VT,AF2,TF2,DF2>& sv,
size_t index,
size_t size );
5268 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
5269 friend bool isIntact(
const Subvector<VT3,AF,TF2,DF2>& sv ) noexcept;
5271 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
5272 friend bool isSame(
const Subvector<VT3,AF,TF2,DF2>& a,
const Vector<VT3,TF2>& b ) noexcept;
5274 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
5275 friend bool isSame(
const Vector<VT3,TF2>& a,
const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
5277 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
5278 friend bool isSame(
const Subvector<VT3,AF,TF2,DF2>& a,
const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
5280 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
5281 friend bool tryAssign(
const Subvector<VT3,AF,TF2,DF2>& lhs,
const Vector<VT4,TF2>& rhs,
size_t index );
5283 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
5284 friend bool tryAddAssign(
const Subvector<VT2,AF,TF2,DF2>& lhs,
const Vector<VT3,TF2>& rhs,
size_t index );
5286 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
5287 friend bool trySubAssign(
const Subvector<VT2,AF,TF2,DF2>& lhs,
const Vector<VT3,TF2>& rhs,
size_t index );
5289 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
5290 friend bool tryMultAssign(
const Subvector<VT3,AF,TF2,DF2>& lhs,
const Vector<VT4,TF2>& rhs,
size_t index );
Constraint on the data type.
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
constexpr bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
typename DerestrictTrait< T >::Type DerestrictTrait_
Auxiliary alias declaration for the DerestrictTrait type trait.The DerestrictTrait_ alias declaration...
Definition: DerestrictTrait.h:110
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the alignment flag values.
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:352
BLAZE_ALWAYS_INLINE bool isSame(const Matrix< MT1, SO1 > &a, const Matrix< MT2, SO2 > &b) noexcept
Returns whether the two given matrices represent the same observable state.
Definition: Matrix.h:721
Header file for basic type definitions.
Header file for the View base class.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:79
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:160
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:261
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i...
Definition: Computation.h:81
constexpr size_t cacheSize
Cache size of the target architecture.This setting specifies the available cache size in Byte of the ...
Definition: CacheSize.h:48
constexpr bool operator<(const NegativeAccuracy< A > &lhs, const T &rhs)
Less-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:329
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1339
const bool aligned
Alignment flag for aligned vectors and matrices.Via this flag it is possible to specify subvectors...
Definition: AlignmentFlag.h:85
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:194
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:533
const DenseIterator< Type, AF > operator+(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Addition between a DenseIterator and an integral value.
Definition: DenseIterator.h:699
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2935
EnableIf_< IsDenseVector< VT1 > > smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP multiplication assignment of a vector to a dense vector...
Definition: DenseVector.h:193
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:223
Header file for the DenseVector base class.
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2928
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:721
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:390
Header file for the Computation base class.
const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:731
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i...
Definition: TransExpr.h:81
System settings for performance optimizations.
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1321
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:77
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:129
BLAZE_ALWAYS_INLINE MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:304
BLAZE_ALWAYS_INLINE MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:238
Header file for the std::initializer_list aliases.
Constraint on the data type.
SubvectorExprTrait_< VT, unaligned > subvector(Vector< VT, TF > &vector, size_t index, size_t size)
Creating a view on a specific subvector of the given vector.
Definition: Subvector.h:152
Header file for the DisableIf class template.
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Header file for nested template disabiguation.
Header file for the If class template.
constexpr bool useStreaming
Configuration of the streaming behavior.For large vectors and matrices non-temporal stores can provid...
Definition: Optimizations.h:68
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2939
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:98
Header file for the Or class template.
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the HasSIMDAdd type trait.
constexpr bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:367
constexpr bool operator>=(const NegativeAccuracy< A > &, const T &rhs)
Greater-or-equal-than comparison between a NegativeAccuracy object and a floating point value...
Definition: Accuracy.h:443
Header file for the implementation of the Subvector base template.
Header file for the Not class template.
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:250
Header file for all SIMD functionality.
Constraint on the data type.
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:80
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not a vectorizable data type...
Definition: Vectorizable.h:61
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:2932
Constraint on the data type.
Header file for the exception macros of the math module.
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:260
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:2933
const bool unaligned
Alignment flag for unaligned vectors and matrices.Via this flag it is possible to specify subvectors...
Definition: AlignmentFlag.h:64
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:290
Constraint on the data type.
Header file for all forward declarations for expression class templates.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2937
Header file for the EnableIf class template.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:553
Header file for the DerestrictTrait class template.
Header file for the CrossExpr base class.
Header file for the IsNumeric type trait.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:75
Header file for the IsSIMDCombinable type trait.
Header file for the IsSparseVector type trait.
Header file for the HasSIMDMult type trait.
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2934
Header file for the IsConst type trait.
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1285
Header file for run time assertion macros.
EnableIf_< IsDenseVector< VT1 > > smpDivAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP division assignment of a vector to a dense vector.
Definition: DenseVector.h:222
Header file for the cache size of the target architecture.
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2938
Header file for the isDefault shim.
Header file for the HasSIMDSub type trait.
constexpr bool operator<=(const NegativeAccuracy< A > &, const T &rhs)
Less-or-equal-than comparison between a NegativeAccuracy object and a floating point value...
Definition: Accuracy.h:405
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:223
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:76
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional vector type...
Definition: DenseVector.h:61
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2929
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBVECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is a subvector type (i.e. a dense or sparse subvector), a compilation error is created.
Definition: Subvector.h:81
Header file for the HasSIMDDiv type trait.
Header file for the alignment check function.
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2930
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:249
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2936
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1303
Header file for the IsRestricted type trait.
const DMatDMatMultExpr< T1, T2, false, false, false, false > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:7505
System settings for the inline keywords.
#define BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG(T, TF)
Constraint on the data type.In case the given data type T is not a dense or sparse vector type and in...
Definition: TransposeFlag.h:63
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the IsExpression type trait class.