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;
616 template< typename Other > inline Subvector& scale( const Other& scalar );
623 template< typename VT2 >
624 struct VectorizedAssign {
626 simdEnabled && VT2::simdEnabled &&
627 AreSIMDCombinable< ElementType, ElementType_<VT2> >::value };
633 template<
typename VT2 >
634 struct VectorizedAddAssign {
636 simdEnabled && VT2::simdEnabled &&
637 AreSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
638 HasSIMDAdd< ElementType, ElementType_<VT2> >::value };
644 template<
typename VT2 >
645 struct VectorizedSubAssign {
647 simdEnabled && VT2::simdEnabled &&
648 AreSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
649 HasSIMDSub< ElementType, ElementType_<VT2> >::value };
655 template<
typename VT2 >
656 struct VectorizedMultAssign {
658 simdEnabled && VT2::simdEnabled &&
659 AreSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
660 HasSIMDMult< ElementType, ElementType_<VT2> >::value };
666 template<
typename VT2 >
667 struct VectorizedDivAssign {
669 simdEnabled && VT2::simdEnabled &&
670 AreSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
671 HasSIMDDiv< ElementType, ElementType_<VT2> >::value };
684 template<
typename Other >
685 inline bool canAlias(
const Other* alias )
const noexcept;
687 template<
typename VT2,
bool AF2,
bool TF2 >
688 inline bool canAlias(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept;
690 template<
typename Other >
691 inline bool isAliased(
const Other* alias )
const noexcept;
693 template<
typename VT2,
bool AF2,
bool TF2 >
694 inline bool isAliased(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept;
696 inline bool isAligned () const noexcept;
697 inline
bool canSMPAssign() const noexcept;
708 template< typename VT2 >
709 inline
DisableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
711 template< typename VT2 >
712 inline
EnableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
714 template< typename VT2 > inline
void assign( const SparseVector<VT2,TF>& rhs );
716 template< typename VT2 >
717 inline
DisableIf_< VectorizedAddAssign<VT2> > addAssign( const DenseVector <VT2,TF>& rhs );
719 template< typename VT2 >
720 inline
EnableIf_< VectorizedAddAssign<VT2> > addAssign ( const DenseVector <VT2,TF>& rhs );
722 template< typename VT2 > inline
void addAssign( const SparseVector<VT2,TF>& rhs );
724 template< typename VT2 >
725 inline
DisableIf_< VectorizedSubAssign<VT2> > subAssign ( const DenseVector <VT2,TF>& rhs );
727 template< typename VT2 >
728 inline
EnableIf_< VectorizedSubAssign<VT2> > subAssign( const DenseVector <VT2,TF>& rhs );
730 template< typename VT2 > inline
void subAssign( const SparseVector<VT2,TF>& rhs );
732 template< typename VT2 >
733 inline
DisableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
735 template< typename VT2 >
736 inline
EnableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
738 template< typename VT2 > inline
void multAssign( const SparseVector<VT2,TF>& rhs );
740 template< typename VT2 >
741 inline
DisableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
743 template< typename VT2 >
744 inline
EnableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
753 const
size_t offset_;
755 const
bool isAligned_;
766 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 > friend class Subvector;
768 template<
bool AF1, typename VT2,
bool AF2,
bool TF2,
bool DF2 >
769 friend const Subvector<VT2,AF1,TF2,DF2>
770 subvector( const Subvector<VT2,AF2,TF2,DF2>& sv,
size_t index,
size_t size );
772 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
773 friend
bool isIntact( const Subvector<VT2,AF2,TF2,DF2>& sv ) noexcept;
775 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
776 friend
bool isSame( const Subvector<VT2,AF2,TF2,DF2>& a, const Vector<VT2,TF2>& b ) noexcept;
778 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
779 friend
bool isSame( const Vector<VT2,TF2>& a, const Subvector<VT2,AF2,TF2,DF2>& b ) noexcept;
781 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
782 friend
bool isSame( const Subvector<VT2,AF2,TF2,DF2>& a, const Subvector<VT2,AF2,TF2,DF2>& b ) noexcept;
784 template< typename VT2,
bool AF2,
bool TF2,
bool DF2, typename VT3 >
785 friend
bool tryAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs,
size_t index );
787 template< typename VT2,
bool AF2,
bool TF2,
bool DF2, typename VT3 >
788 friend
bool tryAddAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs,
size_t index );
790 template< typename VT2,
bool AF2,
bool TF2,
bool DF2, typename VT3 >
791 friend
bool trySubAssign( const Subvector<VT2,AF2,DF2,TF2>& lhs, const Vector<VT3,TF2>& rhs,
size_t index );
793 template< typename VT2,
bool AF2,
bool TF2,
bool DF2, typename VT3 >
794 friend
bool tryMultAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs,
size_t index );
796 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
797 friend
DerestrictTrait_< Subvector<VT2,AF2,TF2,DF2> > derestrict( Subvector<VT2,AF2,TF2,DF2>& sv );
833 template< typename VT
835 inline Subvector<VT,
unaligned,TF,true>::Subvector( Operand vector,
size_t index,
size_t n )
839 , isAligned_( simdEnabled && vector.data() !=
nullptr &&
checkAlignment( data() ) )
841 if( index + n > vector.size() ) {
867 template<
typename VT
870 Subvector<VT,unaligned,TF,true>::operator[](
size_t index )
873 return vector_[offset_+index];
889 template<
typename VT
892 Subvector<VT,unaligned,TF,true>::operator[](
size_t index )
const
895 return const_cast<const VT&
>( vector_ )[offset_+index];
912 template<
typename VT
915 Subvector<VT,unaligned,TF,true>::at(
size_t index )
917 if( index >=
size() ) {
920 return (*
this)[index];
937 template<
typename VT
940 Subvector<VT,unaligned,TF,true>::at(
size_t index )
const
942 if( index >=
size() ) {
945 return (*
this)[index];
959 template<
typename VT
961 inline typename Subvector<VT,unaligned,TF,true>::Pointer
962 Subvector<VT,unaligned,TF,true>::data() noexcept
964 return vector_.data() + offset_;
978 template<
typename VT
980 inline typename Subvector<VT,unaligned,TF,true>::ConstPointer
981 Subvector<VT,unaligned,TF,true>::data() const noexcept
983 return vector_.data() + offset_;
997 template<
typename VT
1002 return Iterator( vector_.begin() + offset_, isAligned_ );
1016 template<
typename VT
1021 return ConstIterator( vector_.cbegin() + offset_, isAligned_ );
1035 template<
typename VT
1040 return ConstIterator( vector_.cbegin() + offset_, isAligned_ );
1054 template<
typename VT
1059 return Iterator( vector_.begin() + offset_ + size_, isAligned_ );
1073 template<
typename VT
1078 return ConstIterator( vector_.cbegin() + offset_ + size_, isAligned_ );
1092 template<
typename VT
1097 return ConstIterator( vector_.cbegin() + offset_ + size_, isAligned_ );
1118 template<
typename VT
1120 inline Subvector<VT,unaligned,TF,true>&
1121 Subvector<VT,unaligned,TF,true>::operator=(
const ElementType& rhs )
1123 const size_t iend( offset_ + size_ );
1125 for(
size_t i=offset_; i<iend; ++i )
1147 template<
typename VT
1149 inline Subvector<VT,unaligned,TF,true>&
1150 Subvector<VT,unaligned,TF,true>::operator=( initializer_list<ElementType> list )
1152 if( list.size() >
size() ) {
1178 template<
typename VT
1180 inline Subvector<VT,unaligned,TF,true>&
1181 Subvector<VT,unaligned,TF,true>::operator=(
const Subvector& rhs )
1186 if( &rhs ==
this || ( &vector_ == &rhs.vector_ && offset_ == rhs.offset_ ) )
1189 if(
size() != rhs.size() ) {
1193 if( !tryAssign( vector_, rhs, offset_ ) ) {
1197 DerestrictTrait_<This> left( derestrict( *
this ) );
1199 if( rhs.canAlias( &vector_ ) ) {
1200 const ResultType tmp( rhs );
1227 template<
typename VT
1229 template<
typename VT2 >
1230 inline Subvector<VT,unaligned,TF,true>&
1231 Subvector<VT,unaligned,TF,true>::operator=(
const Vector<VT2,TF>& rhs )
1240 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
1241 Right right( ~rhs );
1243 if( !tryAssign( vector_, right, offset_ ) ) {
1247 DerestrictTrait_<This> left( derestrict( *
this ) );
1249 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1250 const ResultType_<VT2> tmp( right );
1254 if( IsSparseVector<VT2>::value )
1279 template<
typename VT
1281 template<
typename VT2 >
1282 inline Subvector<VT,unaligned,TF,true>&
1292 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
1293 Right right( ~rhs );
1295 if( !tryAddAssign( vector_, right, offset_ ) ) {
1299 DerestrictTrait_<This> left( derestrict( *
this ) );
1301 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1302 const ResultType_<VT2> tmp( right );
1329 template<
typename VT
1331 template<
typename VT2 >
1332 inline Subvector<VT,unaligned,TF,true>&
1342 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
1343 Right right( ~rhs );
1345 if( !trySubAssign( vector_, right, offset_ ) ) {
1349 DerestrictTrait_<This> left( derestrict( *
this ) );
1351 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1352 const ResultType_<VT2> tmp( right );
1380 template<
typename VT
1382 template<
typename VT2 >
1383 inline Subvector<VT,unaligned,TF,true>&
1393 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
1394 Right right( ~rhs );
1396 if( !tryMultAssign( vector_, right, offset_ ) ) {
1400 DerestrictTrait_<This> left( derestrict( *
this ) );
1402 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1403 const ResultType_<VT2> tmp( right );
1431 template<
typename VT
1433 template<
typename VT2 >
1434 inline Subvector<VT,unaligned,TF,true>&
1444 const ResultType tmp( *
this * (~rhs) );
1446 if( !tryAssign( vector_, tmp, offset_ ) ) {
1450 DerestrictTrait_<This> left( derestrict( *
this ) );
1474 template<
typename VT
1476 template<
typename VT2 >
1477 inline Subvector<VT,unaligned,TF,true>&
1487 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
1488 Right right( ~rhs );
1490 if( !tryDivAssign( vector_, right, offset_ ) ) {
1494 DerestrictTrait_<This> left( derestrict( *
this ) );
1496 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1497 const ResultType_<VT2> tmp( right );
1520 template<
typename VT
1522 template<
typename Other >
1523 inline EnableIf_< IsNumeric<Other>, Subvector<VT,unaligned,TF,true> >&
1526 DerestrictTrait_<This> left( derestrict( *
this ) );
1545 template<
typename VT
1547 template<
typename Other >
1548 inline EnableIf_< IsNumeric<Other>, Subvector<VT,unaligned,TF,true> >&
1553 DerestrictTrait_<This> left( derestrict( *
this ) );
1576 template<
typename VT
1592 template<
typename VT
1596 return vector_.capacity() - offset_;
1611 template<
typename VT
1615 size_t nonzeros( 0 );
1617 const size_t iend( offset_ + size_ );
1618 for(
size_t i=offset_; i<iend; ++i ) {
1635 template<
typename VT
1641 const size_t iend( offset_ + size_ );
1642 for(
size_t i=offset_; i<iend; ++i )
1643 clear( vector_[i] );
1656 template<
typename VT
1658 template<
typename Other >
1659 inline Subvector<VT,unaligned,TF,true>&
1660 Subvector<VT,unaligned,TF,true>::scale(
const Other& scalar )
1662 const size_t iend( offset_ + size_ );
1663 for(
size_t i=offset_; i<iend; ++i )
1664 vector_[i] *= scalar;
1690 template<
typename VT
1692 template<
typename Other >
1693 inline bool Subvector<VT,unaligned,TF,true>::canAlias(
const Other* alias )
const noexcept
1695 return vector_.isAliased( alias );
1712 template<
typename VT
1714 template<
typename VT2
1717 inline bool Subvector<VT,unaligned,TF,true>::canAlias(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept
1719 return ( vector_.isAliased( &alias->vector_ ) &&
1720 ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
1737 template<
typename VT
1739 template<
typename Other >
1740 inline bool Subvector<VT,unaligned,TF,true>::isAliased(
const Other* alias )
const noexcept
1742 return vector_.isAliased( alias );
1759 template<
typename VT
1761 template<
typename VT2
1764 inline bool Subvector<VT,unaligned,TF,true>::isAliased(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept
1766 return ( vector_.isAliased( &alias->vector_ ) &&
1767 ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
1783 template<
typename VT
1785 inline bool Subvector<VT,unaligned,TF,true>::isAligned() const noexcept
1804 template<
typename VT
1806 inline bool Subvector<VT,unaligned,TF,true>::canSMPAssign() const noexcept
1808 return (
size() > SMP_DVECASSIGN_THRESHOLD );
1828 template<
typename VT
1831 Subvector<VT,unaligned,TF,true>::load(
size_t index )
const noexcept
1834 return loada( index );
1836 return loadu( index );
1856 template<
typename VT
1867 return vector_.loada( offset_+index );
1887 template<
typename VT
1898 return vector_.loadu( offset_+index );
1919 template<
typename VT
1922 Subvector<VT,unaligned,TF,true>::store(
size_t index,
const SIMDType& value ) noexcept
1948 template<
typename VT
1959 vector_.storea( offset_+index, value );
1980 template<
typename VT
1991 vector_.storeu( offset_+index, value );
2012 template<
typename VT
2024 vector_.stream( offset_+index, value );
2026 vector_.storeu( offset_+index, value );
2044 template<
typename VT
2046 template<
typename VT2 >
2047 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
2048 Subvector<VT,unaligned,TF,true>::assign(
const DenseVector<VT2,TF>& rhs )
2052 const size_t ipos(
size() &
size_t(-2) );
2053 for(
size_t i=0UL; i<ipos; i+=2UL ) {
2054 vector_[offset_+i ] = (~rhs)[i ];
2055 vector_[offset_+i+1UL] = (~rhs)[i+1UL];
2057 if( ipos <
size() ) {
2058 vector_[offset_+ipos] = (~rhs)[ipos];
2077 template<
typename VT
2079 template<
typename VT2 >
2080 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
2081 Subvector<VT,unaligned,TF,true>::assign(
const DenseVector<VT2,TF>& rhs )
2087 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
2091 Iterator left(
begin() );
2092 ConstIterator_<VT2> right( (~rhs).
begin() );
2095 ( size_ > (
cacheSize/(
sizeof(ElementType) * 3UL ) ) ) &&
2096 !(~rhs).isAliased( &vector_ ) )
2098 for( ; i<ipos; i+=SIMDSIZE ) {
2099 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2101 for( ; i<size_; ++i ) {
2107 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2108 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2109 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2110 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2111 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2113 for( ; i<ipos; i+=SIMDSIZE ) {
2114 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2116 for( ; i<size_; ++i ) {
2117 *left = *right; ++left; ++right;
2137 template<
typename VT
2139 template<
typename VT2 >
2140 inline void Subvector<VT,unaligned,TF,true>::assign(
const SparseVector<VT2,TF>& rhs )
2144 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
2145 vector_[offset_+element->index()] = element->value();
2163 template<
typename VT
2165 template<
typename VT2 >
2166 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
2167 Subvector<VT,unaligned,TF,true>::addAssign(
const DenseVector<VT2,TF>& rhs )
2171 const size_t ipos(
size() &
size_t(-2) );
2172 for(
size_t i=0UL; i<ipos; i+=2UL ) {
2173 vector_[offset_+i ] += (~rhs)[i ];
2174 vector_[offset_+i+1UL] += (~rhs)[i+1UL];
2176 if( ipos <
size() ) {
2177 vector_[offset_+ipos] += (~rhs)[ipos];
2196 template<
typename VT
2198 template<
typename VT2 >
2199 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
2200 Subvector<VT,unaligned,TF,true>::addAssign(
const DenseVector<VT2,TF>& rhs )
2206 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
2210 Iterator left(
begin() );
2211 ConstIterator_<VT2> right( (~rhs).
begin() );
2213 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2214 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2215 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2216 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2217 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2219 for( ; i<ipos; i+=SIMDSIZE ) {
2220 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2222 for( ; i<size_; ++i ) {
2223 *left += *right; ++left; ++right;
2242 template<
typename VT
2244 template<
typename VT2 >
2245 inline void Subvector<VT,unaligned,TF,true>::addAssign(
const SparseVector<VT2,TF>& rhs )
2249 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
2250 vector_[offset_+element->index()] += element->value();
2268 template<
typename VT
2270 template<
typename VT2 >
2271 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
2272 Subvector<VT,unaligned,TF,true>::subAssign(
const DenseVector<VT2,TF>& rhs )
2276 const size_t ipos(
size() &
size_t(-2) );
2277 for(
size_t i=0UL; i<ipos; i+=2UL ) {
2278 vector_[offset_+i ] -= (~rhs)[i ];
2279 vector_[offset_+i+1UL] -= (~rhs)[i+1UL];
2281 if( ipos <
size() ) {
2282 vector_[offset_+ipos] -= (~rhs)[ipos];
2301 template<
typename VT
2303 template<
typename VT2 >
2304 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
2305 Subvector<VT,unaligned,TF,true>::subAssign(
const DenseVector<VT2,TF>& rhs )
2311 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
2315 Iterator left(
begin() );
2316 ConstIterator_<VT2> right( (~rhs).
begin() );
2318 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2319 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2320 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2321 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2322 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2324 for( ; i<ipos; i+=SIMDSIZE ) {
2325 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2327 for( ; i<size_; ++i ) {
2328 *left -= *right; ++left; ++right;
2347 template<
typename VT
2349 template<
typename VT2 >
2350 inline void Subvector<VT,unaligned,TF,true>::subAssign(
const SparseVector<VT2,TF>& rhs )
2354 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
2355 vector_[offset_+element->index()] -= element->value();
2373 template<
typename VT
2375 template<
typename VT2 >
2376 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
2377 Subvector<VT,unaligned,TF,true>::multAssign(
const DenseVector<VT2,TF>& rhs )
2381 const size_t ipos(
size() &
size_t(-2) );
2382 for(
size_t i=0UL; i<ipos; i+=2UL ) {
2383 vector_[offset_+i ] *= (~rhs)[i ];
2384 vector_[offset_+i+1UL] *= (~rhs)[i+1UL];
2386 if( ipos <
size() ) {
2387 vector_[offset_+ipos] *= (~rhs)[ipos];
2406 template<
typename VT
2408 template<
typename VT2 >
2409 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
2410 Subvector<VT,unaligned,TF,true>::multAssign(
const DenseVector<VT2,TF>& rhs )
2416 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
2420 Iterator left(
begin() );
2421 ConstIterator_<VT2> right( (~rhs).
begin() );
2423 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2424 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2425 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2426 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2427 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2429 for( ; i<ipos; i+=SIMDSIZE ) {
2430 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2432 for( ; i<size_; ++i ) {
2433 *left *= *right; ++left; ++right;
2452 template<
typename VT
2454 template<
typename VT2 >
2455 inline void Subvector<VT,unaligned,TF,true>::multAssign(
const SparseVector<VT2,TF>& rhs )
2459 const ResultType tmp(
serial( *
this ) );
2463 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
2464 vector_[offset_+element->index()] = tmp[element->index()] * element->value();
2482 template<
typename VT
2484 template<
typename VT2 >
2485 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
2486 Subvector<VT,unaligned,TF,true>::divAssign(
const DenseVector<VT2,TF>& rhs )
2490 const size_t ipos(
size() &
size_t(-2) );
2491 for(
size_t i=0UL; i<ipos; i+=2UL ) {
2492 vector_[offset_+i ] /= (~rhs)[i ];
2493 vector_[offset_+i+1UL] /= (~rhs)[i+1UL];
2495 if( ipos <
size() ) {
2496 vector_[offset_+ipos] /= (~rhs)[ipos];
2515 template<
typename VT
2517 template<
typename VT2 >
2518 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
2519 Subvector<VT,unaligned,TF,true>::divAssign(
const DenseVector<VT2,TF>& rhs )
2525 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
2529 Iterator left(
begin() );
2530 ConstIterator_<VT2> right( (~rhs).
begin() );
2532 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2533 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2534 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2535 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2536 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2538 for( ; i<ipos; i+=SIMDSIZE ) {
2539 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2541 for( ; i<size_; ++i ) {
2542 *left /= *right; ++left; ++right;
2569 template<
typename VT
2571 class Subvector<VT,
aligned,TF,true>
2572 :
public DenseVector< Subvector<VT,aligned,TF,true>, TF >
2578 typedef If_< IsExpression<VT>, VT, VT& > Operand;
2583 typedef Subvector<VT,aligned,TF,true>
This;
2584 typedef DenseVector<This,TF>
BaseType;
2588 typedef SIMDTrait_<ElementType> SIMDType;
2599 typedef const ElementType* ConstPointer;
2602 typedef If_< Or< IsConst<VT>, Not< HasMutableDataAccess<VT> > >, ConstPointer, ElementType* > Pointer;
2613 enum :
bool { simdEnabled = VT::simdEnabled };
2616 enum :
bool { smpAssignable = VT::smpAssignable };
2622 explicit inline Subvector( Operand vector,
size_t index,
size_t n );
2634 inline Reference operator[](
size_t index );
2635 inline ConstReference operator[](
size_t index )
const;
2636 inline Reference at(
size_t index );
2637 inline ConstReference at(
size_t index )
const;
2638 inline Pointer data () noexcept;
2639 inline ConstPointer data () const noexcept;
2640 inline Iterator
begin ();
2641 inline ConstIterator begin () const;
2642 inline ConstIterator
cbegin() const;
2643 inline Iterator
end ();
2644 inline ConstIterator end () const;
2645 inline ConstIterator
cend () const;
2652 inline Subvector& operator= ( const ElementType& rhs );
2653 inline Subvector& operator= ( initializer_list<ElementType> list );
2654 inline Subvector& operator= ( const Subvector& rhs );
2655 template< typename VT2 > inline Subvector& operator= ( const Vector<VT2,TF>& rhs );
2656 template< typename VT2 > inline Subvector& operator+=( const Vector<VT2,TF>& rhs );
2657 template< typename VT2 > inline Subvector& operator-=( const Vector<VT2,TF>& rhs );
2658 template< typename VT2 > inline Subvector& operator*=( const DenseVector<VT2,TF>& rhs );
2659 template< typename VT2 > inline Subvector& operator*=( const SparseVector<VT2,TF>& rhs );
2660 template< typename VT2 > inline Subvector& operator/=( const DenseVector<VT2,TF>& rhs );
2662 template< typename Other >
2663 inline
EnableIf_< IsNumeric<Other>, Subvector >& operator*=( Other rhs );
2665 template< typename Other >
2666 inline
EnableIf_< IsNumeric<Other>, Subvector >& operator/=( Other rhs );
2673 inline
size_t size() const noexcept;
2674 inline
size_t capacity() const noexcept;
2676 inline
void reset();
2677 template< typename Other > inline Subvector& scale( const Other& scalar );
2684 template< typename VT2 >
2685 struct VectorizedAssign {
2687 simdEnabled && VT2::simdEnabled &&
2688 AreSIMDCombinable< ElementType, ElementType_<VT2> >::value };
2694 template<
typename VT2 >
2695 struct VectorizedAddAssign {
2697 simdEnabled && VT2::simdEnabled &&
2698 AreSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2699 HasSIMDAdd< ElementType, ElementType_<VT2> >::value };
2705 template<
typename VT2 >
2706 struct VectorizedSubAssign {
2708 simdEnabled && VT2::simdEnabled &&
2709 AreSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2710 HasSIMDSub< ElementType, ElementType_<VT2> >::value };
2716 template<
typename VT2 >
2717 struct VectorizedMultAssign {
2719 simdEnabled && VT2::simdEnabled &&
2720 AreSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2721 HasSIMDMult< ElementType, ElementType_<VT2> >::value };
2727 template<
typename VT2 >
2728 struct VectorizedDivAssign {
2730 simdEnabled && VT2::simdEnabled &&
2731 AreSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2732 HasSIMDDiv< ElementType, ElementType_<VT2> >::value };
2745 template<
typename Other >
2746 inline bool canAlias(
const Other* alias )
const noexcept;
2748 template<
typename VT2,
bool AF2,
bool TF2 >
2749 inline bool canAlias(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept;
2751 template<
typename Other >
2752 inline bool isAliased(
const Other* alias )
const noexcept;
2754 template<
typename VT2,
bool AF2,
bool TF2 >
2755 inline bool isAliased(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept;
2757 inline bool isAligned () const noexcept;
2758 inline
bool canSMPAssign() const noexcept;
2769 template< typename VT2 >
2770 inline
DisableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
2772 template< typename VT2 >
2773 inline
EnableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
2775 template< typename VT2 > inline
void assign( const SparseVector<VT2,TF>& rhs );
2777 template< typename VT2 >
2778 inline
DisableIf_< VectorizedAddAssign<VT2> > addAssign( const DenseVector <VT2,TF>& rhs );
2780 template< typename VT2 >
2781 inline
EnableIf_< VectorizedAddAssign<VT2> > addAssign ( const DenseVector <VT2,TF>& rhs );
2783 template< typename VT2 > inline
void addAssign( const SparseVector<VT2,TF>& rhs );
2785 template< typename VT2 >
2786 inline
DisableIf_< VectorizedSubAssign<VT2> > subAssign ( const DenseVector <VT2,TF>& rhs );
2788 template< typename VT2 >
2789 inline
EnableIf_< VectorizedSubAssign<VT2> > subAssign( const DenseVector <VT2,TF>& rhs );
2791 template< typename VT2 > inline
void subAssign( const SparseVector<VT2,TF>& rhs );
2793 template< typename VT2 >
2794 inline
DisableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
2796 template< typename VT2 >
2797 inline
EnableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
2799 template< typename VT2 > inline
void multAssign( const SparseVector<VT2,TF>& rhs );
2801 template< typename VT2 >
2802 inline
DisableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
2804 template< typename VT2 >
2805 inline
EnableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
2814 const
size_t offset_;
2820 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 > friend class Subvector;
2822 template<
bool AF1, typename VT2,
bool AF2,
bool TF2,
bool DF2 >
2823 friend const Subvector<VT2,AF1,TF2,DF2>
2824 subvector( const Subvector<VT2,AF2,TF2,DF2>& sv,
size_t index,
size_t size );
2826 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
2827 friend
bool isIntact( const Subvector<VT2,AF2,TF2,DF2>& sv ) noexcept;
2829 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
2830 friend
bool isSame( const Subvector<VT2,AF2,TF2,DF2>& a, const Vector<VT2,TF2>& b ) noexcept;
2832 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
2833 friend
bool isSame( const Vector<VT2,TF2>& a, const Subvector<VT2,AF2,TF2,DF2>& b ) noexcept;
2835 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
2836 friend
bool isSame( const Subvector<VT2,AF2,TF2,DF2>& a, const Subvector<VT2,AF2,TF2,DF2>& b ) noexcept;
2838 template< typename VT2,
bool AF2,
bool TF2,
bool DF2, typename VT3 >
2839 friend
bool tryAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs,
size_t index );
2841 template< typename VT2,
bool AF2,
bool TF2,
bool DF2, typename VT3 >
2842 friend
bool tryAddAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs,
size_t index );
2844 template< typename VT2,
bool AF2,
bool TF2,
bool DF2, typename VT3 >
2845 friend
bool trySubAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs,
size_t index );
2847 template< typename VT2,
bool AF2,
bool TF2,
bool DF2, typename VT3 >
2848 friend
bool tryMultAssign( const Subvector<VT2,AF2,TF2,DF2>& lhs, const Vector<VT3,TF2>& rhs,
size_t index );
2850 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 >
2851 friend
DerestrictTrait_< Subvector<VT2,AF2,TF2,DF2> > derestrict( Subvector<VT2,AF2,TF2,DF2>& sv );
2887 template< typename VT
2889 inline Subvector<VT,
aligned,TF,true>::Subvector( Operand vector,
size_t index,
size_t n )
2894 if( index + n > vector.size() ) {
2898 if( simdEnabled && vector_.data() !=
nullptr && !
checkAlignment( data() ) ) {
2921 template<
typename VT
2924 Subvector<VT,aligned,TF,true>::operator[](
size_t index )
2927 return vector_[offset_+index];
2940 template<
typename VT
2943 Subvector<VT,aligned,TF,true>::operator[](
size_t index )
const
2946 return const_cast<const VT&
>( vector_ )[offset_+index];
2963 template<
typename VT
2966 Subvector<VT,aligned,TF,true>::at(
size_t index )
2968 if( index >=
size() ) {
2971 return (*
this)[index];
2988 template<
typename VT
2991 Subvector<VT,aligned,TF,true>::at(
size_t index )
const
2993 if( index >=
size() ) {
2996 return (*
this)[index];
3010 template<
typename VT
3012 inline typename Subvector<VT,aligned,TF,true>::Pointer Subvector<VT,aligned,TF,true>::data() noexcept
3014 return vector_.data() + offset_;
3028 template<
typename VT
3030 inline typename Subvector<VT,aligned,TF,true>::ConstPointer
3031 Subvector<VT,aligned,TF,true>::data() const noexcept
3033 return vector_.data() + offset_;
3047 template<
typename VT
3051 return ( vector_.begin() + offset_ );
3065 template<
typename VT
3070 return ( vector_.cbegin() + offset_ );
3084 template<
typename VT
3089 return ( vector_.cbegin() + offset_ );
3103 template<
typename VT
3107 return ( vector_.begin() + offset_ + size_ );
3121 template<
typename VT
3126 return ( vector_.cbegin() + offset_ + size_ );
3140 template<
typename VT
3145 return ( vector_.cbegin() + offset_ + size_ );
3166 template<
typename VT
3168 inline Subvector<VT,aligned,TF,true>&
3169 Subvector<VT,aligned,TF,true>::operator=(
const ElementType& rhs )
3171 const size_t iend( offset_ + size_ );
3173 for(
size_t i=offset_; i<iend; ++i )
3195 template<
typename VT
3197 inline Subvector<VT,aligned,TF,true>&
3198 Subvector<VT,aligned,TF,true>::operator=( initializer_list<ElementType> list )
3200 if( list.size() >
size() ) {
3226 template<
typename VT
3228 inline Subvector<VT,aligned,TF,true>&
3229 Subvector<VT,aligned,TF,true>::operator=(
const Subvector& rhs )
3234 if( &rhs ==
this || ( &vector_ == &rhs.vector_ && offset_ == rhs.offset_ ) )
3237 if(
size() != rhs.size() ) {
3241 if( !tryAssign( vector_, rhs, offset_ ) ) {
3245 DerestrictTrait_<This> left( derestrict( *
this ) );
3247 if( rhs.canAlias( &vector_ ) ) {
3248 const ResultType tmp( ~rhs );
3275 template<
typename VT
3277 template<
typename VT2 >
3278 inline Subvector<VT,aligned,TF,true>&
3279 Subvector<VT,aligned,TF,true>::operator=(
const Vector<VT2,TF>& rhs )
3288 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
3289 Right right( ~rhs );
3291 if( !tryAssign( vector_, right, offset_ ) ) {
3295 DerestrictTrait_<This> left( derestrict( *
this ) );
3297 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3298 const ResultType_<VT2> tmp( right );
3302 if( IsSparseVector<VT2>::value )
3327 template<
typename VT
3329 template<
typename VT2 >
3330 inline Subvector<VT,aligned,TF,true>&
3340 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
3341 Right right( ~rhs );
3343 if( !tryAddAssign( vector_, right, offset_ ) ) {
3347 DerestrictTrait_<This> left( derestrict( *
this ) );
3349 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3350 const ResultType_<VT2> tmp( right );
3377 template<
typename VT
3379 template<
typename VT2 >
3380 inline Subvector<VT,aligned,TF,true>&
3390 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
3391 Right right( ~rhs );
3393 if( !trySubAssign( vector_, right, offset_ ) ) {
3397 DerestrictTrait_<This> left( derestrict( *
this ) );
3399 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3400 const ResultType_<VT2> tmp( right );
3428 template<
typename VT
3430 template<
typename VT2 >
3431 inline Subvector<VT,aligned,TF,true>&
3441 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
3442 Right right( ~rhs );
3444 if( !tryMultAssign( vector_, right, offset_ ) ) {
3448 DerestrictTrait_<This> left( derestrict( *
this ) );
3450 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3451 const ResultType_<VT2> tmp( right );
3479 template<
typename VT
3481 template<
typename VT2 >
3482 inline Subvector<VT,aligned,TF,true>&
3492 const ResultType tmp( *
this * (~rhs) );
3494 if( !tryAssign( vector_, tmp, offset_ ) ) {
3498 DerestrictTrait_<This> left( derestrict( *
this ) );
3522 template<
typename VT
3524 template<
typename VT2 >
3525 inline Subvector<VT,aligned,TF,true>&
3535 typedef If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& > Right;
3536 Right right( ~rhs );
3538 if( !tryDivAssign( vector_, right, offset_ ) ) {
3542 DerestrictTrait_<This> left( derestrict( *
this ) );
3544 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3545 const ResultType_<VT2> tmp( right );
3568 template<
typename VT
3570 template<
typename Other >
3571 inline EnableIf_< IsNumeric<Other>, Subvector<VT,aligned,TF,true> >&
3574 DerestrictTrait_<This> left( derestrict( *
this ) );
3593 template<
typename VT
3595 template<
typename Other >
3596 inline EnableIf_< IsNumeric<Other>, Subvector<VT,aligned,TF,true> >&
3601 DerestrictTrait_<This> left( derestrict( *
this ) );
3624 template<
typename VT
3640 template<
typename VT
3644 return vector_.capacity() - offset_;
3659 template<
typename VT
3663 size_t nonzeros( 0 );
3665 const size_t iend( offset_ + size_ );
3666 for(
size_t i=offset_; i<iend; ++i ) {
3683 template<
typename VT
3689 const size_t iend( offset_ + size_ );
3690 for(
size_t i=offset_; i<iend; ++i )
3691 clear( vector_[i] );
3704 template<
typename VT
3706 template<
typename Other >
3707 inline Subvector<VT,aligned,TF,true>& Subvector<VT,aligned,TF,true>::scale(
const Other& scalar )
3709 const size_t iend( offset_ + size_ );
3710 for(
size_t i=offset_; i<iend; ++i )
3711 vector_[i] *= scalar;
3737 template<
typename VT
3739 template<
typename Other >
3740 inline bool Subvector<VT,aligned,TF,true>::canAlias(
const Other* alias )
const noexcept
3742 return vector_.isAliased( alias );
3759 template<
typename VT
3761 template<
typename VT2
3764 inline bool Subvector<VT,aligned,TF,true>::canAlias(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept
3766 return ( vector_.isAliased( &alias->vector_ ) &&
3767 ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
3784 template<
typename VT
3786 template<
typename Other >
3787 inline bool Subvector<VT,aligned,TF,true>::isAliased(
const Other* alias )
const noexcept
3789 return vector_.isAliased( alias );
3806 template<
typename VT
3808 template<
typename VT2
3811 inline bool Subvector<VT,aligned,TF,true>::isAliased(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept
3813 return ( vector_.isAliased( &alias->vector_ ) &&
3814 ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
3830 template<
typename VT
3832 inline bool Subvector<VT,aligned,TF,true>::isAligned() const noexcept
3851 template<
typename VT
3853 inline bool Subvector<VT,aligned,TF,true>::canSMPAssign() const noexcept
3855 return (
size() > SMP_DVECASSIGN_THRESHOLD );
3875 template<
typename VT
3878 Subvector<VT,aligned,TF,true>::load(
size_t index )
const noexcept
3880 return loada( index );
3900 template<
typename VT
3911 return vector_.loada( offset_+index );
3931 template<
typename VT
3942 return vector_.loadu( offset_+index );
3963 template<
typename VT
3966 Subvector<VT,aligned,TF,true>::store(
size_t index,
const SIMDType& value ) noexcept
3989 template<
typename VT
4000 vector_.storea( offset_+index, value );
4021 template<
typename VT
4032 vector_.storeu( offset_+index, value );
4053 template<
typename VT
4064 vector_.stream( offset_+index, value );
4082 template<
typename VT
4084 template<
typename VT2 >
4085 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
4086 Subvector<VT,aligned,TF,true>::assign(
const DenseVector<VT2,TF>& rhs )
4090 const size_t ipos(
size() &
size_t(-2) );
4091 for(
size_t i=0UL; i<ipos; i+=2UL ) {
4092 vector_[offset_+i ] = (~rhs)[i ];
4093 vector_[offset_+i+1UL] = (~rhs)[i+1UL];
4095 if( ipos <
size() ) {
4096 vector_[offset_+ipos] = (~rhs)[ipos];
4115 template<
typename VT
4117 template<
typename VT2 >
4118 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
4119 Subvector<VT,aligned,TF,true>::assign(
const DenseVector<VT2,TF>& rhs )
4125 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
4129 Iterator left(
begin() );
4130 ConstIterator_<VT2> right( (~rhs).
begin() );
4132 if(
useStreaming && size_ > (
cacheSize/(
sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( &vector_ ) )
4134 for( ; i<ipos; i+=SIMDSIZE ) {
4135 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4137 for( ; i<size_; ++i ) {
4138 *left = *right; ++left; ++right;
4143 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4144 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4145 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4146 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4147 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4149 for( ; i<ipos; i+=SIMDSIZE ) {
4150 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4152 for( ; i<size_; ++i ) {
4153 *left = *right; ++left; ++right;
4173 template<
typename VT
4175 template<
typename VT2 >
4176 inline void Subvector<VT,aligned,TF,true>::assign(
const SparseVector<VT2,TF>& rhs )
4180 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
4181 vector_[offset_+element->index()] = element->value();
4199 template<
typename VT
4201 template<
typename VT2 >
4202 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
4203 Subvector<VT,aligned,TF,true>::addAssign(
const DenseVector<VT2,TF>& rhs )
4207 const size_t ipos(
size() &
size_t(-2) );
4208 for(
size_t i=0UL; i<ipos; i+=2UL ) {
4209 vector_[offset_+i ] += (~rhs)[i ];
4210 vector_[offset_+i+1UL] += (~rhs)[i+1UL];
4212 if( ipos <
size() ) {
4213 vector_[offset_+ipos] += (~rhs)[ipos];
4232 template<
typename VT
4234 template<
typename VT2 >
4235 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
4236 Subvector<VT,aligned,TF,true>::addAssign(
const DenseVector<VT2,TF>& rhs )
4242 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
4246 Iterator left(
begin() );
4247 ConstIterator_<VT2> right( (~rhs).
begin() );
4249 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4250 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4251 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4252 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4253 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4255 for( ; i<ipos; i+=SIMDSIZE ) {
4256 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4258 for( ; i<size_; ++i ) {
4259 *left += *right; ++left; ++right;
4278 template<
typename VT
4280 template<
typename VT2 >
4281 inline void Subvector<VT,aligned,TF,true>::addAssign(
const SparseVector<VT2,TF>& rhs )
4285 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
4286 vector_[offset_+element->index()] += element->value();
4304 template<
typename VT
4306 template<
typename VT2 >
4307 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
4308 Subvector<VT,aligned,TF,true>::subAssign(
const DenseVector<VT2,TF>& rhs )
4312 const size_t ipos(
size() &
size_t(-2) );
4313 for(
size_t i=0UL; i<ipos; i+=2UL ) {
4314 vector_[offset_+i ] -= (~rhs)[i ];
4315 vector_[offset_+i+1UL] -= (~rhs)[i+1UL];
4317 if( ipos <
size() ) {
4318 vector_[offset_+ipos] -= (~rhs)[ipos];
4337 template<
typename VT
4339 template<
typename VT2 >
4340 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
4341 Subvector<VT,aligned,TF,true>::subAssign(
const DenseVector<VT2,TF>& rhs )
4347 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
4351 Iterator left(
begin() );
4352 ConstIterator_<VT2> right( (~rhs).
begin() );
4354 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4355 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4356 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4357 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4358 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4360 for( ; i<ipos; i+=SIMDSIZE ) {
4361 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4363 for( ; i<size_; ++i ) {
4364 *left -= *right; ++left; ++right;
4383 template<
typename VT
4385 template<
typename VT2 >
4386 inline void Subvector<VT,aligned,TF,true>::subAssign(
const SparseVector<VT2,TF>& rhs )
4390 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
4391 vector_[offset_+element->index()] -= element->value();
4409 template<
typename VT
4411 template<
typename VT2 >
4412 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
4413 Subvector<VT,aligned,TF,true>::multAssign(
const DenseVector<VT2,TF>& rhs )
4417 const size_t ipos(
size() &
size_t(-2) );
4418 for(
size_t i=0UL; i<ipos; i+=2UL ) {
4419 vector_[offset_+i ] *= (~rhs)[i ];
4420 vector_[offset_+i+1UL] *= (~rhs)[i+1UL];
4422 if( ipos <
size() ) {
4423 vector_[offset_+ipos] *= (~rhs)[ipos];
4442 template<
typename VT
4444 template<
typename VT2 >
4445 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
4446 Subvector<VT,aligned,TF,true>::multAssign(
const DenseVector<VT2,TF>& rhs )
4452 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
4456 Iterator left(
begin() );
4457 ConstIterator_<VT2> right( (~rhs).
begin() );
4459 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4460 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4461 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4462 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4463 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4465 for( ; i<ipos; i+=SIMDSIZE ) {
4466 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4468 for( ; i<size_; ++i ) {
4469 *left *= *right; ++left; ++right;
4488 template<
typename VT
4490 template<
typename VT2 >
4491 inline void Subvector<VT,aligned,TF,true>::multAssign(
const SparseVector<VT2,TF>& rhs )
4495 const ResultType tmp(
serial( *
this ) );
4499 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
4500 vector_[offset_+element->index()] = tmp[element->index()] * element->value();
4518 template<
typename VT
4520 template<
typename VT2 >
4521 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
4522 Subvector<VT,aligned,TF,true>::divAssign(
const DenseVector<VT2,TF>& rhs )
4526 const size_t ipos(
size() &
size_t(-2) );
4527 for(
size_t i=0UL; i<ipos; i+=2UL ) {
4528 vector_[offset_+i ] /= (~rhs)[i ];
4529 vector_[offset_+i+1UL] /= (~rhs)[i+1UL];
4531 if( ipos <
size() ) {
4532 vector_[offset_+ipos] /= (~rhs)[ipos];
4551 template<
typename VT
4553 template<
typename VT2 >
4554 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
4555 Subvector<VT,aligned,TF,true>::divAssign(
const DenseVector<VT2,TF>& rhs )
4561 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
4565 Iterator left(
begin() );
4566 ConstIterator_<VT2> right( (~rhs).
begin() );
4568 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4569 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4570 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4571 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4572 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4574 for( ; i<ipos; i+=SIMDSIZE ) {
4575 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4577 for( ; i<size_; ++i ) {
4578 *left /= *right; ++left; ++right;
4605 template<
typename VT1
4608 class Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
4609 :
public DenseVector< Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF >
4614 typedef DVecDVecCrossExpr<VT1,VT2,TF> CPE;
4615 typedef ResultType_<CPE> RT;
4620 typedef Subvector<CPE,unaligned,TF,true>
This;
4621 typedef DenseVector<This,TF>
BaseType;
4631 enum :
bool { simdEnabled =
false };
4634 enum :
bool { smpAssignable =
false };
4644 explicit inline Subvector(
const CPE& vector,
size_t index,
size_t n ) noexcept
4657 inline ReturnType operator[](
size_t index )
const {
4659 return vector_[offset_+index];
4670 inline ReturnType at(
size_t index )
const {
4671 if( index >=
size() ) {
4674 return (*
this)[index];
4683 inline size_t size() const noexcept {
4694 template<
typename T >
4695 inline bool canAlias(
const T* alias )
const noexcept {
4696 return vector_.canAlias( alias );
4706 template<
typename T >
4707 inline bool isAliased(
const T* alias )
const noexcept {
4708 return vector_.isAliased( alias );
4717 const size_t offset_;
4723 template<
bool AF1,
typename VT,
bool AF2,
bool TF2,
bool DF2 >
4724 friend const Subvector<VT,AF1,TF2,DF2>
4725 subvector(
const Subvector<VT,AF2,TF2,DF2>& sv,
size_t index,
size_t size );
4727 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
4728 friend bool isIntact(
const Subvector<VT3,AF,TF2,DF2>& sv ) noexcept;
4730 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
4731 friend bool isSame(
const Subvector<VT3,AF,TF2,DF2>& a,
const Vector<VT3,TF2>& b ) noexcept;
4733 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
4734 friend bool isSame(
const Vector<VT3,TF2>& a,
const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
4736 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
4737 friend bool isSame(
const Subvector<VT3,AF,TF2,DF2>& a,
const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
4739 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
4740 friend bool tryAssign(
const Subvector<VT3,AF,TF2,DF2>& lhs,
const Vector<VT4,TF2>& rhs,
size_t index );
4742 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
4743 friend bool tryAddAssign(
const Subvector<VT2,AF,TF2,DF2>& lhs,
const Vector<VT3,TF2>& rhs,
size_t index );
4745 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
4746 friend bool trySubAssign(
const Subvector<VT2,AF,TF2,DF2>& lhs,
const Vector<VT3,TF2>& rhs,
size_t index );
4748 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
4749 friend bool tryMultAssign(
const Subvector<VT3,AF,TF2,DF2>& lhs,
const Vector<VT4,TF2>& rhs,
size_t index );
4776 template<
typename VT1
4779 class Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
4780 :
public DenseVector< Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF >
4785 typedef DVecSVecCrossExpr<VT1,VT2,TF> CPE;
4786 typedef ResultType_<CPE> RT;
4791 typedef Subvector<CPE,unaligned,TF,true>
This;
4792 typedef DenseVector<This,TF>
BaseType;
4802 enum :
bool { simdEnabled =
false };
4805 enum :
bool { smpAssignable =
false };
4815 explicit inline Subvector(
const CPE& vector,
size_t index,
size_t n ) noexcept
4828 inline ReturnType operator[](
size_t index )
const {
4830 return vector_[offset_+index];
4841 inline ReturnType at(
size_t index )
const {
4842 if( index >=
size() ) {
4845 return (*
this)[index];
4854 inline size_t size() const noexcept {
4865 template<
typename T >
4866 inline bool canAlias(
const T* alias )
const noexcept {
4867 return vector_.canAlias( alias );
4877 template<
typename T >
4878 inline bool isAliased(
const T* alias )
const noexcept {
4879 return vector_.isAliased( alias );
4888 const size_t offset_;
4894 template<
bool AF1,
typename VT,
bool AF2,
bool TF2,
bool DF2 >
4895 friend const Subvector<VT,AF1,TF2,DF2>
4896 subvector(
const Subvector<VT,AF2,TF2,DF2>& sv,
size_t index,
size_t size );
4898 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
4899 friend bool isIntact(
const Subvector<VT3,AF,TF2,DF2>& sv ) noexcept;
4901 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
4902 friend bool isSame(
const Subvector<VT3,AF,TF2,DF2>& a,
const Vector<VT3,TF2>& b ) noexcept;
4904 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
4905 friend bool isSame(
const Vector<VT3,TF2>& a,
const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
4907 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
4908 friend bool isSame(
const Subvector<VT3,AF,TF2,DF2>& a,
const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
4910 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
4911 friend bool tryAssign(
const Subvector<VT3,AF,TF2,DF2>& lhs,
const Vector<VT4,TF2>& rhs,
size_t index );
4913 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
4914 friend bool tryAddAssign(
const Subvector<VT2,AF,TF2,DF2>& lhs,
const Vector<VT3,TF2>& rhs,
size_t index );
4916 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
4917 friend bool trySubAssign(
const Subvector<VT2,AF,TF2,DF2>& lhs,
const Vector<VT3,TF2>& rhs,
size_t index );
4919 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
4920 friend bool tryMultAssign(
const Subvector<VT3,AF,TF2,DF2>& lhs,
const Vector<VT4,TF2>& rhs,
size_t index );
4947 template<
typename VT1
4950 class Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
4951 :
public DenseVector< Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF >
4956 typedef SVecDVecCrossExpr<VT1,VT2,TF> CPE;
4957 typedef ResultType_<CPE> RT;
4962 typedef Subvector<CPE,unaligned,TF,true>
This;
4963 typedef DenseVector<This,TF>
BaseType;
4973 enum :
bool { simdEnabled =
false };
4976 enum :
bool { smpAssignable =
false };
4986 explicit inline Subvector(
const CPE& vector,
size_t index,
size_t n ) noexcept
4999 inline ReturnType operator[](
size_t index )
const {
5001 return vector_[offset_+index];
5012 inline ReturnType at(
size_t index )
const {
5013 if( index >=
size() ) {
5016 return (*
this)[index];
5025 inline size_t size() const noexcept {
5036 template<
typename T >
5037 inline bool canAlias(
const T* alias )
const noexcept {
5038 return vector_.canAlias( alias );
5048 template<
typename T >
5049 inline bool isAliased(
const T* alias )
const noexcept {
5050 return vector_.isAliased( alias );
5059 const size_t offset_;
5065 template<
bool AF1,
typename VT,
bool AF2,
bool TF2,
bool DF2 >
5066 friend const Subvector<VT,AF1,TF2,DF2>
5067 subvector(
const Subvector<VT,AF2,TF2,DF2>& sv,
size_t index,
size_t size );
5069 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
5070 friend bool isIntact(
const Subvector<VT3,AF,TF2,DF2>& sv ) noexcept;
5072 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
5073 friend bool isSame(
const Subvector<VT3,AF,TF2,DF2>& a,
const Vector<VT3,TF2>& b ) noexcept;
5075 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
5076 friend bool isSame(
const Vector<VT3,TF2>& a,
const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
5078 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
5079 friend bool isSame(
const Subvector<VT3,AF,TF2,DF2>& a,
const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
5081 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
5082 friend bool tryAssign(
const Subvector<VT3,AF,TF2,DF2>& lhs,
const Vector<VT4,TF2>& rhs,
size_t index );
5084 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
5085 friend bool tryAddAssign(
const Subvector<VT2,AF,TF2,DF2>& lhs,
const Vector<VT3,TF2>& rhs,
size_t index );
5087 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
5088 friend bool trySubAssign(
const Subvector<VT2,AF,TF2,DF2>& lhs,
const Vector<VT3,TF2>& rhs,
size_t index );
5090 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
5091 friend bool tryMultAssign(
const Subvector<VT3,AF,TF2,DF2>& lhs,
const Vector<VT4,TF2>& rhs,
size_t index );
5118 template<
typename VT1
5121 class Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
5122 :
public DenseVector< Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF >
5127 typedef SVecSVecCrossExpr<VT1,VT2,TF> CPE;
5128 typedef ResultType_<CPE> RT;
5133 typedef Subvector<CPE,unaligned,TF,true>
This;
5134 typedef DenseVector<This,TF>
BaseType;
5144 enum :
bool { simdEnabled =
false };
5147 enum :
bool { smpAssignable =
false };
5157 explicit inline Subvector(
const CPE& vector,
size_t index,
size_t n ) noexcept
5170 inline ReturnType operator[](
size_t index )
const {
5172 return vector_[offset_+index];
5183 inline ReturnType at(
size_t index )
const {
5184 if( index >=
size() ) {
5187 return (*
this)[index];
5196 inline size_t size() const noexcept {
5207 template<
typename T >
5208 inline bool canAlias(
const T* alias )
const noexcept {
5209 return vector_.canAlias( alias );
5219 template<
typename T >
5220 inline bool isAliased(
const T* alias )
const {
5221 return vector_.isAliased( alias );
5230 const size_t offset_;
5236 template<
bool AF1,
typename VT,
bool AF2,
bool TF2,
bool DF2 >
5237 friend const Subvector<VT,AF1,TF2,DF2>
5238 subvector(
const Subvector<VT,AF2,TF2,DF2>& sv,
size_t index,
size_t size );
5240 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
5241 friend bool isIntact(
const Subvector<VT3,AF,TF2,DF2>& sv ) noexcept;
5243 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
5244 friend bool isSame(
const Subvector<VT3,AF,TF2,DF2>& a,
const Vector<VT3,TF2>& b ) noexcept;
5246 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
5247 friend bool isSame(
const Vector<VT3,TF2>& a,
const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
5249 template<
typename VT3,
bool AF,
bool TF2,
bool DF2 >
5250 friend bool isSame(
const Subvector<VT3,AF,TF2,DF2>& a,
const Subvector<VT3,AF,TF2,DF2>& b ) noexcept;
5252 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
5253 friend bool tryAssign(
const Subvector<VT3,AF,TF2,DF2>& lhs,
const Vector<VT4,TF2>& rhs,
size_t index );
5255 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
5256 friend bool tryAddAssign(
const Subvector<VT2,AF,TF2,DF2>& lhs,
const Vector<VT3,TF2>& rhs,
size_t index );
5258 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
5259 friend bool trySubAssign(
const Subvector<VT2,AF,TF2,DF2>& lhs,
const Vector<VT3,TF2>& rhs,
size_t index );
5261 template<
typename VT3,
bool AF,
bool TF2,
bool DF2,
typename VT4 >
5262 friend bool tryMultAssign(
const Subvector<VT3,AF,TF2,DF2>& lhs,
const Vector<VT4,TF2>& rhs,
size_t index );
Constraint on the data type.
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
constexpr bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
typename DerestrictTrait< T >::Type DerestrictTrait_
Auxiliary alias declaration for the DerestrictTrait type trait.The DerestrictTrait_ alias declaration...
Definition: DerestrictTrait.h:110
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the alignment flag values.
const DMatDMatMultExpr< T1, T2 > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:7800
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:346
BLAZE_ALWAYS_INLINE bool isSame(const Matrix< MT1, SO1 > &a, const Matrix< MT2, SO2 > &b) noexcept
Returns whether the two given matrices represent the same observable state.
Definition: Matrix.h:653
Header file for basic type definitions.
Header file for the View base class.
bool operator<=(const NegativeAccuracy< A > &, const T &rhs)
Less-or-equal-than comparison between a NegativeAccuracy object and a floating point value...
Definition: Accuracy.h:404
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:79
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:160
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:258
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i...
Definition: Computation.h:81
constexpr size_t cacheSize
Cache size of the target architecture.This setting specifies the available cache size in Byte of the ...
Definition: CacheSize.h:48
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1339
const bool aligned
Alignment flag for aligned vectors and matrices.Via this flag it is possible to specify subvectors...
Definition: AlignmentFlag.h:85
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:188
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:533
const DenseIterator< Type, AF > operator+(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Addition between a DenseIterator and an integral value.
Definition: DenseIterator.h:699
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2643
EnableIf_< IsDenseVector< VT1 > > smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP multiplication assignment of a vector to a dense vector...
Definition: DenseVector.h:193
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:223
bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:366
Header file for the DenseVector base class.
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2636
bool operator>=(const NegativeAccuracy< A > &, const T &rhs)
Greater-or-equal-than comparison between a NegativeAccuracy object and a floating point value...
Definition: Accuracy.h:442
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:723
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:384
Header file for the Computation base class.
const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:731
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i...
Definition: TransExpr.h:81
System settings for performance optimizations.
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1321
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:77
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:129
BLAZE_ALWAYS_INLINE MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:298
BLAZE_ALWAYS_INLINE MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:232
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
Header file for the std::initializer_list aliases.
Constraint on the data type.
SubvectorExprTrait_< VT, unaligned > subvector(Vector< VT, TF > &vector, size_t index, size_t size)
Creating a view on a specific subvector of the given vector.
Definition: Subvector.h:152
Header file for the DisableIf class template.
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Header file for nested template disabiguation.
Header file for the If class template.
constexpr bool useStreaming
Configuration of the streaming behavior.For large vectors and matrices non-temporal stores can provid...
Definition: Optimizations.h:68
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2647
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:98
Header file for the Or class template.
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the HasSIMDAdd type trait.
Header file for the implementation of the Subvector base template.
Header file for the Not class template.
Header file for all SIMD functionality.
Constraint on the data type.
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:80
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not a vectorizable data type...
Definition: Vectorizable.h:61
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:2640
Constraint on the data type.
Header file for the exception macros of the math module.
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:254
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2641
const bool unaligned
Alignment flag for unaligned vectors and matrices.Via this flag it is possible to specify subvectors...
Definition: AlignmentFlag.h:64
Constraint on the data type.
Header file for all forward declarations for expression class templates.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2645
Header file for the EnableIf class template.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:553
Header file for the DerestrictTrait class template.
Header file for the CrossExpr base class.
Header file for the IsNumeric type trait.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:75
Header file for the IsSparseVector type trait.
Header file for the HasSIMDMult type trait.
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2642
Header file for the IsConst type trait.
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1285
Header file for run time assertion macros.
EnableIf_< IsDenseVector< VT1 > > smpDivAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP division assignment of a vector to a dense vector.
Definition: DenseVector.h:222
Header file for the cache size of the target architecture.
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2646
Header file for the isDefault shim.
Header file for the HasSIMDSub type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:223
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:76
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional vector type...
Definition: DenseVector.h:61
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2637
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBVECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is a subvector type (i.e. a dense or sparse subvector), a compilation error is created.
Definition: Subvector.h:81
Header file for the AreSIMDCombinable type trait.
bool operator<(const NegativeAccuracy< A > &lhs, const T &rhs)
Less-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:328
Header file for the HasSIMDDiv type trait.
Header file for the alignment check function.
bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:249
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2638
bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:289
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:240
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2644
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1303
Header file for the IsRestricted type trait.
System settings for the inline keywords.
#define BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG(T, TF)
Constraint on the data type.In case the given data type T is not a dense or sparse vector type and in...
Definition: TransposeFlag.h:63
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the IsExpression type trait class.