35 #ifndef _BLAZE_MATH_VIEWS_SUBVECTOR_DENSE_H_ 36 #define _BLAZE_MATH_VIEWS_SUBVECTOR_DENSE_H_ 106 template<
typename VT
109 :
public View< DenseVector< Subvector<VT,unaligned,TF,true>, TF > >
114 using Operand = If_< IsExpression<VT>, VT, VT& >;
119 using This = Subvector<VT,unaligned,TF,true>;
120 using BaseType = DenseVector<This,TF>;
124 using SIMDType = SIMDTrait_<ElementType>;
138 using Pointer = If_< Or< IsConst<VT>, Not< HasMutableDataAccess<VT> > >, ConstPointer,
ElementType* >;
144 template<
typename IteratorType >
145 class SubvectorIterator
150 using IteratorCategory =
typename std::iterator_traits<IteratorType>::iterator_category;
153 using ValueType =
typename std::iterator_traits<IteratorType>::value_type;
156 using PointerType =
typename std::iterator_traits<IteratorType>::pointer;
159 using ReferenceType =
typename std::iterator_traits<IteratorType>::reference;
162 using DifferenceType =
typename std::iterator_traits<IteratorType>::difference_type;
165 using iterator_category = IteratorCategory;
166 using value_type = ValueType;
167 using pointer = PointerType;
168 using reference = ReferenceType;
169 using difference_type = DifferenceType;
175 inline SubvectorIterator()
177 , isAligned_( false )
187 inline SubvectorIterator( IteratorType iterator,
bool isMemoryAligned )
188 : iterator_ ( iterator )
189 , isAligned_( isMemoryAligned )
198 template<
typename IteratorType2 >
199 inline SubvectorIterator(
const SubvectorIterator<IteratorType2>& it )
200 : iterator_ ( it.base() )
201 , isAligned_( it.isAligned() )
211 inline SubvectorIterator&
operator+=(
size_t inc ) {
223 inline SubvectorIterator&
operator-=(
size_t dec ) {
234 inline SubvectorIterator& operator++() {
245 inline const SubvectorIterator operator++(
int ) {
246 return SubvectorIterator( iterator_++, isAligned_ );
255 inline SubvectorIterator& operator--() {
266 inline const SubvectorIterator operator--(
int ) {
267 return SubvectorIterator( iterator_--, isAligned_ );
291 inline SIMDType load()
const {
306 inline SIMDType
loada()
const {
307 return iterator_.loada();
321 inline SIMDType
loadu()
const {
323 return iterator_.loada();
326 return iterator_.loadu();
342 inline void store(
const SIMDType& value )
const {
358 inline void storea(
const SIMDType& value )
const {
359 iterator_.storea( value );
374 inline void storeu(
const SIMDType& value )
const {
376 iterator_.storea( value );
379 iterator_.storeu( value );
395 inline void stream(
const SIMDType& value )
const {
396 iterator_.stream( value );
406 inline bool operator==(
const SubvectorIterator& rhs )
const {
407 return iterator_ == rhs.iterator_;
417 inline bool operator!=(
const SubvectorIterator& rhs )
const {
418 return iterator_ != rhs.iterator_;
428 inline bool operator<(
const SubvectorIterator& rhs )
const {
429 return iterator_ < rhs.iterator_;
439 inline bool operator>(
const SubvectorIterator& rhs )
const {
440 return iterator_ > rhs.iterator_;
450 inline bool operator<=(
const SubvectorIterator& rhs )
const {
451 return iterator_ <= rhs.iterator_;
461 inline bool operator>=(
const SubvectorIterator& rhs )
const {
462 return iterator_ >= rhs.iterator_;
472 inline DifferenceType
operator-(
const SubvectorIterator& rhs )
const {
473 return iterator_ - rhs.iterator_;
484 friend inline const SubvectorIterator
operator+(
const SubvectorIterator& it,
size_t inc ) {
485 return SubvectorIterator( it.iterator_ + inc, it.isAligned_ );
496 friend inline const SubvectorIterator
operator+(
size_t inc,
const SubvectorIterator& it ) {
497 return SubvectorIterator( it.iterator_ + inc, it.isAligned_ );
508 friend inline const SubvectorIterator
operator-(
const SubvectorIterator& it,
size_t dec ) {
509 return SubvectorIterator( it.iterator_ - dec, it.isAligned_ );
518 inline IteratorType base()
const {
528 inline bool isAligned()
const {
535 IteratorType iterator_;
543 using ConstIterator = SubvectorIterator< ConstIterator_<VT> >;
551 enum :
bool { simdEnabled = VT::simdEnabled };
554 enum :
bool { smpAssignable = VT::smpAssignable };
560 explicit inline Subvector( Operand vector,
size_t index,
size_t n );
572 inline Reference operator[](
size_t index );
573 inline ConstReference operator[](
size_t index )
const;
575 inline ConstReference at(
size_t index )
const;
576 inline Pointer data () noexcept;
577 inline ConstPointer data () const noexcept;
579 inline ConstIterator begin () const;
580 inline ConstIterator
cbegin() const;
582 inline ConstIterator end () const;
583 inline ConstIterator
cend () const;
590 inline Subvector& operator= ( const ElementType& rhs );
591 inline Subvector& operator= ( initializer_list<ElementType> list );
592 inline Subvector& operator= ( const Subvector& rhs );
593 template< typename VT2 > inline Subvector& operator= ( const Vector<VT2,TF>& 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 DenseVector<VT2,TF>& rhs );
597 template< typename VT2 > inline Subvector& operator*=( const SparseVector<VT2,TF>& rhs );
598 template< typename VT2 > inline Subvector& operator/=( const DenseVector<VT2,TF>& rhs );
599 template< typename VT2 > inline Subvector& operator%=( const Vector<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 Operand operand() const noexcept;
613 inline
size_t offset() const noexcept;
614 inline
size_t size() const noexcept;
615 inline
size_t spacing() const noexcept;
616 inline
size_t capacity() const noexcept;
625 template< typename Other > inline Subvector& scale( const Other& scalar );
632 template< typename VT2 >
633 struct VectorizedAssign {
634 enum :
bool { value = useOptimizedKernels &&
635 simdEnabled && VT2::simdEnabled &&
636 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value };
642 template<
typename VT2 >
643 struct VectorizedAddAssign {
644 enum :
bool { value = useOptimizedKernels &&
645 simdEnabled && VT2::simdEnabled &&
646 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
647 HasSIMDAdd< ElementType, ElementType_<VT2> >::value };
653 template<
typename VT2 >
654 struct VectorizedSubAssign {
655 enum :
bool { value = useOptimizedKernels &&
656 simdEnabled && VT2::simdEnabled &&
657 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
658 HasSIMDSub< ElementType, ElementType_<VT2> >::value };
664 template<
typename VT2 >
665 struct VectorizedMultAssign {
666 enum :
bool { value = useOptimizedKernels &&
667 simdEnabled && VT2::simdEnabled &&
668 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
669 HasSIMDMult< ElementType, ElementType_<VT2> >::value };
675 template<
typename VT2 >
676 struct VectorizedDivAssign {
677 enum :
bool { value = useOptimizedKernels &&
678 simdEnabled && VT2::simdEnabled &&
679 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
680 HasSIMDDiv< ElementType, ElementType_<VT2> >::value };
693 template<
typename Other >
694 inline bool canAlias(
const Other* alias )
const noexcept;
696 template<
typename VT2,
bool AF2,
bool TF2 >
697 inline bool canAlias(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept;
699 template<
typename Other >
700 inline bool isAliased(
const Other* alias )
const noexcept;
702 template<
typename VT2,
bool AF2,
bool TF2 >
703 inline bool isAliased(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept;
705 inline bool isAligned () const noexcept;
706 inline
bool canSMPAssign() const noexcept;
717 template< typename VT2 >
718 inline
DisableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
720 template< typename VT2 >
721 inline
EnableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
723 template< typename VT2 > inline
void assign( const SparseVector<VT2,TF>& rhs );
725 template< typename VT2 >
726 inline
DisableIf_< VectorizedAddAssign<VT2> > addAssign( const DenseVector <VT2,TF>& rhs );
728 template< typename VT2 >
729 inline
EnableIf_< VectorizedAddAssign<VT2> > addAssign ( const DenseVector <VT2,TF>& rhs );
731 template< typename VT2 > inline
void addAssign( const SparseVector<VT2,TF>& rhs );
733 template< typename VT2 >
734 inline
DisableIf_< VectorizedSubAssign<VT2> > subAssign ( const DenseVector <VT2,TF>& rhs );
736 template< typename VT2 >
737 inline
EnableIf_< VectorizedSubAssign<VT2> > subAssign( const DenseVector <VT2,TF>& rhs );
739 template< typename VT2 > inline
void subAssign( const SparseVector<VT2,TF>& rhs );
741 template< typename VT2 >
742 inline
DisableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
744 template< typename VT2 >
745 inline
EnableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
747 template< typename VT2 > inline
void multAssign( const SparseVector<VT2,TF>& rhs );
749 template< typename VT2 >
750 inline
DisableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
752 template< typename VT2 >
753 inline
EnableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
762 const
size_t offset_;
764 const
bool isAligned_;
775 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 > friend class Subvector;
811 template< typename VT
813 inline Subvector<VT,
unaligned,TF,true>::Subvector( Operand vector,
size_t index,
size_t n )
817 , isAligned_( simdEnabled && vector.data() !=
nullptr &&
checkAlignment( data() ) )
819 if( index + n > vector.size() ) {
845 template<
typename VT
848 Subvector<VT,unaligned,TF,true>::operator[](
size_t index )
851 return vector_[offset_+index];
867 template<
typename VT
870 Subvector<VT,unaligned,TF,true>::operator[](
size_t index )
const 873 return const_cast<const VT&
>( vector_ )[offset_+index];
890 template<
typename VT
893 Subvector<VT,unaligned,TF,true>::at(
size_t index )
895 if( index >=
size() ) {
898 return (*
this)[index];
915 template<
typename VT
918 Subvector<VT,unaligned,TF,true>::at(
size_t index )
const 920 if( index >=
size() ) {
923 return (*
this)[index];
937 template<
typename VT
939 inline typename Subvector<VT,unaligned,TF,true>::Pointer
940 Subvector<VT,unaligned,TF,true>::data() noexcept
942 return vector_.data() + offset_;
956 template<
typename VT
958 inline typename Subvector<VT,unaligned,TF,true>::ConstPointer
959 Subvector<VT,unaligned,TF,true>::data() const noexcept
961 return vector_.data() + offset_;
975 template<
typename VT
980 return Iterator( vector_.begin() + offset_, isAligned_ );
994 template<
typename VT
999 return ConstIterator( vector_.cbegin() + offset_, isAligned_ );
1013 template<
typename VT
1018 return ConstIterator( vector_.cbegin() + offset_, isAligned_ );
1032 template<
typename VT
1037 return Iterator( vector_.begin() + offset_ + size_, isAligned_ );
1051 template<
typename VT
1056 return ConstIterator( vector_.cbegin() + offset_ + size_, isAligned_ );
1070 template<
typename VT
1075 return ConstIterator( vector_.cbegin() + offset_ + size_, isAligned_ );
1096 template<
typename VT
1098 inline Subvector<VT,unaligned,TF,true>&
1099 Subvector<VT,unaligned,TF,true>::operator=(
const ElementType& rhs )
1101 const size_t iend( offset_ + size_ );
1103 for(
size_t i=offset_; i<iend; ++i )
1125 template<
typename VT
1127 inline Subvector<VT,unaligned,TF,true>&
1128 Subvector<VT,unaligned,TF,true>::operator=( initializer_list<ElementType> list )
1130 if( list.size() >
size() ) {
1156 template<
typename VT
1158 inline Subvector<VT,unaligned,TF,true>&
1159 Subvector<VT,unaligned,TF,true>::operator=(
const Subvector& rhs )
1164 if( &rhs ==
this || ( &vector_ == &rhs.vector_ && offset_ == rhs.offset_ ) )
1167 if(
size() != rhs.size() ) {
1171 if( !tryAssign( vector_, rhs, offset_ ) ) {
1175 decltype(
auto) left( derestrict( *this ) );
1177 if( rhs.canAlias( &vector_ ) ) {
1205 template<
typename VT
1207 template<
typename VT2 >
1208 inline Subvector<VT,unaligned,TF,true>&
1209 Subvector<VT,unaligned,TF,true>::operator=(
const Vector<VT2,TF>& rhs )
1218 using Right = If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& >;
1219 Right right( ~rhs );
1221 if( !tryAssign( vector_, right, offset_ ) ) {
1225 decltype(
auto) left( derestrict( *this ) );
1227 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1228 const ResultType_<VT2> tmp( right );
1232 if( IsSparseVector<VT2>::value )
1257 template<
typename VT
1259 template<
typename VT2 >
1260 inline Subvector<VT,unaligned,TF,true>&
1270 using Right = If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& >;
1271 Right right( ~rhs );
1273 if( !tryAddAssign( vector_, right, offset_ ) ) {
1277 decltype(
auto) left( derestrict( *this ) );
1279 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1280 const ResultType_<VT2> tmp( right );
1307 template<
typename VT
1309 template<
typename VT2 >
1310 inline Subvector<VT,unaligned,TF,true>&
1320 using Right = If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& >;
1321 Right right( ~rhs );
1323 if( !trySubAssign( vector_, right, offset_ ) ) {
1327 decltype(
auto) left( derestrict( *this ) );
1329 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1330 const ResultType_<VT2> tmp( right );
1358 template<
typename VT
1360 template<
typename VT2 >
1361 inline Subvector<VT,unaligned,TF,true>&
1371 using Right = If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& >;
1372 Right right( ~rhs );
1374 if( !tryMultAssign( vector_, right, offset_ ) ) {
1378 decltype(
auto) left( derestrict( *this ) );
1380 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1381 const ResultType_<VT2> tmp( right );
1409 template<
typename VT
1411 template<
typename VT2 >
1412 inline Subvector<VT,unaligned,TF,true>&
1424 if( !tryAssign( vector_, tmp, offset_ ) ) {
1428 decltype(
auto) left( derestrict( *this ) );
1452 template< typename VT
1454 template< typename VT2 >
1455 inline Subvector<VT,unaligned,TF,true>&
1456 Subvector<VT,unaligned,TF,true>::operator/=( const DenseVector<VT2,TF>& rhs )
1465 using Right = If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& >;
1466 Right right( ~rhs );
1468 if( !tryDivAssign( vector_, right, offset_ ) ) {
1472 decltype(
auto) left( derestrict( *this ) );
1474 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
1475 const ResultType_<VT2> tmp( right );
1503 template<
typename VT
1505 template<
typename VT2 >
1506 inline Subvector<VT,unaligned,TF,true>&
1507 Subvector<VT,unaligned,TF,true>::operator%=(
const Vector<VT2,TF>& rhs )
1509 using blaze::assign;
1514 using CrossType = CrossTrait_< ResultType, ResultType_<VT2> >;
1520 if(
size() != 3UL || (~rhs).
size() != 3UL ) {
1524 const CrossType tmp( *
this % (~rhs) );
1526 if( !tryAssign( vector_, tmp, offset_ ) ) {
1530 decltype(
auto) left( derestrict( *this ) );
1532 assign( left, tmp );
1550 template< typename VT
1552 template< typename Other >
1553 inline
EnableIf_< IsNumeric<Other>, Subvector<VT,unaligned,TF,true> >&
1554 Subvector<VT,unaligned,TF,true>::operator*=( Other rhs )
1556 decltype(
auto) left( derestrict( *this ) );
1575 template< typename VT
1577 template< typename Other >
1578 inline
EnableIf_< IsNumeric<Other>, Subvector<VT,unaligned,TF,true> >&
1579 Subvector<VT,unaligned,TF,true>::operator/=( Other rhs )
1583 decltype(
auto) left( derestrict( *this ) );
1606 template< typename VT
1608 inline typename Subvector<VT,unaligned,TF,true>::Operand
1609 Subvector<VT,unaligned,TF,true>::operand() const noexcept
1623 template<
typename VT
1625 inline size_t Subvector<VT,unaligned,TF,true>::offset() const noexcept
1639 template<
typename VT
1658 template<
typename VT
1662 return vector_.spacing() - offset_;
1674 template<
typename VT
1678 return vector_.capacity() - offset_;
1693 template<
typename VT
1697 size_t nonzeros( 0 );
1699 const size_t iend( offset_ + size_ );
1700 for(
size_t i=offset_; i<iend; ++i ) {
1717 template<
typename VT
1723 const size_t iend( offset_ + size_ );
1724 for(
size_t i=offset_; i<iend; ++i )
1725 clear( vector_[i] );
1750 template<
typename VT
1752 template<
typename Other >
1753 inline Subvector<VT,unaligned,TF,true>&
1754 Subvector<VT,unaligned,TF,true>::scale(
const Other& scalar )
1756 const size_t iend( offset_ + size_ );
1757 for(
size_t i=offset_; i<iend; ++i )
1758 vector_[i] *= scalar;
1784 template<
typename VT
1786 template<
typename Other >
1787 inline bool Subvector<VT,unaligned,TF,true>::canAlias(
const Other* alias )
const noexcept
1789 return vector_.isAliased( alias );
1806 template<
typename VT
1808 template<
typename VT2
1811 inline bool Subvector<VT,unaligned,TF,true>::canAlias(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept
1813 return ( vector_.isAliased( &alias->vector_ ) &&
1814 ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
1831 template<
typename VT
1833 template<
typename Other >
1834 inline bool Subvector<VT,unaligned,TF,true>::isAliased(
const Other* alias )
const noexcept
1836 return vector_.isAliased( alias );
1853 template<
typename VT
1855 template<
typename VT2
1858 inline bool Subvector<VT,unaligned,TF,true>::isAliased(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept
1860 return ( vector_.isAliased( &alias->vector_ ) &&
1861 ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
1877 template<
typename VT
1879 inline bool Subvector<VT,unaligned,TF,true>::isAligned() const noexcept
1898 template<
typename VT
1900 inline bool Subvector<VT,unaligned,TF,true>::canSMPAssign() const noexcept
1902 return (
size() > SMP_DVECASSIGN_THRESHOLD );
1922 template<
typename VT
1925 Subvector<VT,unaligned,TF,true>::load(
size_t index )
const noexcept
1928 return loada( index );
1930 return loadu( index );
1950 template<
typename VT
1961 return vector_.loada( offset_+index );
1981 template<
typename VT
1992 return vector_.loadu( offset_+index );
2013 template<
typename VT
2016 Subvector<VT,unaligned,TF,true>::store(
size_t index,
const SIMDType& value ) noexcept
2042 template<
typename VT
2053 vector_.storea( offset_+index, value );
2074 template<
typename VT
2085 vector_.storeu( offset_+index, value );
2106 template<
typename VT
2118 vector_.stream( offset_+index, value );
2120 vector_.storeu( offset_+index, value );
2138 template<
typename VT
2140 template<
typename VT2 >
2141 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
2142 Subvector<VT,unaligned,TF,true>::assign(
const DenseVector<VT2,TF>& rhs )
2146 const size_t ipos(
size() &
size_t(-2) );
2147 for(
size_t i=0UL; i<ipos; i+=2UL ) {
2148 vector_[offset_+i ] = (~rhs)[i ];
2149 vector_[offset_+i+1UL] = (~rhs)[i+1UL];
2151 if( ipos <
size() ) {
2152 vector_[offset_+ipos] = (~rhs)[ipos];
2171 template<
typename VT
2173 template<
typename VT2 >
2174 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
2175 Subvector<VT,unaligned,TF,true>::assign(
const DenseVector<VT2,TF>& rhs )
2181 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
2186 ConstIterator_<VT2> right( (~rhs).
begin() );
2188 if( useStreaming && isAligned_ &&
2189 ( size_ > ( cacheSize/(
sizeof(ElementType) * 3UL ) ) ) &&
2190 !(~rhs).isAliased( &vector_ ) )
2192 for( ; i<ipos; i+=SIMDSIZE ) {
2193 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2195 for( ; i<size_; ++i ) {
2201 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2202 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2203 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2204 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2205 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2207 for( ; i<ipos; i+=SIMDSIZE ) {
2208 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2210 for( ; i<size_; ++i ) {
2211 *left = *right; ++left; ++right;
2231 template<
typename VT
2233 template<
typename VT2 >
2234 inline void Subvector<VT,unaligned,TF,true>::assign(
const SparseVector<VT2,TF>& rhs )
2238 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
2239 vector_[offset_+element->index()] = element->value();
2257 template<
typename VT
2259 template<
typename VT2 >
2260 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
2261 Subvector<VT,unaligned,TF,true>::addAssign(
const DenseVector<VT2,TF>& rhs )
2265 const size_t ipos(
size() &
size_t(-2) );
2266 for(
size_t i=0UL; i<ipos; i+=2UL ) {
2267 vector_[offset_+i ] += (~rhs)[i ];
2268 vector_[offset_+i+1UL] += (~rhs)[i+1UL];
2270 if( ipos <
size() ) {
2271 vector_[offset_+ipos] += (~rhs)[ipos];
2290 template<
typename VT
2292 template<
typename VT2 >
2293 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
2294 Subvector<VT,unaligned,TF,true>::addAssign(
const DenseVector<VT2,TF>& rhs )
2300 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
2305 ConstIterator_<VT2> right( (~rhs).
begin() );
2307 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2308 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2309 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2310 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2311 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2313 for( ; i<ipos; i+=SIMDSIZE ) {
2314 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2316 for( ; i<size_; ++i ) {
2317 *left += *right; ++left; ++right;
2336 template<
typename VT
2338 template<
typename VT2 >
2339 inline void Subvector<VT,unaligned,TF,true>::addAssign(
const SparseVector<VT2,TF>& rhs )
2343 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
2344 vector_[offset_+element->index()] += element->value();
2362 template<
typename VT
2364 template<
typename VT2 >
2365 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
2366 Subvector<VT,unaligned,TF,true>::subAssign(
const DenseVector<VT2,TF>& rhs )
2370 const size_t ipos(
size() &
size_t(-2) );
2371 for(
size_t i=0UL; i<ipos; i+=2UL ) {
2372 vector_[offset_+i ] -= (~rhs)[i ];
2373 vector_[offset_+i+1UL] -= (~rhs)[i+1UL];
2375 if( ipos <
size() ) {
2376 vector_[offset_+ipos] -= (~rhs)[ipos];
2395 template<
typename VT
2397 template<
typename VT2 >
2398 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
2399 Subvector<VT,unaligned,TF,true>::subAssign(
const DenseVector<VT2,TF>& rhs )
2405 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
2410 ConstIterator_<VT2> right( (~rhs).
begin() );
2412 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2413 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2414 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2415 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2416 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2418 for( ; i<ipos; i+=SIMDSIZE ) {
2419 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2421 for( ; i<size_; ++i ) {
2422 *left -= *right; ++left; ++right;
2441 template<
typename VT
2443 template<
typename VT2 >
2444 inline void Subvector<VT,unaligned,TF,true>::subAssign(
const SparseVector<VT2,TF>& rhs )
2448 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
2449 vector_[offset_+element->index()] -= element->value();
2467 template<
typename VT
2469 template<
typename VT2 >
2470 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
2471 Subvector<VT,unaligned,TF,true>::multAssign(
const DenseVector<VT2,TF>& rhs )
2475 const size_t ipos(
size() &
size_t(-2) );
2476 for(
size_t i=0UL; i<ipos; i+=2UL ) {
2477 vector_[offset_+i ] *= (~rhs)[i ];
2478 vector_[offset_+i+1UL] *= (~rhs)[i+1UL];
2480 if( ipos <
size() ) {
2481 vector_[offset_+ipos] *= (~rhs)[ipos];
2500 template<
typename VT
2502 template<
typename VT2 >
2503 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
2504 Subvector<VT,unaligned,TF,true>::multAssign(
const DenseVector<VT2,TF>& rhs )
2510 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
2515 ConstIterator_<VT2> right( (~rhs).
begin() );
2517 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2518 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2519 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2520 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2521 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2523 for( ; i<ipos; i+=SIMDSIZE ) {
2524 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2526 for( ; i<size_; ++i ) {
2527 *left *= *right; ++left; ++right;
2546 template<
typename VT
2548 template<
typename VT2 >
2549 inline void Subvector<VT,unaligned,TF,true>::multAssign(
const SparseVector<VT2,TF>& rhs )
2557 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
2558 vector_[offset_+element->index()] = tmp[element->index()] * element->value();
2576 template<
typename VT
2578 template<
typename VT2 >
2579 inline DisableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
2580 Subvector<VT,unaligned,TF,true>::divAssign(
const DenseVector<VT2,TF>& rhs )
2584 const size_t ipos(
size() &
size_t(-2) );
2585 for(
size_t i=0UL; i<ipos; i+=2UL ) {
2586 vector_[offset_+i ] /= (~rhs)[i ];
2587 vector_[offset_+i+1UL] /= (~rhs)[i+1UL];
2589 if( ipos <
size() ) {
2590 vector_[offset_+ipos] /= (~rhs)[ipos];
2609 template<
typename VT
2611 template<
typename VT2 >
2612 inline EnableIf_< typename Subvector<VT,unaligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
2613 Subvector<VT,unaligned,TF,true>::divAssign(
const DenseVector<VT2,TF>& rhs )
2619 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
2624 ConstIterator_<VT2> right( (~rhs).
begin() );
2626 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2627 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2628 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2629 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2630 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2632 for( ; i<ipos; i+=SIMDSIZE ) {
2633 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2635 for( ; i<size_; ++i ) {
2636 *left /= *right; ++left; ++right;
2663 template<
typename VT
2665 class Subvector<VT,
aligned,TF,true>
2666 :
public View< DenseVector< Subvector<VT,aligned,TF,true>, TF > >
2671 using Operand = If_< IsExpression<VT>, VT, VT& >;
2676 using This = Subvector<VT,aligned,TF,true>;
2677 using BaseType = DenseVector<This,TF>;
2680 using ElementType = ElementType_<VT>;
2681 using SIMDType = SIMDTrait_<ElementType>;
2686 using ConstReference = ConstReference_<VT>;
2692 using ConstPointer =
const ElementType*;
2695 using Pointer = If_< Or< IsConst<VT>, Not< HasMutableDataAccess<VT> > >, ConstPointer, ElementType* >;
2698 using ConstIterator = ConstIterator_<VT>;
2706 enum :
bool { simdEnabled = VT::simdEnabled };
2709 enum :
bool { smpAssignable = VT::smpAssignable };
2715 explicit inline Subvector( Operand vector,
size_t index,
size_t n );
2727 inline Reference operator[](
size_t index );
2728 inline ConstReference operator[](
size_t index )
const;
2730 inline ConstReference at(
size_t index )
const;
2731 inline Pointer data () noexcept;
2732 inline ConstPointer data () const noexcept;
2734 inline ConstIterator begin () const;
2735 inline ConstIterator
cbegin() const;
2737 inline ConstIterator end () const;
2738 inline ConstIterator
cend () const;
2745 inline Subvector& operator= ( const ElementType& rhs );
2746 inline Subvector& operator= ( initializer_list<ElementType> list );
2747 inline Subvector& operator= ( const Subvector& rhs );
2748 template< typename VT2 > inline Subvector& operator= ( const Vector<VT2,TF>& rhs );
2749 template< typename VT2 > inline Subvector& operator+=( const Vector<VT2,TF>& rhs );
2750 template< typename VT2 > inline Subvector& operator-=( const Vector<VT2,TF>& rhs );
2751 template< typename VT2 > inline Subvector& operator*=( const DenseVector<VT2,TF>& rhs );
2752 template< typename VT2 > inline Subvector& operator*=( const SparseVector<VT2,TF>& rhs );
2753 template< typename VT2 > inline Subvector& operator/=( const DenseVector<VT2,TF>& rhs );
2754 template< typename VT2 > inline Subvector& operator%=( const Vector<VT2,TF>& rhs );
2756 template< typename Other >
2757 inline
EnableIf_< IsNumeric<Other>, Subvector >& operator*=( Other rhs );
2759 template< typename Other >
2760 inline
EnableIf_< IsNumeric<Other>, Subvector >& operator/=( Other rhs );
2767 inline Operand operand() const noexcept;
2768 inline
size_t offset() const noexcept;
2769 inline
size_t size() const noexcept;
2770 inline
size_t spacing() const noexcept;
2771 inline
size_t capacity() const noexcept;
2773 inline
void reset();
2780 template< typename Other > inline Subvector& scale( const Other& scalar );
2787 template< typename VT2 >
2788 struct VectorizedAssign {
2789 enum :
bool { value = useOptimizedKernels &&
2790 simdEnabled && VT2::simdEnabled &&
2791 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value };
2797 template<
typename VT2 >
2798 struct VectorizedAddAssign {
2799 enum :
bool { value = useOptimizedKernels &&
2800 simdEnabled && VT2::simdEnabled &&
2801 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2802 HasSIMDAdd< ElementType, ElementType_<VT2> >::value };
2808 template<
typename VT2 >
2809 struct VectorizedSubAssign {
2810 enum :
bool { value = useOptimizedKernels &&
2811 simdEnabled && VT2::simdEnabled &&
2812 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2813 HasSIMDSub< ElementType, ElementType_<VT2> >::value };
2819 template<
typename VT2 >
2820 struct VectorizedMultAssign {
2821 enum :
bool { value = useOptimizedKernels &&
2822 simdEnabled && VT2::simdEnabled &&
2823 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2824 HasSIMDMult< ElementType, ElementType_<VT2> >::value };
2830 template<
typename VT2 >
2831 struct VectorizedDivAssign {
2832 enum :
bool { value = useOptimizedKernels &&
2833 simdEnabled && VT2::simdEnabled &&
2834 IsSIMDCombinable< ElementType, ElementType_<VT2> >::value &&
2835 HasSIMDDiv< ElementType, ElementType_<VT2> >::value };
2848 template<
typename Other >
2849 inline bool canAlias(
const Other* alias )
const noexcept;
2851 template<
typename VT2,
bool AF2,
bool TF2 >
2852 inline bool canAlias(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept;
2854 template<
typename Other >
2855 inline bool isAliased(
const Other* alias )
const noexcept;
2857 template<
typename VT2,
bool AF2,
bool TF2 >
2858 inline bool isAliased(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept;
2860 inline bool isAligned () const noexcept;
2861 inline
bool canSMPAssign() const noexcept;
2872 template< typename VT2 >
2873 inline
DisableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
2875 template< typename VT2 >
2876 inline
EnableIf_< VectorizedAssign<VT2> > assign( const DenseVector <VT2,TF>& rhs );
2878 template< typename VT2 > inline
void assign( const SparseVector<VT2,TF>& rhs );
2880 template< typename VT2 >
2881 inline
DisableIf_< VectorizedAddAssign<VT2> > addAssign( const DenseVector <VT2,TF>& rhs );
2883 template< typename VT2 >
2884 inline
EnableIf_< VectorizedAddAssign<VT2> > addAssign ( const DenseVector <VT2,TF>& rhs );
2886 template< typename VT2 > inline
void addAssign( const SparseVector<VT2,TF>& rhs );
2888 template< typename VT2 >
2889 inline
DisableIf_< VectorizedSubAssign<VT2> > subAssign ( const DenseVector <VT2,TF>& rhs );
2891 template< typename VT2 >
2892 inline
EnableIf_< VectorizedSubAssign<VT2> > subAssign( const DenseVector <VT2,TF>& rhs );
2894 template< typename VT2 > inline
void subAssign( const SparseVector<VT2,TF>& rhs );
2896 template< typename VT2 >
2897 inline
DisableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
2899 template< typename VT2 >
2900 inline
EnableIf_< VectorizedMultAssign<VT2> > multAssign( const DenseVector <VT2,TF>& rhs );
2902 template< typename VT2 > inline
void multAssign( const SparseVector<VT2,TF>& rhs );
2904 template< typename VT2 >
2905 inline
DisableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
2907 template< typename VT2 >
2908 inline
EnableIf_< VectorizedDivAssign<VT2> > divAssign( const DenseVector <VT2,TF>& rhs );
2917 const
size_t offset_;
2923 template< typename VT2,
bool AF2,
bool TF2,
bool DF2 > friend class Subvector;
2959 template< typename VT
2961 inline Subvector<VT,
aligned,TF,true>::Subvector( Operand vector,
size_t index,
size_t n )
2966 if( index + n > vector.size() ) {
2970 if( simdEnabled && vector_.data() !=
nullptr && !
checkAlignment( data() ) ) {
2993 template<
typename VT
2996 Subvector<VT,aligned,TF,true>::operator[](
size_t index )
2999 return vector_[offset_+index];
3012 template<
typename VT
3015 Subvector<VT,aligned,TF,true>::operator[](
size_t index )
const 3018 return const_cast<const VT&
>( vector_ )[offset_+index];
3035 template<
typename VT
3038 Subvector<VT,aligned,TF,true>::at(
size_t index )
3040 if( index >=
size() ) {
3043 return (*
this)[index];
3060 template<
typename VT
3063 Subvector<VT,aligned,TF,true>::at(
size_t index )
const 3065 if( index >=
size() ) {
3068 return (*
this)[index];
3082 template<
typename VT
3084 inline typename Subvector<VT,aligned,TF,true>::Pointer Subvector<VT,aligned,TF,true>::data() noexcept
3086 return vector_.data() + offset_;
3100 template<
typename VT
3102 inline typename Subvector<VT,aligned,TF,true>::ConstPointer
3103 Subvector<VT,aligned,TF,true>::data() const noexcept
3105 return vector_.data() + offset_;
3119 template<
typename VT
3123 return ( vector_.begin() + offset_ );
3137 template<
typename VT
3142 return ( vector_.cbegin() + offset_ );
3156 template<
typename VT
3161 return ( vector_.cbegin() + offset_ );
3175 template<
typename VT
3179 return ( vector_.begin() + offset_ + size_ );
3193 template<
typename VT
3198 return ( vector_.cbegin() + offset_ + size_ );
3212 template<
typename VT
3217 return ( vector_.cbegin() + offset_ + size_ );
3238 template<
typename VT
3240 inline Subvector<VT,aligned,TF,true>&
3241 Subvector<VT,aligned,TF,true>::operator=(
const ElementType& rhs )
3243 const size_t iend( offset_ + size_ );
3245 for(
size_t i=offset_; i<iend; ++i )
3267 template<
typename VT
3269 inline Subvector<VT,aligned,TF,true>&
3270 Subvector<VT,aligned,TF,true>::operator=( initializer_list<ElementType> list )
3272 if( list.size() >
size() ) {
3298 template<
typename VT
3300 inline Subvector<VT,aligned,TF,true>&
3301 Subvector<VT,aligned,TF,true>::operator=(
const Subvector& rhs )
3306 if( &rhs ==
this || ( &vector_ == &rhs.vector_ && offset_ == rhs.offset_ ) )
3309 if(
size() != rhs.size() ) {
3313 if( !tryAssign( vector_, rhs, offset_ ) ) {
3317 decltype(
auto) left( derestrict( *this ) );
3319 if( rhs.canAlias( &vector_ ) ) {
3347 template<
typename VT
3349 template<
typename VT2 >
3350 inline Subvector<VT,aligned,TF,true>&
3351 Subvector<VT,aligned,TF,true>::operator=(
const Vector<VT2,TF>& rhs )
3360 using Right = If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& >;
3361 Right right( ~rhs );
3363 if( !tryAssign( vector_, right, offset_ ) ) {
3367 decltype(
auto) left( derestrict( *this ) );
3369 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3370 const ResultType_<VT2> tmp( right );
3374 if( IsSparseVector<VT2>::value )
3399 template<
typename VT
3401 template<
typename VT2 >
3402 inline Subvector<VT,aligned,TF,true>&
3412 using Right = If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& >;
3413 Right right( ~rhs );
3415 if( !tryAddAssign( vector_, right, offset_ ) ) {
3419 decltype(
auto) left( derestrict( *this ) );
3421 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3422 const ResultType_<VT2> tmp( right );
3449 template<
typename VT
3451 template<
typename VT2 >
3452 inline Subvector<VT,aligned,TF,true>&
3462 using Right = If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& >;
3463 Right right( ~rhs );
3465 if( !trySubAssign( vector_, right, offset_ ) ) {
3469 decltype(
auto) left( derestrict( *this ) );
3471 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3472 const ResultType_<VT2> tmp( right );
3500 template<
typename VT
3502 template<
typename VT2 >
3503 inline Subvector<VT,aligned,TF,true>&
3513 using Right = If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& >;
3514 Right right( ~rhs );
3516 if( !tryMultAssign( vector_, right, offset_ ) ) {
3520 decltype(
auto) left( derestrict( *this ) );
3522 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3523 const ResultType_<VT2> tmp( right );
3551 template<
typename VT
3553 template<
typename VT2 >
3554 inline Subvector<VT,aligned,TF,true>&
3566 if( !tryAssign( vector_, tmp, offset_ ) ) {
3570 decltype(
auto) left( derestrict( *this ) );
3594 template< typename VT
3596 template< typename VT2 >
3597 inline Subvector<VT,aligned,TF,true>&
3598 Subvector<VT,aligned,TF,true>::operator/=( const DenseVector<VT2,TF>& rhs )
3607 using Right = If_< IsRestricted<VT>, CompositeType_<VT2>,
const VT2& >;
3608 Right right( ~rhs );
3610 if( !tryDivAssign( vector_, right, offset_ ) ) {
3614 decltype(
auto) left( derestrict( *this ) );
3616 if( IsReference<Right>::value && right.canAlias( &vector_ ) ) {
3617 const ResultType_<VT2> tmp( right );
3645 template<
typename VT
3647 template<
typename VT2 >
3648 inline Subvector<VT,aligned,TF,true>&
3649 Subvector<VT,aligned,TF,true>::operator%=(
const Vector<VT2,TF>& rhs )
3651 using blaze::assign;
3656 using CrossType = CrossTrait_< ResultType, ResultType_<VT2> >;
3662 if(
size() != 3UL || (~rhs).
size() != 3UL ) {
3666 const CrossType tmp( *
this % (~rhs) );
3668 if( !tryAssign( vector_, tmp, offset_ ) ) {
3672 decltype(
auto) left( derestrict( *this ) );
3674 assign( left, tmp );
3692 template< typename VT
3694 template< typename Other >
3695 inline
EnableIf_< IsNumeric<Other>, Subvector<VT,aligned,TF,true> >&
3696 Subvector<VT,aligned,TF,true>::operator*=( Other rhs )
3698 decltype(
auto) left( derestrict( *this ) );
3717 template< typename VT
3719 template< typename Other >
3720 inline
EnableIf_< IsNumeric<Other>, Subvector<VT,aligned,TF,true> >&
3721 Subvector<VT,aligned,TF,true>::operator/=( Other rhs )
3725 decltype(
auto) left( derestrict( *this ) );
3748 template< typename VT
3750 inline typename Subvector<VT,aligned,TF,true>::Operand
3751 Subvector<VT,aligned,TF,true>::operand() const noexcept
3765 template<
typename VT
3767 inline size_t Subvector<VT,aligned,TF,true>::offset() const noexcept
3781 template<
typename VT
3800 template<
typename VT
3804 return vector_.spacing() - offset_;
3816 template<
typename VT
3820 return vector_.capacity() - offset_;
3835 template<
typename VT
3839 size_t nonzeros( 0 );
3841 const size_t iend( offset_ + size_ );
3842 for(
size_t i=offset_; i<iend; ++i ) {
3859 template<
typename VT
3865 const size_t iend( offset_ + size_ );
3866 for(
size_t i=offset_; i<iend; ++i )
3867 clear( vector_[i] );
3892 template<
typename VT
3894 template<
typename Other >
3895 inline Subvector<VT,aligned,TF,true>& Subvector<VT,aligned,TF,true>::scale(
const Other& scalar )
3897 const size_t iend( offset_ + size_ );
3898 for(
size_t i=offset_; i<iend; ++i )
3899 vector_[i] *= scalar;
3925 template<
typename VT
3927 template<
typename Other >
3928 inline bool Subvector<VT,aligned,TF,true>::canAlias(
const Other* alias )
const noexcept
3930 return vector_.isAliased( alias );
3947 template<
typename VT
3949 template<
typename VT2
3952 inline bool Subvector<VT,aligned,TF,true>::canAlias(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept
3954 return ( vector_.isAliased( &alias->vector_ ) &&
3955 ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
3972 template<
typename VT
3974 template<
typename Other >
3975 inline bool Subvector<VT,aligned,TF,true>::isAliased(
const Other* alias )
const noexcept
3977 return vector_.isAliased( alias );
3994 template<
typename VT
3996 template<
typename VT2
3999 inline bool Subvector<VT,aligned,TF,true>::isAliased(
const Subvector<VT2,AF2,TF2,true>* alias )
const noexcept
4001 return ( vector_.isAliased( &alias->vector_ ) &&
4002 ( offset_ + size_ > alias->offset_ ) && ( offset_ < alias->offset_ + alias->size_ ) );
4018 template<
typename VT
4020 inline bool Subvector<VT,aligned,TF,true>::isAligned() const noexcept
4039 template<
typename VT
4041 inline bool Subvector<VT,aligned,TF,true>::canSMPAssign() const noexcept
4043 return (
size() > SMP_DVECASSIGN_THRESHOLD );
4063 template<
typename VT
4066 Subvector<VT,aligned,TF,true>::load(
size_t index )
const noexcept
4068 return loada( index );
4088 template<
typename VT
4099 return vector_.loada( offset_+index );
4119 template<
typename VT
4130 return vector_.loadu( offset_+index );
4151 template<
typename VT
4154 Subvector<VT,aligned,TF,true>::store(
size_t index,
const SIMDType& value ) noexcept
4177 template<
typename VT
4188 vector_.storea( offset_+index, value );
4209 template<
typename VT
4220 vector_.storeu( offset_+index, value );
4241 template<
typename VT
4252 vector_.stream( offset_+index, value );
4270 template<
typename VT
4272 template<
typename VT2 >
4273 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
4274 Subvector<VT,aligned,TF,true>::assign(
const DenseVector<VT2,TF>& rhs )
4278 const size_t ipos(
size() &
size_t(-2) );
4279 for(
size_t i=0UL; i<ipos; i+=2UL ) {
4280 vector_[offset_+i ] = (~rhs)[i ];
4281 vector_[offset_+i+1UL] = (~rhs)[i+1UL];
4283 if( ipos <
size() ) {
4284 vector_[offset_+ipos] = (~rhs)[ipos];
4303 template<
typename VT
4305 template<
typename VT2 >
4306 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAssign<VT2> >
4307 Subvector<VT,aligned,TF,true>::assign(
const DenseVector<VT2,TF>& rhs )
4313 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
4318 ConstIterator_<VT2> right( (~rhs).
begin() );
4320 if( useStreaming && size_ > ( cacheSize/(
sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( &vector_ ) )
4322 for( ; i<ipos; i+=SIMDSIZE ) {
4323 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4325 for( ; i<size_; ++i ) {
4326 *left = *right; ++left; ++right;
4331 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4332 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4333 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4334 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4335 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4337 for( ; i<ipos; i+=SIMDSIZE ) {
4338 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4340 for( ; i<size_; ++i ) {
4341 *left = *right; ++left; ++right;
4361 template<
typename VT
4363 template<
typename VT2 >
4364 inline void Subvector<VT,aligned,TF,true>::assign(
const SparseVector<VT2,TF>& rhs )
4368 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
4369 vector_[offset_+element->index()] = element->value();
4387 template<
typename VT
4389 template<
typename VT2 >
4390 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
4391 Subvector<VT,aligned,TF,true>::addAssign(
const DenseVector<VT2,TF>& rhs )
4395 const size_t ipos(
size() &
size_t(-2) );
4396 for(
size_t i=0UL; i<ipos; i+=2UL ) {
4397 vector_[offset_+i ] += (~rhs)[i ];
4398 vector_[offset_+i+1UL] += (~rhs)[i+1UL];
4400 if( ipos <
size() ) {
4401 vector_[offset_+ipos] += (~rhs)[ipos];
4420 template<
typename VT
4422 template<
typename VT2 >
4423 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >
4424 Subvector<VT,aligned,TF,true>::addAssign(
const DenseVector<VT2,TF>& rhs )
4430 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
4435 ConstIterator_<VT2> right( (~rhs).
begin() );
4437 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4438 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4439 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4440 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4441 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4443 for( ; i<ipos; i+=SIMDSIZE ) {
4444 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4446 for( ; i<size_; ++i ) {
4447 *left += *right; ++left; ++right;
4466 template<
typename VT
4468 template<
typename VT2 >
4469 inline void Subvector<VT,aligned,TF,true>::addAssign(
const SparseVector<VT2,TF>& rhs )
4473 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
4474 vector_[offset_+element->index()] += element->value();
4492 template<
typename VT
4494 template<
typename VT2 >
4495 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
4496 Subvector<VT,aligned,TF,true>::subAssign(
const DenseVector<VT2,TF>& rhs )
4500 const size_t ipos(
size() &
size_t(-2) );
4501 for(
size_t i=0UL; i<ipos; i+=2UL ) {
4502 vector_[offset_+i ] -= (~rhs)[i ];
4503 vector_[offset_+i+1UL] -= (~rhs)[i+1UL];
4505 if( ipos <
size() ) {
4506 vector_[offset_+ipos] -= (~rhs)[ipos];
4525 template<
typename VT
4527 template<
typename VT2 >
4528 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >
4529 Subvector<VT,aligned,TF,true>::subAssign(
const DenseVector<VT2,TF>& rhs )
4535 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
4540 ConstIterator_<VT2> right( (~rhs).
begin() );
4542 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4543 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4544 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4545 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4546 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4548 for( ; i<ipos; i+=SIMDSIZE ) {
4549 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4551 for( ; i<size_; ++i ) {
4552 *left -= *right; ++left; ++right;
4571 template<
typename VT
4573 template<
typename VT2 >
4574 inline void Subvector<VT,aligned,TF,true>::subAssign(
const SparseVector<VT2,TF>& rhs )
4578 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
4579 vector_[offset_+element->index()] -= element->value();
4597 template<
typename VT
4599 template<
typename VT2 >
4600 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
4601 Subvector<VT,aligned,TF,true>::multAssign(
const DenseVector<VT2,TF>& rhs )
4605 const size_t ipos(
size() &
size_t(-2) );
4606 for(
size_t i=0UL; i<ipos; i+=2UL ) {
4607 vector_[offset_+i ] *= (~rhs)[i ];
4608 vector_[offset_+i+1UL] *= (~rhs)[i+1UL];
4610 if( ipos <
size() ) {
4611 vector_[offset_+ipos] *= (~rhs)[ipos];
4630 template<
typename VT
4632 template<
typename VT2 >
4633 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >
4634 Subvector<VT,aligned,TF,true>::multAssign(
const DenseVector<VT2,TF>& rhs )
4640 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
4645 ConstIterator_<VT2> right( (~rhs).
begin() );
4647 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4648 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4649 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4650 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4651 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4653 for( ; i<ipos; i+=SIMDSIZE ) {
4654 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4656 for( ; i<size_; ++i ) {
4657 *left *= *right; ++left; ++right;
4676 template<
typename VT
4678 template<
typename VT2 >
4679 inline void Subvector<VT,aligned,TF,true>::multAssign(
const SparseVector<VT2,TF>& rhs )
4687 for( ConstIterator_<VT2> element=(~rhs).
begin(); element!=(~rhs).
end(); ++element )
4688 vector_[offset_+element->index()] = tmp[element->index()] * element->value();
4706 template<
typename VT
4708 template<
typename VT2 >
4709 inline DisableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
4710 Subvector<VT,aligned,TF,true>::divAssign(
const DenseVector<VT2,TF>& rhs )
4714 const size_t ipos(
size() &
size_t(-2) );
4715 for(
size_t i=0UL; i<ipos; i+=2UL ) {
4716 vector_[offset_+i ] /= (~rhs)[i ];
4717 vector_[offset_+i+1UL] /= (~rhs)[i+1UL];
4719 if( ipos <
size() ) {
4720 vector_[offset_+ipos] /= (~rhs)[ipos];
4739 template<
typename VT
4741 template<
typename VT2 >
4742 inline EnableIf_< typename Subvector<VT,aligned,TF,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT2> >
4743 Subvector<VT,aligned,TF,true>::divAssign(
const DenseVector<VT2,TF>& rhs )
4749 const size_t ipos( size_ &
size_t(-SIMDSIZE) );
4754 ConstIterator_<VT2> right( (~rhs).
begin() );
4756 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
4757 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4758 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4759 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4760 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4762 for( ; i<ipos; i+=SIMDSIZE ) {
4763 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
4765 for( ; i<size_; ++i ) {
4766 *left /= *right; ++left; ++right;
4793 template<
typename VT1
4796 class Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
4797 :
public View< DenseVector< Subvector< DVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF > >
4801 using CPE = DVecDVecCrossExpr<VT1,VT2,TF>;
4802 using RT = ResultType_<CPE>;
4807 using This = Subvector<CPE,unaligned,TF,true>;
4808 using BaseType = DenseVector<This,TF>;
4811 using ElementType = ElementType_<CPE>;
4818 enum :
bool { simdEnabled =
false };
4821 enum :
bool { smpAssignable =
false };
4831 explicit inline Subvector(
const CPE& vector,
size_t index,
size_t n ) noexcept
4844 inline ReturnType operator[](
size_t index )
const {
4846 return vector_[offset_+index];
4858 if( index >=
size() ) {
4861 return (*
this)[index];
4870 inline CPE operand() const noexcept {
4880 inline size_t offset() const noexcept {
4890 inline size_t size() const noexcept {
4901 template<
typename T >
4902 inline bool canAlias(
const T* alias )
const noexcept {
4903 return vector_.canAlias( alias );
4913 template<
typename T >
4914 inline bool isAliased(
const T* alias )
const noexcept {
4915 return vector_.isAliased( alias );
4924 const size_t offset_;
4953 template<
typename VT1
4956 class Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
4957 :
public View< DenseVector< Subvector< DVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF > >
4961 using CPE = DVecSVecCrossExpr<VT1,VT2,TF>;
4962 using RT = ResultType_<CPE>;
4967 using This = Subvector<CPE,unaligned,TF,true>;
4968 using BaseType = DenseVector<This,TF>;
4971 using ElementType = ElementType_<CPE>;
4978 enum :
bool { simdEnabled =
false };
4981 enum :
bool { smpAssignable =
false };
4991 explicit inline Subvector(
const CPE& vector,
size_t index,
size_t n ) noexcept
5004 inline ReturnType operator[](
size_t index )
const {
5006 return vector_[offset_+index];
5018 if( index >=
size() ) {
5021 return (*
this)[index];
5030 inline CPE operand() const noexcept {
5040 inline size_t offset() const noexcept {
5050 inline size_t size() const noexcept {
5061 template<
typename T >
5062 inline bool canAlias(
const T* alias )
const noexcept {
5063 return vector_.canAlias( alias );
5073 template<
typename T >
5074 inline bool isAliased(
const T* alias )
const noexcept {
5075 return vector_.isAliased( alias );
5084 const size_t offset_;
5113 template<
typename VT1
5116 class Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
5117 :
public View< DenseVector< Subvector< SVecDVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF > >
5121 using CPE = SVecDVecCrossExpr<VT1,VT2,TF>;
5122 using RT = ResultType_<CPE>;
5127 using This = Subvector<CPE,unaligned,TF,true>;
5128 using BaseType = DenseVector<This,TF>;
5131 using ElementType = ElementType_<CPE>;
5138 enum :
bool { simdEnabled =
false };
5141 enum :
bool { smpAssignable =
false };
5151 explicit inline Subvector(
const CPE& vector,
size_t index,
size_t n ) noexcept
5164 inline ReturnType operator[](
size_t index )
const {
5166 return vector_[offset_+index];
5178 if( index >=
size() ) {
5181 return (*
this)[index];
5190 inline CPE operand() const noexcept {
5200 inline size_t offset() const noexcept {
5210 inline size_t size() const noexcept {
5221 template<
typename T >
5222 inline bool canAlias(
const T* alias )
const noexcept {
5223 return vector_.canAlias( alias );
5233 template<
typename T >
5234 inline bool isAliased(
const T* alias )
const noexcept {
5235 return vector_.isAliased( alias );
5244 const size_t offset_;
5273 template<
typename VT1
5276 class Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >
5277 :
public View< DenseVector< Subvector< SVecSVecCrossExpr<VT1,VT2,TF>, unaligned, TF, true >, TF > >
5281 using CPE = SVecSVecCrossExpr<VT1,VT2,TF>;
5282 using RT = ResultType_<CPE>;
5287 using This = Subvector<CPE,unaligned,TF,true>;
5288 using BaseType = DenseVector<This,TF>;
5291 using ElementType = ElementType_<CPE>;
5298 enum :
bool { simdEnabled =
false };
5301 enum :
bool { smpAssignable =
false };
5311 explicit inline Subvector(
const CPE& vector,
size_t index,
size_t n ) noexcept
5324 inline ReturnType operator[](
size_t index )
const {
5326 return vector_[offset_+index];
5338 if( index >=
size() ) {
5341 return (*
this)[index];
5350 inline CPE operand() const noexcept {
5360 inline size_t offset() const noexcept {
5370 inline size_t size() const noexcept {
5381 template<
typename T >
5382 inline bool canAlias(
const T* alias )
const noexcept {
5383 return vector_.canAlias( alias );
5393 template<
typename T >
5394 inline bool isAliased(
const T* alias )
const {
5395 return vector_.isAliased( alias );
5404 const size_t offset_;
constexpr bool aligned
Alignment flag for aligned vectors and matrices.Via this flag it is possible to specify subvectors...
Definition: AlignmentFlag.h:85
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.
#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:356
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:164
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:265
#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 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
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3078
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:198
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3076
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:560
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
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:224
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3080
Header file for the DenseVector base class.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3085
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:394
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
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3086
#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:1393
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:133
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:308
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:242
BLAZE_ALWAYS_INLINE size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:110
Header file for the std::initializer_list aliases.
Constraint on the data type.
Header file for the DisableIf class template.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3084
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.
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3077
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:102
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3081
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.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3087
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
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:264
decltype(auto) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:8893
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.
constexpr bool unaligned
Alignment flag for unaligned vectors and matrices.Via this flag it is possible to specify subvectors...
Definition: AlignmentFlag.h:64
Header file for the EnableIf class template.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:580
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.
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:1357
Header file for run time assertion macros.
Header file for the cross product trait.
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.
Header file for the isDefault shim.
Header file for the HasSIMDSub type trait.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:819
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:224
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
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3082
#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
#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.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3083
Header file for the alignment check function.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:252
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:600
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:1375
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.