All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DenseSubvector.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_DENSESUBVECTOR_H_
36 #define _BLAZE_MATH_VIEWS_DENSESUBVECTOR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <stdexcept>
57 #include <blaze/math/Intrinsics.h>
59 #include <blaze/math/shims/Reset.h>
68 #include <blaze/system/CacheSize.h>
69 #include <blaze/system/Streaming.h>
71 #include <blaze/util/Assert.h>
73 #include <blaze/util/DisableIf.h>
74 #include <blaze/util/EnableIf.h>
76 #include <blaze/util/mpl/Or.h>
77 #include <blaze/util/SelectType.h>
78 #include <blaze/util/Template.h>
79 #include <blaze/util/Types.h>
83 
84 
85 namespace blaze {
86 
87 //=================================================================================================
88 //
89 // CLASS DEFINITION
90 //
91 //=================================================================================================
92 
93 //*************************************************************************************************
374 template< typename VT // Type of the dense vector
375  , bool AF = unaligned // Alignment flag
376  , bool TF = IsRowVector<VT>::value > // Transpose flag
377 class DenseSubvector : public DenseVector< DenseSubvector<VT,AF,TF>, TF >
378  , private Subvector
379 {
380  private:
381  //**Type definitions****************************************************************************
383  typedef typename SelectType< IsExpression<VT>::value, VT, VT& >::Type Operand;
384 
387  //**********************************************************************************************
388 
389  //**********************************************************************************************
391 
397  enum { useConst = IsConst<VT>::value };
398  //**********************************************************************************************
399 
400  public:
401  //**Type definitions****************************************************************************
405  typedef typename VT::ElementType ElementType;
406  typedef typename IT::Type IntrinsicType;
407  typedef typename VT::ReturnType ReturnType;
408  typedef const DenseSubvector& CompositeType;
409 
412 
415 
417  typedef const ElementType* ConstPointer;
418 
421  //**********************************************************************************************
422 
423  //**SubvectorIterator class definition**********************************************************
426  template< typename IteratorType > // Type of the dense vector iterator
428  {
429  public:
430  //**Type definitions*************************************************************************
432  typedef typename std::iterator_traits<IteratorType>::iterator_category IteratorCategory;
433 
435  typedef typename std::iterator_traits<IteratorType>::value_type ValueType;
436 
438  typedef typename std::iterator_traits<IteratorType>::pointer PointerType;
439 
441  typedef typename std::iterator_traits<IteratorType>::reference ReferenceType;
442 
444  typedef typename std::iterator_traits<IteratorType>::difference_type DifferenceType;
445 
446  // STL iterator requirements
452  //*******************************************************************************************
453 
454  //**Constructor******************************************************************************
462  explicit inline SubvectorIterator( IteratorType iterator, IteratorType final, size_t rest, bool isAligned )
463  : iterator_ ( iterator ) // Iterator to the current subvector element
464  , final_ ( final ) // The final iterator for intrinsic operations
465  , rest_ ( rest ) // The number of remaining elements beyond the final iterator
466  , isAligned_( isAligned ) // Memory alignment flag
467  {}
468  //*******************************************************************************************
469 
470  //**Addition assignment operator*************************************************************
476  inline SubvectorIterator& operator+=( size_t inc ) {
477  iterator_ += inc;
478  return *this;
479  }
480  //*******************************************************************************************
481 
482  //**Subtraction assignment operator**********************************************************
488  inline SubvectorIterator& operator-=( size_t dec ) {
489  iterator_ -= dec;
490  return *this;
491  }
492  //*******************************************************************************************
493 
494  //**Prefix increment operator****************************************************************
500  ++iterator_;
501  return *this;
502  }
503  //*******************************************************************************************
504 
505  //**Postfix increment operator***************************************************************
510  inline const SubvectorIterator operator++( int ) {
512  }
513  //*******************************************************************************************
514 
515  //**Prefix decrement operator****************************************************************
521  --iterator_;
522  return *this;
523  }
524  //*******************************************************************************************
525 
526  //**Postfix decrement operator***************************************************************
531  inline const SubvectorIterator operator--( int ) {
533  }
534  //*******************************************************************************************
535 
536  //**Element access operator******************************************************************
541  inline ReferenceType operator*() const {
542  return *iterator_;
543  }
544  //*******************************************************************************************
545 
546  //**Load function****************************************************************************
556  inline IntrinsicType load() const {
557  return loadu();
558  }
559  //*******************************************************************************************
560 
561  //**Loadu function***************************************************************************
571  inline IntrinsicType loadu() const {
572  if( isAligned_ ) {
573  return iterator_.load();
574  }
575  else if( iterator_ != final_ ) {
576  return iterator_.loadu();
577  }
578  else {
579  IntrinsicType value;
580  for( size_t j=0UL; j<rest_; ++j )
581  value[j] = *(iterator_+j);
582  return value;
583  }
584  }
585  //*******************************************************************************************
586 
587  //**Equality operator************************************************************************
593  inline bool operator==( const SubvectorIterator& rhs ) const {
594  return iterator_ == rhs.iterator_;
595  }
596  //*******************************************************************************************
597 
598  //**Inequality operator**********************************************************************
604  inline bool operator!=( const SubvectorIterator& rhs ) const {
605  return iterator_ != rhs.iterator_;
606  }
607  //*******************************************************************************************
608 
609  //**Less-than operator***********************************************************************
615  inline bool operator<( const SubvectorIterator& rhs ) const {
616  return iterator_ < rhs.iterator_;
617  }
618  //*******************************************************************************************
619 
620  //**Greater-than operator********************************************************************
626  inline bool operator>( const SubvectorIterator& rhs ) const {
627  return iterator_ > rhs.iterator_;
628  }
629  //*******************************************************************************************
630 
631  //**Less-or-equal-than operator**************************************************************
637  inline bool operator<=( const SubvectorIterator& rhs ) const {
638  return iterator_ <= rhs.iterator_;
639  }
640  //*******************************************************************************************
641 
642  //**Greater-or-equal-than operator***********************************************************
648  inline bool operator>=( const SubvectorIterator& rhs ) const {
649  return iterator_ >= rhs.iterator_;
650  }
651  //*******************************************************************************************
652 
653  //**Subtraction operator*********************************************************************
659  inline DifferenceType operator-( const SubvectorIterator& rhs ) const {
660  return iterator_ - rhs.iterator_;
661  }
662  //*******************************************************************************************
663 
664  //**Addition operator************************************************************************
671  friend inline const SubvectorIterator operator+( const SubvectorIterator& it, size_t inc ) {
672  return SubvectorIterator( it.iterator_ + inc, it.final_, it.rest_, it.isAligned_ );
673  }
674  //*******************************************************************************************
675 
676  //**Addition operator************************************************************************
683  friend inline const SubvectorIterator operator+( size_t inc, const SubvectorIterator& it ) {
684  return SubvectorIterator( it.iterator_ + inc, it.final_, it.rest_, it.isAligned_ );
685  }
686  //*******************************************************************************************
687 
688  //**Subtraction operator*********************************************************************
695  friend inline const SubvectorIterator operator-( const SubvectorIterator& it, size_t dec ) {
696  return SubvectorIterator( it.iterator_ - dec, it.final_, it.rest_, it.isAligned_ );
697  }
698  //*******************************************************************************************
699 
700  private:
701  //**Member variables*************************************************************************
702  IteratorType iterator_;
703  IteratorType final_;
704  size_t rest_;
705  bool isAligned_;
706  //*******************************************************************************************
707  };
708  //**********************************************************************************************
709 
710  //**Type definitions****************************************************************************
713 
716  //**********************************************************************************************
717 
718  //**Compilation flags***************************************************************************
720  enum { vectorizable = VT::vectorizable };
721 
723  enum { smpAssignable = VT::smpAssignable };
724  //**********************************************************************************************
725 
726  //**Constructors********************************************************************************
729  explicit inline DenseSubvector( Operand vector, size_t index, size_t n );
730  // No explicitly declared copy constructor.
732  //**********************************************************************************************
733 
734  //**Destructor**********************************************************************************
735  // No explicitly declared destructor.
736  //**********************************************************************************************
737 
738  //**Data access functions***********************************************************************
741  inline Reference operator[]( size_t index );
742  inline ConstReference operator[]( size_t index ) const;
743  inline Pointer data ();
744  inline ConstPointer data () const;
745  inline Iterator begin ();
746  inline ConstIterator begin () const;
747  inline ConstIterator cbegin() const;
748  inline Iterator end ();
749  inline ConstIterator end () const;
750  inline ConstIterator cend () const;
752  //**********************************************************************************************
753 
754  //**Assignment operators************************************************************************
757  inline DenseSubvector& operator= ( const ElementType& rhs );
758  inline DenseSubvector& operator= ( const DenseSubvector& rhs );
759  template< typename VT2 > inline DenseSubvector& operator= ( const Vector<VT2,TF>& rhs );
760  template< typename VT2 > inline DenseSubvector& operator+=( const Vector<VT2,TF>& rhs );
761  template< typename VT2 > inline DenseSubvector& operator-=( const Vector<VT2,TF>& rhs );
762  template< typename VT2 > inline DenseSubvector& operator*=( const Vector<VT2,TF>& rhs );
763 
764  template< typename Other >
765  inline typename EnableIf< IsNumeric<Other>, DenseSubvector >::Type&
766  operator*=( Other rhs );
767 
768  template< typename Other >
769  inline typename EnableIf< IsNumeric<Other>, DenseSubvector >::Type&
770  operator/=( Other rhs );
772  //**********************************************************************************************
773 
774  //**Utility functions***************************************************************************
777  inline size_t size() const;
778  inline size_t capacity() const;
779  inline size_t nonZeros() const;
780  inline void reset();
781  template< typename Other > inline DenseSubvector& scale( const Other& scalar );
783  //**********************************************************************************************
784 
785  private:
786  //**********************************************************************************************
788  template< typename VT2 >
790  struct VectorizedAssign {
791  enum { value = vectorizable && VT2::vectorizable &&
792  IsSame<ElementType,typename VT2::ElementType>::value };
793  };
795  //**********************************************************************************************
796 
797  //**********************************************************************************************
799  template< typename VT2 >
801  struct VectorizedAddAssign {
802  enum { value = vectorizable && VT2::vectorizable &&
803  IsSame<ElementType,typename VT2::ElementType>::value &&
804  IntrinsicTrait<ElementType>::addition };
805  };
807  //**********************************************************************************************
808 
809  //**********************************************************************************************
811  template< typename VT2 >
813  struct VectorizedSubAssign {
814  enum { value = vectorizable && VT2::vectorizable &&
815  IsSame<ElementType,typename VT2::ElementType>::value &&
816  IntrinsicTrait<ElementType>::subtraction };
817  };
819  //**********************************************************************************************
820 
821  //**********************************************************************************************
823  template< typename VT2 >
825  struct VectorizedMultAssign {
826  enum { value = vectorizable && VT2::vectorizable &&
827  IsSame<ElementType,typename VT2::ElementType>::value &&
828  IntrinsicTrait<ElementType>::multiplication };
829  };
831  //**********************************************************************************************
832 
833  public:
834  //**Expression template evaluation functions****************************************************
837  template< typename Other > inline bool canAlias ( const Other* alias ) const;
838  template< typename Other > inline bool isAliased( const Other* alias ) const;
839 
840  inline bool isAligned () const;
841  inline bool canSMPAssign() const;
842 
843  inline IntrinsicType load ( size_t index ) const;
844  inline IntrinsicType loadu ( size_t index ) const;
845  inline void store ( size_t index, const IntrinsicType& value );
846  inline void storeu( size_t index, const IntrinsicType& value );
847  inline void stream( size_t index, const IntrinsicType& value );
848 
849  template< typename VT2 >
850  inline typename DisableIf< VectorizedAssign<VT2> >::Type
851  assign( const DenseVector <VT2,TF>& rhs );
852 
853  template< typename VT2 >
854  inline typename EnableIf< VectorizedAssign<VT2> >::Type
855  assign( const DenseVector <VT2,TF>& rhs );
856 
857  template< typename VT2 > inline void assign( const SparseVector<VT2,TF>& rhs );
858 
859  template< typename VT2 >
860  inline typename DisableIf< VectorizedAddAssign<VT2> >::Type
861  addAssign( const DenseVector <VT2,TF>& rhs );
862 
863  template< typename VT2 >
864  inline typename EnableIf< VectorizedAddAssign<VT2> >::Type
865  addAssign ( const DenseVector <VT2,TF>& rhs );
866 
867  template< typename VT2 > inline void addAssign( const SparseVector<VT2,TF>& rhs );
868 
869  template< typename VT2 >
870  inline typename DisableIf< VectorizedSubAssign<VT2> >::Type
871  subAssign ( const DenseVector <VT2,TF>& rhs );
872 
873  template< typename VT2 >
874  inline typename EnableIf< VectorizedSubAssign<VT2> >::Type
875  subAssign( const DenseVector <VT2,TF>& rhs );
876 
877  template< typename VT2 > inline void subAssign( const SparseVector<VT2,TF>& rhs );
878 
879  template< typename VT2 >
880  inline typename DisableIf< VectorizedMultAssign<VT2> >::Type
881  multAssign( const DenseVector <VT2,TF>& rhs );
882 
883  template< typename VT2 >
884  inline typename EnableIf< VectorizedMultAssign<VT2> >::Type
885  multAssign( const DenseVector <VT2,TF>& rhs );
886 
887  template< typename VT2 > inline void multAssign( const SparseVector<VT2,TF>& rhs );
889  //**********************************************************************************************
890 
891  private:
892  //**Member variables****************************************************************************
896  const size_t offset_;
897  const size_t size_;
898  const size_t rest_;
899  const size_t final_;
900 
904  const bool isAligned_;
905 
915  //**********************************************************************************************
916 
917  //**Friend declarations*************************************************************************
919  template< bool AF1, typename VT2, bool AF2, bool TF2 >
920  friend const DenseSubvector<VT2,AF1,TF2>
921  subvector( const DenseSubvector<VT2,AF2,TF2>& dv, size_t index, size_t size );
923  //**********************************************************************************************
924 
925  //**Compile time checks*************************************************************************
933  //**********************************************************************************************
934 };
935 //*************************************************************************************************
936 
937 
938 
939 
940 //=================================================================================================
941 //
942 // CONSTRUCTOR
943 //
944 //=================================================================================================
945 
946 //*************************************************************************************************
958 template< typename VT // Type of the dense vector
959  , bool AF // Alignment flag
960  , bool TF > // Transpose flag
961 inline DenseSubvector<VT,AF,TF>::DenseSubvector( Operand vector, size_t index, size_t n )
962  : vector_ ( vector ) // The vector containing the subvector
963  , offset_ ( index ) // The offset of the subvector within the dense vector
964  , size_ ( n ) // The size of the subvector
965  , rest_ ( n % IT::size ) // The number of remaining elements in an unaligned intrinsic operation
966  , final_ ( n - rest_ ) // The final index for unaligned intrinsic operations
967  , isAligned_( ( index % IT::size == 0UL ) &&
968  ( index + n == vector.size() || n % IT::size == 0UL ) )
969 {
970  if( index + n > vector.size() )
971  throw std::invalid_argument( "Invalid subvector specification" );
972 }
973 //*************************************************************************************************
974 
975 
976 
977 
978 //=================================================================================================
979 //
980 // DATA ACCESS FUNCTIONS
981 //
982 //=================================================================================================
983 
984 //*************************************************************************************************
990 template< typename VT // Type of the dense vector
991  , bool AF // Alignment flag
992  , bool TF > // Transpose flag
995 {
996  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
997  return vector_[offset_+index];
998 }
999 //*************************************************************************************************
1000 
1001 
1002 //*************************************************************************************************
1008 template< typename VT // Type of the dense vector
1009  , bool AF // Alignment flag
1010  , bool TF > // Transpose flag
1013 {
1014  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
1015  return const_cast<const VT&>( vector_ )[offset_+index];
1016 }
1017 //*************************************************************************************************
1018 
1019 
1020 //*************************************************************************************************
1027 template< typename VT // Type of the dense vector
1028  , bool AF // Alignment flag
1029  , bool TF > // Transpose flag
1031 {
1032  return vector_.data() + offset_;
1033 }
1034 //*************************************************************************************************
1035 
1036 
1037 //*************************************************************************************************
1044 template< typename VT // Type of the dense vector
1045  , bool AF // Alignment flag
1046  , bool TF > // Transpose flag
1048 {
1049  return vector_.data() + offset_;
1050 }
1051 //*************************************************************************************************
1052 
1053 
1054 //*************************************************************************************************
1061 template< typename VT // Type of the dense vector
1062  , bool AF // Alignment flag
1063  , bool TF > // Transpose flag
1065 {
1066  const typename VT::Iterator first( vector_.begin() + offset_ );
1067  return Iterator( first, first + final_, rest_, isAligned_ );
1068 }
1069 //*************************************************************************************************
1070 
1071 
1072 //*************************************************************************************************
1079 template< typename VT // Type of the dense vector
1080  , bool AF // Alignment flag
1081  , bool TF > // Transpose flag
1083 {
1084  const typename VT::ConstIterator first( vector_.cbegin() + offset_ );
1085  return ConstIterator( first, first + final_, rest_, isAligned_ );
1086 }
1087 //*************************************************************************************************
1088 
1089 
1090 //*************************************************************************************************
1097 template< typename VT // Type of the dense vector
1098  , bool AF // Alignment flag
1099  , bool TF > // Transpose flag
1101 {
1102  const typename VT::ConstIterator first( vector_.cbegin() + offset_ );
1103  return ConstIterator( first, first + final_, rest_, isAligned_ );
1104 }
1105 //*************************************************************************************************
1106 
1107 
1108 //*************************************************************************************************
1115 template< typename VT // Type of the dense vector
1116  , bool AF // Alignment flag
1117  , bool TF > // Transpose flag
1119 {
1120  const typename VT::Iterator last( vector_.begin() + offset_ + size_ );
1121  return Iterator( last, last, rest_, isAligned_ );
1122 }
1123 //*************************************************************************************************
1124 
1125 
1126 //*************************************************************************************************
1133 template< typename VT // Type of the dense vector
1134  , bool AF // Alignment flag
1135  , bool TF > // Transpose flag
1137 {
1138  const typename VT::ConstIterator last( vector_.cbegin() + offset_ + size_ );
1139  return ConstIterator( last, last, rest_, isAligned_ );
1140 }
1141 //*************************************************************************************************
1142 
1143 
1144 //*************************************************************************************************
1151 template< typename VT // Type of the dense vector
1152  , bool AF // Alignment flag
1153  , bool TF > // Transpose flag
1155 {
1156  const typename VT::ConstIterator last( vector_.cbegin() + offset_ + size_ );
1157  return ConstIterator( last, last, rest_, isAligned_ );
1158 }
1159 //*************************************************************************************************
1160 
1161 
1162 
1163 
1164 //=================================================================================================
1165 //
1166 // ASSIGNMENT OPERATORS
1167 //
1168 //=================================================================================================
1169 
1170 //*************************************************************************************************
1176 template< typename VT // Type of the dense vector
1177  , bool AF // Alignment flag
1178  , bool TF > // Transpose flag
1180 {
1181  const size_t iend( offset_ + size_ );
1182 
1183  for( size_t i=offset_; i<iend; ++i )
1184  vector_[i] = rhs;
1185 
1186  return *this;
1187 }
1188 //*************************************************************************************************
1189 
1190 
1191 //*************************************************************************************************
1201 template< typename VT // Type of the dense vector
1202  , bool AF // Alignment flag
1203  , bool TF > // Transpose flag
1205 {
1208 
1209  if( &rhs == this || ( &vector_ == &rhs.vector_ && offset_ == rhs.offset_ ) )
1210  return *this;
1211 
1212  if( size() != rhs.size() )
1213  throw std::invalid_argument( "Subvector sizes do not match" );
1214 
1215  if( rhs.canAlias( &vector_ ) ) {
1216  const ResultType tmp( ~rhs );
1217  smpAssign( *this, tmp );
1218  }
1219  else {
1220  smpAssign( *this, rhs );
1221  }
1222 
1223  return *this;
1224 }
1225 //*************************************************************************************************
1226 
1227 
1228 //*************************************************************************************************
1238 template< typename VT // Type of the dense vector
1239  , bool AF // Alignment flag
1240  , bool TF > // Transpose flag
1241 template< typename VT2 > // Type of the right-hand side vector
1243 {
1246 
1247  if( size() != (~rhs).size() )
1248  throw std::invalid_argument( "Vector sizes do not match" );
1249 
1250  if( (~rhs).canAlias( &vector_ ) ) {
1251  const typename VT2::ResultType tmp( ~rhs );
1252  smpAssign( *this, tmp );
1253  }
1254  else {
1256  reset();
1257  smpAssign( *this, ~rhs );
1258  }
1259 
1260  return *this;
1261 }
1262 //*************************************************************************************************
1263 
1264 
1265 //*************************************************************************************************
1275 template< typename VT // Type of the dense vector
1276  , bool AF // Alignment flag
1277  , bool TF > // Transpose flag
1278 template< typename VT2 > // Type of the right-hand side vector
1280 {
1283 
1284  if( size() != (~rhs).size() )
1285  throw std::invalid_argument( "Vector sizes do not match" );
1286 
1287  if( (~rhs).canAlias( &vector_ ) ) {
1288  const typename VT2::ResultType tmp( ~rhs );
1289  smpAddAssign( *this, tmp );
1290  }
1291  else {
1292  smpAddAssign( *this, ~rhs );
1293  }
1294 
1295  return *this;
1296 }
1297 //*************************************************************************************************
1298 
1299 
1300 //*************************************************************************************************
1310 template< typename VT // Type of the dense vector
1311  , bool AF // Alignment flag
1312  , bool TF > // Transpose flag
1313 template< typename VT2 > // Type of the right-hand side vector
1315 {
1318 
1319  if( size() != (~rhs).size() )
1320  throw std::invalid_argument( "Vector sizes do not match" );
1321 
1322  if( (~rhs).canAlias( &vector_ ) ) {
1323  const typename VT2::ResultType tmp( ~rhs );
1324  smpSubAssign( *this, tmp );
1325  }
1326  else {
1327  smpSubAssign( *this, ~rhs );
1328  }
1329 
1330  return *this;
1331 }
1332 //*************************************************************************************************
1333 
1334 
1335 //*************************************************************************************************
1346 template< typename VT // Type of the dense vector
1347  , bool AF // Alignment flag
1348  , bool TF > // Transpose flag
1349 template< typename VT2 > // Type of the right-hand side vector
1351 {
1354 
1355  if( size() != (~rhs).size() )
1356  throw std::invalid_argument( "Vector sizes do not match" );
1357 
1358  if( (~rhs).canAlias( &vector_ ) || IsSparseVector<VT2>::value ) {
1359  const typename VT2::ResultType tmp( ~rhs );
1360  smpMultAssign( *this, tmp );
1361  }
1362  else {
1363  smpMultAssign( *this, ~rhs );
1364  }
1365 
1366  return *this;
1367 }
1368 //*************************************************************************************************
1369 
1370 
1371 //*************************************************************************************************
1378 template< typename VT // Type of the dense vector
1379  , bool AF // Alignment flag
1380  , bool TF > // Transpose flag
1381 template< typename Other > // Data type of the right-hand side scalar
1382 inline typename EnableIf< IsNumeric<Other>, DenseSubvector<VT,AF,TF> >::Type&
1384 {
1385  smpAssign( *this, (*this) * rhs );
1386  return *this;
1387 }
1388 //*************************************************************************************************
1389 
1390 
1391 //*************************************************************************************************
1400 template< typename VT // Type of the dense vector
1401  , bool AF // Alignment flag
1402  , bool TF > // Transpose flag
1403 template< typename Other > // Data type of the right-hand side scalar
1404 inline typename EnableIf< IsNumeric<Other>, DenseSubvector<VT,AF,TF> >::Type&
1406 {
1407  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1408 
1409  smpAssign( *this, (*this) / rhs );
1410  return *this;
1411 }
1412 //*************************************************************************************************
1413 
1414 
1415 
1416 
1417 //=================================================================================================
1418 //
1419 // UTILITY FUNCTIONS
1420 //
1421 //=================================================================================================
1422 
1423 //*************************************************************************************************
1428 template< typename VT // Type of the dense vector
1429  , bool AF // Alignment flag
1430  , bool TF > // Transpose flag
1431 inline size_t DenseSubvector<VT,AF,TF>::size() const
1432 {
1433  return size_;
1434 }
1435 //*************************************************************************************************
1436 
1437 
1438 //*************************************************************************************************
1443 template< typename VT // Type of the dense vector
1444  , bool AF // Alignment flag
1445  , bool TF > // Transpose flag
1447 {
1448  return vector_.capacity() - offset_;
1449 }
1450 //*************************************************************************************************
1451 
1452 
1453 //*************************************************************************************************
1461 template< typename VT // Type of the dense vector
1462  , bool AF // Alignment flag
1463  , bool TF > // Transpose flag
1465 {
1466  size_t nonzeros( 0 );
1467 
1468  const size_t iend( offset_ + size_ );
1469  for( size_t i=offset_; i<iend; ++i ) {
1470  if( !isDefault( vector_[i] ) )
1471  ++nonzeros;
1472  }
1473 
1474  return nonzeros;
1475 }
1476 //*************************************************************************************************
1477 
1478 
1479 //*************************************************************************************************
1484 template< typename VT // Type of the dense vector
1485  , bool AF // Alignment flag
1486  , bool TF > // Transpose flag
1488 {
1489  using blaze::reset;
1490 
1491  const size_t iend( offset_ + size_ );
1492  for( size_t i=offset_; i<iend; ++i )
1493  reset( vector_[i] );
1494 }
1495 //*************************************************************************************************
1496 
1497 
1498 //*************************************************************************************************
1504 template< typename VT // Type of the dense vector
1505  , bool AF // Alignment flag
1506  , bool TF > // Transpose flag
1507 template< typename Other > // Data type of the scalar value
1509 {
1510  const size_t iend( offset_ + size_ );
1511  for( size_t i=offset_; i<iend; ++i )
1512  vector_[i] *= scalar;
1513  return *this;
1514 }
1515 //*************************************************************************************************
1516 
1517 
1518 
1519 
1520 //=================================================================================================
1521 //
1522 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1523 //
1524 //=================================================================================================
1525 
1526 //*************************************************************************************************
1536 template< typename VT // Type of the dense vector
1537  , bool AF // Alignment flag
1538  , bool TF > // Transpose flag
1539 template< typename Other > // Data type of the foreign expression
1540 inline bool DenseSubvector<VT,AF,TF>::canAlias( const Other* alias ) const
1541 {
1542  return static_cast<const void*>( &vector_ ) == static_cast<const void*>( alias );
1543 }
1544 //*************************************************************************************************
1545 
1546 
1547 //*************************************************************************************************
1557 template< typename VT // Type of the dense vector
1558  , bool AF // Alignment flag
1559  , bool TF > // Transpose flag
1560 template< typename Other > // Data type of the foreign expression
1561 inline bool DenseSubvector<VT,AF,TF>::isAliased( const Other* alias ) const
1562 {
1563  return static_cast<const void*>( &vector_ ) == static_cast<const void*>( alias );
1564 }
1565 //*************************************************************************************************
1566 
1567 
1568 //*************************************************************************************************
1577 template< typename VT // Type of the dense vector
1578  , bool AF // Alignment flag
1579  , bool TF > // Transpose flag
1581 {
1582  return isAligned_;
1583 }
1584 //*************************************************************************************************
1585 
1586 
1587 //*************************************************************************************************
1597 template< typename VT // Type of the dense vector
1598  , bool AF // Alignment flag
1599  , bool TF > // Transpose flag
1601 {
1602  return ( size() > OPENMP_DVECASSIGN_THRESHOLD );
1603 }
1604 //*************************************************************************************************
1605 
1606 
1607 //*************************************************************************************************
1620 template< typename VT // Type of the dense vector
1621  , bool AF // Alignment flag
1622  , bool TF > // Transpose flag
1624  DenseSubvector<VT,AF,TF>::load( size_t index ) const
1625 {
1626  return loadu( index );
1627 }
1628 //*************************************************************************************************
1629 
1630 
1631 //*************************************************************************************************
1644 template< typename VT // Type of the dense vector
1645  , bool AF // Alignment flag
1646  , bool TF > // Transpose flag
1648  DenseSubvector<VT,AF,TF>::loadu( size_t index ) const
1649 {
1651 
1652  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
1653  BLAZE_INTERNAL_ASSERT( index % IT::size == 0UL, "Invalid subvector access index" );
1654 
1655  if( isAligned_ || index != final_ ) {
1656  return vector_.loadu( offset_+index );
1657  }
1658  else {
1659  IntrinsicType value;
1660  for( size_t j=0UL; j<rest_; ++j )
1661  value[j] = vector_[offset_+index+j];
1662  return value;
1663  }
1664 }
1665 //*************************************************************************************************
1666 
1667 
1668 //*************************************************************************************************
1682 template< typename VT // Type of the dense vector
1683  , bool AF // Alignment flag
1684  , bool TF > // Transpose flag
1685 inline void DenseSubvector<VT,AF,TF>::store( size_t index, const IntrinsicType& value )
1686 {
1687  storeu( index, value );
1688 }
1689 //*************************************************************************************************
1690 
1691 
1692 //*************************************************************************************************
1706 template< typename VT // Type of the dense vector
1707  , bool AF // Alignment flag
1708  , bool TF > // Transpose flag
1709 inline void DenseSubvector<VT,AF,TF>::storeu( size_t index, const IntrinsicType& value )
1710 {
1712 
1713  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
1714  BLAZE_INTERNAL_ASSERT( index % IT::size == 0UL, "Invalid subvector access index" );
1715 
1716  if( isAligned_ || index != final_ ) {
1717  vector_.storeu( offset_+index, value );
1718  }
1719  else {
1720  for( size_t j=0UL; j<rest_; ++j )
1721  vector_[offset_+index+j] = value[j];
1722  }
1723 }
1724 //*************************************************************************************************
1725 
1726 
1727 //*************************************************************************************************
1741 template< typename VT // Type of the dense vector
1742  , bool AF // Alignment flag
1743  , bool TF > // Transpose flag
1744 inline void DenseSubvector<VT,AF,TF>::stream( size_t index, const IntrinsicType& value )
1745 {
1746  storeu( index, value );
1747 }
1748 //*************************************************************************************************
1749 
1750 
1751 //*************************************************************************************************
1762 template< typename VT // Type of the dense vector
1763  , bool AF // Alignment flag
1764  , bool TF > // Transpose flag
1765 template< typename VT2 > // Type of the right-hand side dense vector
1766 inline typename DisableIf< typename DenseSubvector<VT,AF,TF>::BLAZE_TEMPLATE VectorizedAssign<VT2> >::Type
1768 {
1769  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1770 
1771  const size_t iend( size() & size_t(-2) );
1772  for( size_t i=0UL; i<iend; i+=2UL ) {
1773  vector_[i+offset_ ] = (~rhs)[i ];
1774  vector_[i+offset_+1UL] = (~rhs)[i+1UL];
1775  }
1776  if( iend < size() ) {
1777  vector_[iend+offset_] = (~rhs)[iend];
1778  }
1779 }
1780 //*************************************************************************************************
1781 
1782 
1783 //*************************************************************************************************
1794 template< typename VT // Type of the dense vector
1795  , bool AF // Alignment flag
1796  , bool TF > // Transpose flag
1797 template< typename VT2 > // Type of the right-hand side dense vector
1798 inline typename EnableIf< typename DenseSubvector<VT,AF,TF>::BLAZE_TEMPLATE VectorizedAssign<VT2> >::Type
1800 {
1801  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1802 
1804 
1805  if( useStreaming && isAligned_ &&
1806  ( size_ > ( cacheSize/( sizeof(ElementType) * 3UL ) ) ) &&
1807  !(~rhs).isAliased( &vector_ ) )
1808  {
1809  for( size_t i=0UL; i<size(); i+=IT::size ) {
1810  vector_.stream( offset_+i, (~rhs).load(i) );
1811  }
1812  }
1813  else
1814  {
1815  const size_t iend( size_ & size_t(-IT::size*4) );
1816  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
1817 
1818  typename VT2::ConstIterator it( (~rhs).begin() );
1819  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
1820  vector_.storeu( offset_+i , it.load() ); it += IT::size;
1821  vector_.storeu( offset_+i+IT::size , it.load() ); it += IT::size;
1822  vector_.storeu( offset_+i+IT::size*2UL, it.load() ); it += IT::size;
1823  vector_.storeu( offset_+i+IT::size*3UL, it.load() ); it += IT::size;
1824  }
1825  for( size_t i=iend; i<size_; i+=IT::size, it+=IT::size ) {
1826  storeu( i, it.load() );
1827  }
1828  }
1829 }
1830 //*************************************************************************************************
1831 
1832 
1833 //*************************************************************************************************
1844 template< typename VT // Type of the dense vector
1845  , bool AF // Alignment flag
1846  , bool TF > // Transpose flag
1847 template< typename VT2 > // Type of the right-hand side dense vector
1849 {
1850  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1851 
1852  for( typename VT2::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1853  vector_[element->index()+offset_] = element->value();
1854 }
1855 //*************************************************************************************************
1856 
1857 
1858 //*************************************************************************************************
1869 template< typename VT // Type of the dense vector
1870  , bool AF // Alignment flag
1871  , bool TF > // Transpose flag
1872 template< typename VT2 > // Type of the right-hand side dense vector
1873 inline typename DisableIf< typename DenseSubvector<VT,AF,TF>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >::Type
1875 {
1876  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1877 
1878  const size_t iend( size() & size_t(-2) );
1879  for( size_t i=0UL; i<iend; i+=2UL ) {
1880  vector_[i+offset_ ] += (~rhs)[i ];
1881  vector_[i+offset_+1UL] += (~rhs)[i+1UL];
1882  }
1883  if( iend < size() ) {
1884  vector_[iend+offset_] += (~rhs)[iend];
1885  }
1886 }
1887 //*************************************************************************************************
1888 
1889 
1890 //*************************************************************************************************
1901 template< typename VT // Type of the dense vector
1902  , bool AF // Alignment flag
1903  , bool TF > // Transpose flag
1904 template< typename VT2 > // Type of the right-hand side dense vector
1905 inline typename EnableIf< typename DenseSubvector<VT,AF,TF>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >::Type
1907 {
1908  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1909 
1911 
1912  const size_t iend( size_ & size_t(-IT::size*4) );
1913  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
1914 
1915  typename VT2::ConstIterator it( (~rhs).begin() );
1916  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
1917  vector_.storeu( offset_+i , load(i ) + it.load() ); it += IT::size;
1918  vector_.storeu( offset_+i+IT::size , load(i+IT::size ) + it.load() ); it += IT::size;
1919  vector_.storeu( offset_+i+IT::size*2UL, load(i+IT::size*2UL) + it.load() ); it += IT::size;
1920  vector_.storeu( offset_+i+IT::size*3UL, load(i+IT::size*3UL) + it.load() ); it += IT::size;
1921  }
1922  for( size_t i=iend; i<size_; i+=IT::size, it+=IT::size ) {
1923  storeu( i, load(i) + it.load() );
1924  }
1925 }
1926 //*************************************************************************************************
1927 
1928 
1929 //*************************************************************************************************
1940 template< typename VT // Type of the dense vector
1941  , bool AF // Alignment flag
1942  , bool TF > // Transpose flag
1943 template< typename VT2 > // Type of the right-hand side dense vector
1945 {
1946  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1947 
1948  for( typename VT2::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1949  vector_[element->index()+offset_] += element->value();
1950 }
1951 //*************************************************************************************************
1952 
1953 
1954 //*************************************************************************************************
1965 template< typename VT // Type of the dense vector
1966  , bool AF // Alignment flag
1967  , bool TF > // Transpose flag
1968 template< typename VT2 > // Type of the right-hand side dense vector
1969 inline typename DisableIf< typename DenseSubvector<VT,AF,TF>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >::Type
1971 {
1972  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1973 
1974  const size_t iend( size() & size_t(-2) );
1975  for( size_t i=0UL; i<iend; i+=2UL ) {
1976  vector_[i+offset_ ] -= (~rhs)[i ];
1977  vector_[i+offset_+1UL] -= (~rhs)[i+1UL];
1978  }
1979  if( iend < size() ) {
1980  vector_[iend+offset_] -= (~rhs)[iend];
1981  }
1982 }
1983 //*************************************************************************************************
1984 
1985 
1986 //*************************************************************************************************
1997 template< typename VT // Type of the dense vector
1998  , bool AF // Alignment flag
1999  , bool TF > // Transpose flag
2000 template< typename VT2 > // Type of the right-hand side dense vector
2001 inline typename EnableIf< typename DenseSubvector<VT,AF,TF>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >::Type
2003 {
2004  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2005 
2007 
2008  const size_t iend( size_ & size_t(-IT::size*4) );
2009  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
2010 
2011  typename VT2::ConstIterator it( (~rhs).begin() );
2012  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
2013  vector_.storeu( offset_+i , load(i ) - it.load() ); it += IT::size;
2014  vector_.storeu( offset_+i+IT::size , load(i+IT::size ) - it.load() ); it += IT::size;
2015  vector_.storeu( offset_+i+IT::size*2UL, load(i+IT::size*2UL) - it.load() ); it += IT::size;
2016  vector_.storeu( offset_+i+IT::size*3UL, load(i+IT::size*3UL) - it.load() ); it += IT::size;
2017  }
2018  for( size_t i=iend; i<size_; i+=IT::size, it+=IT::size ) {
2019  storeu( i, load(i) - it.load() );
2020  }
2021 }
2022 //*************************************************************************************************
2023 
2024 
2025 //*************************************************************************************************
2036 template< typename VT // Type of the dense vector
2037  , bool AF // Alignment flag
2038  , bool TF > // Transpose flag
2039 template< typename VT2 > // Type of the right-hand side dense vector
2041 {
2042  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2043 
2044  for( typename VT2::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2045  vector_[element->index()+offset_] -= element->value();
2046 }
2047 //*************************************************************************************************
2048 
2049 
2050 //*************************************************************************************************
2061 template< typename VT // Type of the dense vector
2062  , bool AF // Alignment flag
2063  , bool TF > // Transpose flag
2064 template< typename VT2 > // Type of the right-hand side dense vector
2065 inline typename DisableIf< typename DenseSubvector<VT,AF,TF>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >::Type
2067 {
2068  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2069 
2070  const size_t iend( size() & size_t(-2) );
2071  for( size_t i=0UL; i<iend; i+=2UL ) {
2072  vector_[i+offset_ ] *= (~rhs)[i ];
2073  vector_[i+offset_+1UL] *= (~rhs)[i+1UL];
2074  }
2075  if( iend < size() ) {
2076  vector_[iend+offset_] *= (~rhs)[iend];
2077  }
2078 }
2079 //*************************************************************************************************
2080 
2081 
2082 //*************************************************************************************************
2093 template< typename VT // Type of the dense vector
2094  , bool AF // Alignment flag
2095  , bool TF > // Transpose flag
2096 template< typename VT2 > // Type of the right-hand side dense vector
2097 inline typename EnableIf< typename DenseSubvector<VT,AF,TF>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >::Type
2099 {
2100  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2101 
2103 
2104  const size_t iend( size_ & size_t(-IT::size*4) );
2105  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
2106 
2107  typename VT2::ConstIterator it( (~rhs).begin() );
2108  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
2109  vector_.storeu( offset_+i , load(i ) * it.load() ); it += IT::size;
2110  vector_.storeu( offset_+i+IT::size , load(i+IT::size ) * it.load() ); it += IT::size;
2111  vector_.storeu( offset_+i+IT::size*2UL, load(i+IT::size*2UL) * it.load() ); it += IT::size;
2112  vector_.storeu( offset_+i+IT::size*3UL, load(i+IT::size*3UL) * it.load() ); it += IT::size;
2113  }
2114  for( size_t i=iend; i<size_; i+=IT::size, it+=IT::size ) {
2115  storeu( i, load(i) * it.load() );
2116  }
2117 }
2118 //*************************************************************************************************
2119 
2120 
2121 //*************************************************************************************************
2132 template< typename VT // Type of the dense vector
2133  , bool AF // Alignment flag
2134  , bool TF > // Transpose flag
2135 template< typename VT2 > // Type of the right-hand side dense vector
2137 {
2138  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2139 
2140  const ResultType tmp( *this );
2141 
2142  reset();
2143 
2144  for( typename VT2::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2145  vector_[element->index()+offset_] = tmp[element->index()] * element->value();
2146 }
2147 //*************************************************************************************************
2148 
2149 
2150 
2151 
2152 
2153 
2154 
2155 
2156 //=================================================================================================
2157 //
2158 // CLASS TEMPLATE SPECIALIZATION FOR ALIGNED SUBVECTORS
2159 //
2160 //=================================================================================================
2161 
2162 //*************************************************************************************************
2170 template< typename VT // Type of the dense vector
2171  , bool TF > // Transpose flag
2172 class DenseSubvector<VT,aligned,TF> : public DenseVector< DenseSubvector<VT,aligned,TF>, TF >
2173  , private Subvector
2174 {
2175  private:
2176  //**Type definitions****************************************************************************
2178  typedef typename SelectType< IsExpression<VT>::value, VT, VT& >::Type Operand;
2179 
2182  //**********************************************************************************************
2183 
2184  //**********************************************************************************************
2186 
2192  enum { useConst = IsConst<VT>::value };
2193  //**********************************************************************************************
2194 
2195  public:
2196  //**Type definitions****************************************************************************
2197  typedef DenseSubvector<VT,aligned,TF> This;
2198  typedef typename SubvectorTrait<VT>::Type ResultType;
2199  typedef typename ResultType::TransposeType TransposeType;
2200  typedef typename VT::ElementType ElementType;
2201  typedef typename IT::Type IntrinsicType;
2202  typedef typename VT::ReturnType ReturnType;
2203  typedef const DenseSubvector& CompositeType;
2204 
2206  typedef typename VT::ConstReference ConstReference;
2207 
2209  typedef typename SelectType< useConst, ConstReference, typename VT::Reference >::Type Reference;
2210 
2212  typedef const ElementType* ConstPointer;
2213 
2215  typedef typename SelectType< useConst, ConstPointer, ElementType* >::Type Pointer;
2216 
2218  typedef typename VT::ConstIterator ConstIterator;
2219 
2221  typedef typename SelectType< useConst, ConstIterator, typename VT::Iterator >::Type Iterator;
2222  //**********************************************************************************************
2223 
2224  //**Compilation flags***************************************************************************
2226  enum { vectorizable = VT::vectorizable };
2227 
2229  enum { smpAssignable = VT::smpAssignable };
2230  //**********************************************************************************************
2231 
2232  //**Constructors********************************************************************************
2235  explicit inline DenseSubvector( Operand vector, size_t index, size_t n );
2236  // No explicitly declared copy constructor.
2238  //**********************************************************************************************
2239 
2240  //**Destructor**********************************************************************************
2241  // No explicitly declared destructor.
2242  //**********************************************************************************************
2243 
2244  //**Data access functions***********************************************************************
2247  inline Reference operator[]( size_t index );
2248  inline ConstReference operator[]( size_t index ) const;
2249  inline Pointer data ();
2250  inline ConstPointer data () const;
2251  inline Iterator begin ();
2252  inline ConstIterator begin () const;
2253  inline ConstIterator cbegin() const;
2254  inline Iterator end ();
2255  inline ConstIterator end () const;
2256  inline ConstIterator cend () const;
2258  //**********************************************************************************************
2259 
2260  //**Assignment operators************************************************************************
2263  inline DenseSubvector& operator= ( const ElementType& rhs );
2264  inline DenseSubvector& operator= ( const DenseSubvector& rhs );
2265  template< typename VT2 > inline DenseSubvector& operator= ( const Vector<VT2,TF>& rhs );
2266  template< typename VT2 > inline DenseSubvector& operator+=( const Vector<VT2,TF>& rhs );
2267  template< typename VT2 > inline DenseSubvector& operator-=( const Vector<VT2,TF>& rhs );
2268  template< typename VT2 > inline DenseSubvector& operator*=( const Vector<VT2,TF>& rhs );
2269 
2270  template< typename Other >
2271  inline typename EnableIf< IsNumeric<Other>, DenseSubvector >::Type&
2272  operator*=( Other rhs );
2273 
2274  template< typename Other >
2275  inline typename EnableIf< IsNumeric<Other>, DenseSubvector >::Type&
2276  operator/=( Other rhs );
2278  //**********************************************************************************************
2279 
2280  //**Utility functions***************************************************************************
2283  inline size_t size() const;
2284  inline size_t capacity() const;
2285  inline size_t nonZeros() const;
2286  inline void reset();
2287  template< typename Other > inline DenseSubvector& scale( const Other& scalar );
2289  //**********************************************************************************************
2290 
2291  private:
2292  //**********************************************************************************************
2294  template< typename VT2 >
2295  struct VectorizedAssign {
2296  enum { value = vectorizable && VT2::vectorizable &&
2297  IsSame<ElementType,typename VT2::ElementType>::value };
2298  };
2299  //**********************************************************************************************
2300 
2301  //**********************************************************************************************
2303  template< typename VT2 >
2304  struct VectorizedAddAssign {
2305  enum { value = vectorizable && VT2::vectorizable &&
2306  IsSame<ElementType,typename VT2::ElementType>::value &&
2307  IntrinsicTrait<ElementType>::addition };
2308  };
2309  //**********************************************************************************************
2310 
2311  //**********************************************************************************************
2313  template< typename VT2 >
2314  struct VectorizedSubAssign {
2315  enum { value = vectorizable && VT2::vectorizable &&
2316  IsSame<ElementType,typename VT2::ElementType>::value &&
2317  IntrinsicTrait<ElementType>::subtraction };
2318  };
2319  //**********************************************************************************************
2320 
2321  //**********************************************************************************************
2323  template< typename VT2 >
2324  struct VectorizedMultAssign {
2325  enum { value = vectorizable && VT2::vectorizable &&
2326  IsSame<ElementType,typename VT2::ElementType>::value &&
2327  IntrinsicTrait<ElementType>::multiplication };
2328  };
2329  //**********************************************************************************************
2330 
2331  public:
2332  //**Expression template evaluation functions****************************************************
2335  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2336  template< typename Other > inline bool isAliased( const Other* alias ) const;
2337 
2338  inline bool isAligned () const;
2339  inline bool canSMPAssign() const;
2340 
2341  inline IntrinsicType load ( size_t index ) const;
2342  inline IntrinsicType loadu ( size_t index ) const;
2343  inline void store ( size_t index, const IntrinsicType& value );
2344  inline void storeu( size_t index, const IntrinsicType& value );
2345  inline void stream( size_t index, const IntrinsicType& value );
2346 
2347  template< typename VT2 >
2348  inline typename DisableIf< VectorizedAssign<VT2> >::Type
2349  assign( const DenseVector <VT2,TF>& rhs );
2350 
2351  template< typename VT2 >
2352  inline typename EnableIf< VectorizedAssign<VT2> >::Type
2353  assign( const DenseVector <VT2,TF>& rhs );
2354 
2355  template< typename VT2 > inline void assign( const SparseVector<VT2,TF>& rhs );
2356 
2357  template< typename VT2 >
2358  inline typename DisableIf< VectorizedAddAssign<VT2> >::Type
2359  addAssign( const DenseVector <VT2,TF>& rhs );
2360 
2361  template< typename VT2 >
2362  inline typename EnableIf< VectorizedAddAssign<VT2> >::Type
2363  addAssign ( const DenseVector <VT2,TF>& rhs );
2364 
2365  template< typename VT2 > inline void addAssign( const SparseVector<VT2,TF>& rhs );
2366 
2367  template< typename VT2 >
2368  inline typename DisableIf< VectorizedSubAssign<VT2> >::Type
2369  subAssign ( const DenseVector <VT2,TF>& rhs );
2370 
2371  template< typename VT2 >
2372  inline typename EnableIf< VectorizedSubAssign<VT2> >::Type
2373  subAssign( const DenseVector <VT2,TF>& rhs );
2374 
2375  template< typename VT2 > inline void subAssign( const SparseVector<VT2,TF>& rhs );
2376 
2377  template< typename VT2 >
2378  inline typename DisableIf< VectorizedMultAssign<VT2> >::Type
2379  multAssign( const DenseVector <VT2,TF>& rhs );
2380 
2381  template< typename VT2 >
2382  inline typename EnableIf< VectorizedMultAssign<VT2> >::Type
2383  multAssign( const DenseVector <VT2,TF>& rhs );
2384 
2385  template< typename VT2 > inline void multAssign( const SparseVector<VT2,TF>& rhs );
2387  //**********************************************************************************************
2388 
2389  private:
2390  //**Member variables****************************************************************************
2393  Operand vector_;
2394  const size_t offset_;
2395  const size_t size_;
2396 
2397  //**********************************************************************************************
2398 
2399  //**Friend declarations*************************************************************************
2400  template< bool AF1, typename VT2, bool AF2, bool TF2 >
2401  friend const DenseSubvector<VT2,AF1,TF2>
2402  subvector( const DenseSubvector<VT2,AF2,TF2>& dv, size_t index, size_t size );
2403  //**********************************************************************************************
2404 
2405  //**Compile time checks*************************************************************************
2411  //**********************************************************************************************
2412 };
2414 //*************************************************************************************************
2415 
2416 
2417 
2418 
2419 //=================================================================================================
2420 //
2421 // CONSTRUCTOR
2422 //
2423 //=================================================================================================
2424 
2425 //*************************************************************************************************
2438 template< typename VT // Type of the dense vector
2439  , bool TF > // Transpose flag
2440 inline DenseSubvector<VT,aligned,TF>::DenseSubvector( Operand vector, size_t index, size_t n )
2441  : vector_( vector ) // The vector containing the subvector
2442  , offset_( index ) // The offset of the subvector within the dense vector
2443  , size_ ( n ) // The size of the subvector
2444 {
2445  if( index + n > vector.size() )
2446  throw std::invalid_argument( "Invalid subvector specification" );
2447 
2448  if( offset_ % IT::size != 0UL || ( offset_ + size_ != vector_.size() && size_ % IT::size != 0UL ) )
2449  throw std::invalid_argument( "Invalid subvector alignment" );
2450 }
2452 //*************************************************************************************************
2453 
2454 
2455 
2456 
2457 //=================================================================================================
2458 //
2459 // DATA ACCESS FUNCTIONS
2460 //
2461 //=================================================================================================
2462 
2463 //*************************************************************************************************
2470 template< typename VT // Type of the dense vector
2471  , bool TF > // Transpose flag
2474 {
2475  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
2476  return vector_[offset_+index];
2477 }
2479 //*************************************************************************************************
2480 
2481 
2482 //*************************************************************************************************
2489 template< typename VT // Type of the dense vector
2490  , bool TF > // Transpose flag
2492  DenseSubvector<VT,aligned,TF>::operator[]( size_t index ) const
2493 {
2494  BLAZE_USER_ASSERT( index < size(), "Invalid subvector access index" );
2495  return const_cast<const VT&>( vector_ )[offset_+index];
2496 }
2498 //*************************************************************************************************
2499 
2500 
2501 //*************************************************************************************************
2509 template< typename VT // Type of the dense vector
2510  , bool TF > // Transpose flag
2511 inline typename DenseSubvector<VT,aligned,TF>::Pointer DenseSubvector<VT,aligned,TF>::data()
2512 {
2513  return vector_.data() + offset_;
2514 }
2516 //*************************************************************************************************
2517 
2518 
2519 //*************************************************************************************************
2527 template< typename VT // Type of the dense vector
2528  , bool TF > // Transpose flag
2529 inline typename DenseSubvector<VT,aligned,TF>::ConstPointer DenseSubvector<VT,aligned,TF>::data() const
2530 {
2531  return vector_.data() + offset_;
2532 }
2534 //*************************************************************************************************
2535 
2536 
2537 //*************************************************************************************************
2545 template< typename VT // Type of the dense vector
2546  , bool TF > // Transpose flag
2548 {
2549  return ( vector_.begin() + offset_ );
2550 }
2552 //*************************************************************************************************
2553 
2554 
2555 //*************************************************************************************************
2563 template< typename VT // Type of the dense vector
2564  , bool TF > // Transpose flag
2567 {
2568  return ( vector_.cbegin() + offset_ );
2569 }
2571 //*************************************************************************************************
2572 
2573 
2574 //*************************************************************************************************
2582 template< typename VT // Type of the dense vector
2583  , bool TF > // Transpose flag
2586 {
2587  return ( vector_.cbegin() + offset_ );
2588 }
2590 //*************************************************************************************************
2591 
2592 
2593 //*************************************************************************************************
2601 template< typename VT // Type of the dense vector
2602  , bool TF > // Transpose flag
2604 {
2605  return ( vector_.begin() + offset_ + size_ );
2606 }
2608 //*************************************************************************************************
2609 
2610 
2611 //*************************************************************************************************
2619 template< typename VT // Type of the dense vector
2620  , bool TF > // Transpose flag
2623 {
2624  return ( vector_.cbegin() + offset_ + size_ );
2625 }
2627 //*************************************************************************************************
2628 
2629 
2630 //*************************************************************************************************
2638 template< typename VT // Type of the dense vector
2639  , bool TF > // Transpose flag
2642 {
2643  return ( vector_.cbegin() + offset_ + size_ );
2644 }
2646 //*************************************************************************************************
2647 
2648 
2649 
2650 
2651 //=================================================================================================
2652 //
2653 // ASSIGNMENT OPERATORS
2654 //
2655 //=================================================================================================
2656 
2657 //*************************************************************************************************
2664 template< typename VT // Type of the dense vector
2665  , bool TF > // Transpose flag
2666 inline DenseSubvector<VT,aligned,TF>&
2668 {
2669  const size_t iend( offset_ + size_ );
2670 
2671  for( size_t i=offset_; i<iend; ++i )
2672  vector_[i] = rhs;
2673 
2674  return *this;
2675 }
2677 //*************************************************************************************************
2678 
2679 
2680 //*************************************************************************************************
2691 template< typename VT // Type of the dense vector
2692  , bool TF > // Transpose flag
2693 inline DenseSubvector<VT,aligned,TF>&
2694  DenseSubvector<VT,aligned,TF>::operator=( const DenseSubvector& rhs )
2695 {
2698 
2699  if( &rhs == this || ( &vector_ == &rhs.vector_ && offset_ == rhs.offset_ ) )
2700  return *this;
2701 
2702  if( size() != rhs.size() )
2703  throw std::invalid_argument( "Subvector sizes do not match" );
2704 
2705  if( rhs.canAlias( &vector_ ) ) {
2706  const ResultType tmp( ~rhs );
2707  smpAssign( *this, tmp );
2708  }
2709  else {
2710  smpAssign( *this, rhs );
2711  }
2712 
2713  return *this;
2714 }
2716 //*************************************************************************************************
2717 
2718 
2719 //*************************************************************************************************
2730 template< typename VT // Type of the dense vector
2731  , bool TF > // Transpose flag
2732 template< typename VT2 > // Type of the right-hand side vector
2733 inline DenseSubvector<VT,aligned,TF>&
2734  DenseSubvector<VT,aligned,TF>::operator=( const Vector<VT2,TF>& rhs )
2735 {
2738 
2739  if( size() != (~rhs).size() )
2740  throw std::invalid_argument( "Vector sizes do not match" );
2741 
2742  if( (~rhs).canAlias( &vector_ ) ) {
2743  const typename VT2::ResultType tmp( ~rhs );
2744  smpAssign( *this, tmp );
2745  }
2746  else {
2747  if( IsSparseVector<VT2>::value )
2748  reset();
2749  smpAssign( *this, ~rhs );
2750  }
2751 
2752  return *this;
2753 }
2755 //*************************************************************************************************
2756 
2757 
2758 //*************************************************************************************************
2769 template< typename VT // Type of the dense vector
2770  , bool TF > // Transpose flag
2771 template< typename VT2 > // Type of the right-hand side vector
2772 inline DenseSubvector<VT,aligned,TF>&
2773  DenseSubvector<VT,aligned,TF>::operator+=( const Vector<VT2,TF>& rhs )
2774 {
2777 
2778  if( size() != (~rhs).size() )
2779  throw std::invalid_argument( "Vector sizes do not match" );
2780 
2781  if( (~rhs).canAlias( &vector_ ) ) {
2782  const typename VT2::ResultType tmp( ~rhs );
2783  smpAddAssign( *this, tmp );
2784  }
2785  else {
2786  smpAddAssign( *this, ~rhs );
2787  }
2788 
2789  return *this;
2790 }
2792 //*************************************************************************************************
2793 
2794 
2795 //*************************************************************************************************
2806 template< typename VT // Type of the dense vector
2807  , bool TF > // Transpose flag
2808 template< typename VT2 > // Type of the right-hand side vector
2809 inline DenseSubvector<VT,aligned,TF>&
2810  DenseSubvector<VT,aligned,TF>::operator-=( const Vector<VT2,TF>& rhs )
2811 {
2814 
2815  if( size() != (~rhs).size() )
2816  throw std::invalid_argument( "Vector sizes do not match" );
2817 
2818  if( (~rhs).canAlias( &vector_ ) ) {
2819  const typename VT2::ResultType tmp( ~rhs );
2820  smpSubAssign( *this, tmp );
2821  }
2822  else {
2823  smpSubAssign( *this, ~rhs );
2824  }
2825 
2826  return *this;
2827 }
2829 //*************************************************************************************************
2830 
2831 
2832 //*************************************************************************************************
2844 template< typename VT // Type of the dense vector
2845  , bool TF > // Transpose flag
2846 template< typename VT2 > // Type of the right-hand side vector
2847 inline DenseSubvector<VT,aligned,TF>&
2848  DenseSubvector<VT,aligned,TF>::operator*=( const Vector<VT2,TF>& rhs )
2849 {
2852 
2853  if( size() != (~rhs).size() )
2854  throw std::invalid_argument( "Vector sizes do not match" );
2855 
2856  if( (~rhs).canAlias( &vector_ ) || IsSparseVector<VT2>::value ) {
2857  const typename VT2::ResultType tmp( ~rhs );
2858  smpMultAssign( *this, tmp );
2859  }
2860  else {
2861  smpMultAssign( *this, ~rhs );
2862  }
2863 
2864  return *this;
2865 }
2867 //*************************************************************************************************
2868 
2869 
2870 //*************************************************************************************************
2878 template< typename VT // Type of the dense vector
2879  , bool TF > // Transpose flag
2880 template< typename Other > // Data type of the right-hand side scalar
2881 inline typename EnableIf< IsNumeric<Other>, DenseSubvector<VT,aligned,TF> >::Type&
2882  DenseSubvector<VT,aligned,TF>::operator*=( Other rhs )
2883 {
2884  smpAssign( *this, (*this) * rhs );
2885  return *this;
2886 }
2888 //*************************************************************************************************
2889 
2890 
2891 //*************************************************************************************************
2901 template< typename VT // Type of the dense vector
2902  , bool TF > // Transpose flag
2903 template< typename Other > // Data type of the right-hand side scalar
2904 inline typename EnableIf< IsNumeric<Other>, DenseSubvector<VT,aligned,TF> >::Type&
2905  DenseSubvector<VT,aligned,TF>::operator/=( Other rhs )
2906 {
2907  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
2908 
2909  smpAssign( *this, (*this) / rhs );
2910  return *this;
2911 }
2913 //*************************************************************************************************
2914 
2915 
2916 
2917 
2918 //=================================================================================================
2919 //
2920 // UTILITY FUNCTIONS
2921 //
2922 //=================================================================================================
2923 
2924 //*************************************************************************************************
2930 template< typename VT // Type of the dense vector
2931  , bool TF > // Transpose flag
2932 inline size_t DenseSubvector<VT,aligned,TF>::size() const
2933 {
2934  return size_;
2935 }
2937 //*************************************************************************************************
2938 
2939 
2940 //*************************************************************************************************
2946 template< typename VT // Type of the dense vector
2947  , bool TF > // Transpose flag
2948 inline size_t DenseSubvector<VT,aligned,TF>::capacity() const
2949 {
2950  return vector_.capacity() - offset_;
2951 }
2953 //*************************************************************************************************
2954 
2955 
2956 //*************************************************************************************************
2965 template< typename VT // Type of the dense vector
2966  , bool TF > // Transpose flag
2967 inline size_t DenseSubvector<VT,aligned,TF>::nonZeros() const
2968 {
2969  size_t nonzeros( 0 );
2970 
2971  const size_t iend( offset_ + size_ );
2972  for( size_t i=offset_; i<iend; ++i ) {
2973  if( !isDefault( vector_[i] ) )
2974  ++nonzeros;
2975  }
2976 
2977  return nonzeros;
2978 }
2980 //*************************************************************************************************
2981 
2982 
2983 //*************************************************************************************************
2989 template< typename VT // Type of the dense vector
2990  , bool TF > // Transpose flag
2992 {
2993  using blaze::reset;
2994 
2995  const size_t iend( offset_ + size_ );
2996  for( size_t i=offset_; i<iend; ++i )
2997  reset( vector_[i] );
2998 }
3000 //*************************************************************************************************
3001 
3002 
3003 //*************************************************************************************************
3010 template< typename VT // Type of the dense vector
3011  , bool TF > // Transpose flag
3012 template< typename Other > // Data type of the scalar value
3013 inline DenseSubvector<VT,aligned,TF>& DenseSubvector<VT,aligned,TF>::scale( const Other& scalar )
3014 {
3015  const size_t iend( offset_ + size_ );
3016  for( size_t i=offset_; i<iend; ++i )
3017  vector_[i] *= scalar;
3018  return *this;
3019 }
3021 //*************************************************************************************************
3022 
3023 
3024 
3025 
3026 //=================================================================================================
3027 //
3028 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3029 //
3030 //=================================================================================================
3031 
3032 //*************************************************************************************************
3043 template< typename VT // Type of the dense vector
3044  , bool TF > // Transpose flag
3045 template< typename Other > // Data type of the foreign expression
3046 inline bool DenseSubvector<VT,aligned,TF>::canAlias( const Other* alias ) const
3047 {
3048  return static_cast<const void*>( &vector_ ) == static_cast<const void*>( alias );
3049 }
3051 //*************************************************************************************************
3052 
3053 
3054 //*************************************************************************************************
3065 template< typename VT // Type of the dense vector
3066  , bool TF > // Transpose flag
3067 template< typename Other > // Data type of the foreign expression
3068 inline bool DenseSubvector<VT,aligned,TF>::isAliased( const Other* alias ) const
3069 {
3070  return static_cast<const void*>( &vector_ ) == static_cast<const void*>( alias );
3071 }
3073 //*************************************************************************************************
3074 
3075 
3076 //*************************************************************************************************
3086 template< typename VT // Type of the dense vector
3087  , bool TF > // Transpose flag
3088 inline bool DenseSubvector<VT,aligned,TF>::isAligned() const
3089 {
3090  return true;
3091 }
3093 //*************************************************************************************************
3094 
3095 
3096 //*************************************************************************************************
3107 template< typename VT // Type of the dense vector
3108  , bool TF > // Transpose flag
3110 {
3111  return ( size() > OPENMP_DVECASSIGN_THRESHOLD );
3112 }
3114 //*************************************************************************************************
3115 
3116 
3117 //*************************************************************************************************
3131 template< typename VT // Type of the dense vector
3132  , bool TF > // Transpose flag
3133 inline typename DenseSubvector<VT,aligned,TF>::IntrinsicType
3134  DenseSubvector<VT,aligned,TF>::load( size_t index ) const
3135 {
3137 
3138  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
3139  BLAZE_INTERNAL_ASSERT( index % IT::size == 0UL, "Invalid subvector access index" );
3140 
3141  return vector_.load( offset_+index );
3142 }
3144 //*************************************************************************************************
3145 
3146 
3147 //*************************************************************************************************
3161 template< typename VT // Type of the dense vector
3162  , bool TF > // Transpose flag
3163 inline typename DenseSubvector<VT,aligned,TF>::IntrinsicType
3164  DenseSubvector<VT,aligned,TF>::loadu( size_t index ) const
3165 {
3167 
3168  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
3169  BLAZE_INTERNAL_ASSERT( index % IT::size == 0UL, "Invalid subvector access index" );
3170 
3171  return vector_.loadu( offset_+index );
3172 }
3174 //*************************************************************************************************
3175 
3176 
3177 //*************************************************************************************************
3192 template< typename VT // Type of the dense vector
3193  , bool TF > // Transpose flag
3194 inline void DenseSubvector<VT,aligned,TF>::store( size_t index, const IntrinsicType& value )
3195 {
3197 
3198  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
3199  BLAZE_INTERNAL_ASSERT( index % IT::size == 0UL, "Invalid subvector access index" );
3200 
3201  vector_.store( offset_+index, value );
3202 }
3204 //*************************************************************************************************
3205 
3206 
3207 //*************************************************************************************************
3222 template< typename VT // Type of the dense vector
3223  , bool TF > // Transpose flag
3224 inline void DenseSubvector<VT,aligned,TF>::storeu( size_t index, const IntrinsicType& value )
3225 {
3227 
3228  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
3229  BLAZE_INTERNAL_ASSERT( index % IT::size == 0UL, "Invalid subvector access index" );
3230 
3231  vector_.storeu( offset_+index, value );
3232 }
3234 //*************************************************************************************************
3235 
3236 
3237 //*************************************************************************************************
3252 template< typename VT // Type of the dense vector
3253  , bool TF > // Transpose flag
3254 inline void DenseSubvector<VT,aligned,TF>::stream( size_t index, const IntrinsicType& value )
3255 {
3257 
3258  BLAZE_INTERNAL_ASSERT( index < size() , "Invalid subvector access index" );
3259  BLAZE_INTERNAL_ASSERT( index % IT::size == 0UL, "Invalid subvector access index" );
3260 
3261  vector_.stream( offset_+index, value );
3262 }
3264 //*************************************************************************************************
3265 
3266 
3267 //*************************************************************************************************
3279 template< typename VT // Type of the dense vector
3280  , bool TF > // Transpose flag
3281 template< typename VT2 > // Type of the right-hand side dense vector
3282 inline typename DisableIf< typename DenseSubvector<VT,aligned,TF>::BLAZE_TEMPLATE VectorizedAssign<VT2> >::Type
3283  DenseSubvector<VT,aligned,TF>::assign( const DenseVector<VT2,TF>& rhs )
3284 {
3285  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3286 
3287  const size_t iend( size() & size_t(-2) );
3288  for( size_t i=0UL; i<iend; i+=2UL ) {
3289  vector_[i+offset_ ] = (~rhs)[i ];
3290  vector_[i+offset_+1UL] = (~rhs)[i+1UL];
3291  }
3292  if( iend < size() ) {
3293  vector_[iend+offset_] = (~rhs)[iend];
3294  }
3295 }
3297 //*************************************************************************************************
3298 
3299 
3300 //*************************************************************************************************
3312 template< typename VT // Type of the dense vector
3313  , bool TF > // Transpose flag
3314 template< typename VT2 > // Type of the right-hand side dense vector
3315 inline typename EnableIf< typename DenseSubvector<VT,aligned,TF>::BLAZE_TEMPLATE VectorizedAssign<VT2> >::Type
3316  DenseSubvector<VT,aligned,TF>::assign( const DenseVector<VT2,TF>& rhs )
3317 {
3318  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3319 
3321 
3322  if( useStreaming && size_ > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( &vector_ ) )
3323  {
3324  for( size_t i=0UL; i<size(); i+=IT::size ) {
3325  vector_.stream( offset_+i, (~rhs).load(i) );
3326  }
3327  }
3328  else
3329  {
3330  const size_t iend( size_ & size_t(-IT::size*4) );
3331  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
3332 
3333  typename VT2::ConstIterator it( (~rhs).begin() );
3334  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
3335  store( i , it.load() ); it += IT::size;
3336  store( i+IT::size , it.load() ); it += IT::size;
3337  store( i+IT::size*2UL, it.load() ); it += IT::size;
3338  store( i+IT::size*3UL, it.load() ); it += IT::size;
3339  }
3340  for( size_t i=iend; i<size_; i+=IT::size, it+=IT::size ) {
3341  store( i, it.load() );
3342  }
3343  }
3344 }
3346 //*************************************************************************************************
3347 
3348 
3349 //*************************************************************************************************
3361 template< typename VT // Type of the dense vector
3362  , bool TF > // Transpose flag
3363 template< typename VT2 > // Type of the right-hand side dense vector
3364 inline void DenseSubvector<VT,aligned,TF>::assign( const SparseVector<VT2,TF>& rhs )
3365 {
3366  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3367 
3368  for( typename VT2::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3369  vector_[element->index()+offset_] = element->value();
3370 }
3372 //*************************************************************************************************
3373 
3374 
3375 //*************************************************************************************************
3387 template< typename VT // Type of the dense vector
3388  , bool TF > // Transpose flag
3389 template< typename VT2 > // Type of the right-hand side dense vector
3390 inline typename DisableIf< typename DenseSubvector<VT,aligned,TF>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >::Type
3391  DenseSubvector<VT,aligned,TF>::addAssign( const DenseVector<VT2,TF>& rhs )
3392 {
3393  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3394 
3395  const size_t iend( size() & size_t(-2) );
3396  for( size_t i=0UL; i<iend; i+=2UL ) {
3397  vector_[i+offset_ ] += (~rhs)[i ];
3398  vector_[i+offset_+1UL] += (~rhs)[i+1UL];
3399  }
3400  if( iend < size() ) {
3401  vector_[iend+offset_] += (~rhs)[iend];
3402  }
3403 }
3405 //*************************************************************************************************
3406 
3407 
3408 //*************************************************************************************************
3420 template< typename VT // Type of the dense vector
3421  , bool TF > // Transpose flag
3422 template< typename VT2 > // Type of the right-hand side dense vector
3423 inline typename EnableIf< typename DenseSubvector<VT,aligned,TF>::BLAZE_TEMPLATE VectorizedAddAssign<VT2> >::Type
3424  DenseSubvector<VT,aligned,TF>::addAssign( const DenseVector<VT2,TF>& rhs )
3425 {
3426  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3427 
3429 
3430  const size_t iend( size_ & size_t(-IT::size*4) );
3431  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
3432 
3433  typename VT2::ConstIterator it( (~rhs).begin() );
3434  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
3435  store( i , load(i ) + it.load() ); it += IT::size;
3436  store( i+IT::size , load(i+IT::size ) + it.load() ); it += IT::size;
3437  store( i+IT::size*2UL, load(i+IT::size*2UL) + it.load() ); it += IT::size;
3438  store( i+IT::size*3UL, load(i+IT::size*3UL) + it.load() ); it += IT::size;
3439  }
3440  for( size_t i=iend; i<size_; i+=IT::size, it+=IT::size ) {
3441  store( i, load(i) + it.load() );
3442  }
3443 }
3445 //*************************************************************************************************
3446 
3447 
3448 //*************************************************************************************************
3460 template< typename VT // Type of the dense vector
3461  , bool TF > // Transpose flag
3462 template< typename VT2 > // Type of the right-hand side dense vector
3463 inline void DenseSubvector<VT,aligned,TF>::addAssign( const SparseVector<VT2,TF>& rhs )
3464 {
3465  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3466 
3467  for( typename VT2::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3468  vector_[element->index()+offset_] += element->value();
3469 }
3471 //*************************************************************************************************
3472 
3473 
3474 //*************************************************************************************************
3486 template< typename VT // Type of the dense vector
3487  , bool TF > // Transpose flag
3488 template< typename VT2 > // Type of the right-hand side dense vector
3489 inline typename DisableIf< typename DenseSubvector<VT,aligned,TF>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >::Type
3490  DenseSubvector<VT,aligned,TF>::subAssign( const DenseVector<VT2,TF>& rhs )
3491 {
3492  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3493 
3494  const size_t iend( size() & size_t(-2) );
3495  for( size_t i=0UL; i<iend; i+=2UL ) {
3496  vector_[i+offset_ ] -= (~rhs)[i ];
3497  vector_[i+offset_+1UL] -= (~rhs)[i+1UL];
3498  }
3499  if( iend < size() ) {
3500  vector_[iend+offset_] -= (~rhs)[iend];
3501  }
3502 }
3504 //*************************************************************************************************
3505 
3506 
3507 //*************************************************************************************************
3519 template< typename VT // Type of the dense vector
3520  , bool TF > // Transpose flag
3521 template< typename VT2 > // Type of the right-hand side dense vector
3522 inline typename EnableIf< typename DenseSubvector<VT,aligned,TF>::BLAZE_TEMPLATE VectorizedSubAssign<VT2> >::Type
3523  DenseSubvector<VT,aligned,TF>::subAssign( const DenseVector<VT2,TF>& rhs )
3524 {
3525  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3526 
3528 
3529  const size_t iend( size_ & size_t(-IT::size*4) );
3530  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
3531 
3532  typename VT2::ConstIterator it( (~rhs).begin() );
3533  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
3534  store( i , load(i ) - it.load() ); it += IT::size;
3535  store( i+IT::size , load(i+IT::size ) - it.load() ); it += IT::size;
3536  store( i+IT::size*2UL, load(i+IT::size*2UL) - it.load() ); it += IT::size;
3537  store( i+IT::size*3UL, load(i+IT::size*3UL) - it.load() ); it += IT::size;
3538  }
3539  for( size_t i=iend; i<size_; i+=IT::size, it+=IT::size ) {
3540  store( i, load(i) - it.load() );
3541  }
3542 }
3544 //*************************************************************************************************
3545 
3546 
3547 //*************************************************************************************************
3559 template< typename VT // Type of the dense vector
3560  , bool TF > // Transpose flag
3561 template< typename VT2 > // Type of the right-hand side dense vector
3562 inline void DenseSubvector<VT,aligned,TF>::subAssign( const SparseVector<VT2,TF>& rhs )
3563 {
3564  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3565 
3566  for( typename VT2::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3567  vector_[element->index()+offset_] -= element->value();
3568 }
3570 //*************************************************************************************************
3571 
3572 
3573 //*************************************************************************************************
3585 template< typename VT // Type of the dense vector
3586  , bool TF > // Transpose flag
3587 template< typename VT2 > // Type of the right-hand side dense vector
3588 inline typename DisableIf< typename DenseSubvector<VT,aligned,TF>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >::Type
3589  DenseSubvector<VT,aligned,TF>::multAssign( const DenseVector<VT2,TF>& rhs )
3590 {
3591  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3592 
3593  const size_t iend( size() & size_t(-2) );
3594  for( size_t i=0UL; i<iend; i+=2UL ) {
3595  vector_[i+offset_ ] *= (~rhs)[i ];
3596  vector_[i+offset_+1UL] *= (~rhs)[i+1UL];
3597  }
3598  if( iend < size() ) {
3599  vector_[iend+offset_] *= (~rhs)[iend];
3600  }
3601 }
3603 //*************************************************************************************************
3604 
3605 
3606 //*************************************************************************************************
3618 template< typename VT // Type of the dense vector
3619  , bool TF > // Transpose flag
3620 template< typename VT2 > // Type of the right-hand side dense vector
3621 inline typename EnableIf< typename DenseSubvector<VT,aligned,TF>::BLAZE_TEMPLATE VectorizedMultAssign<VT2> >::Type
3622  DenseSubvector<VT,aligned,TF>::multAssign( const DenseVector<VT2,TF>& rhs )
3623 {
3624  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3625 
3627 
3628  const size_t iend( size_ & size_t(-IT::size*4) );
3629  BLAZE_INTERNAL_ASSERT( ( size_ - ( size_ % (IT::size*4UL) ) ) == iend, "Invalid end calculation" );
3630 
3631  typename VT2::ConstIterator it( (~rhs).begin() );
3632  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
3633  store( i , load(i ) * it.load() ); it += IT::size;
3634  store( i+IT::size , load(i+IT::size ) * it.load() ); it += IT::size;
3635  store( i+IT::size*2UL, load(i+IT::size*2UL) * it.load() ); it += IT::size;
3636  store( i+IT::size*3UL, load(i+IT::size*3UL) * it.load() ); it += IT::size;
3637  }
3638  for( size_t i=iend; i<size_; i+=IT::size, it+=IT::size ) {
3639  store( i, load(i) * it.load() );
3640  }
3641 }
3643 //*************************************************************************************************
3644 
3645 
3646 //*************************************************************************************************
3658 template< typename VT // Type of the dense vector
3659  , bool TF > // Transpose flag
3660 template< typename VT2 > // Type of the right-hand side dense vector
3661 inline void DenseSubvector<VT,aligned,TF>::multAssign( const SparseVector<VT2,TF>& rhs )
3662 {
3663  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3664 
3665  const ResultType tmp( *this );
3666 
3667  reset();
3668 
3669  for( typename VT2::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3670  vector_[element->index()+offset_] = tmp[element->index()] * element->value();
3671 }
3673 //*************************************************************************************************
3674 
3675 
3676 
3677 
3678 
3679 
3680 
3681 
3682 //=================================================================================================
3683 //
3684 // CLASS TEMPLATE SPECIALIZATION FOR DVECDVECCROSSEXPR
3685 //
3686 //=================================================================================================
3687 
3688 //*************************************************************************************************
3696 template< typename VT1 // Type of the left-hand side dense vector
3697  , typename VT2 > // Type of the right-hand side dense vector
3698 class DenseSubvector< DVecDVecCrossExpr<VT1,VT2>, unaligned, false >
3699  : public DenseVector< DenseSubvector< DVecDVecCrossExpr<VT1,VT2>, unaligned, false >, false >
3700  , private Subvector
3701 {
3702  private:
3703  //**Type definitions****************************************************************************
3704  typedef DVecDVecCrossExpr<VT1,VT2> CPE;
3705  typedef typename CPE::ResultType RT;
3706  //**********************************************************************************************
3707 
3708  public:
3709  //**Type definitions****************************************************************************
3710  typedef DenseSubvector<CPE,unaligned,false> This;
3711  typedef typename SubvectorTrait<RT>::Type ResultType;
3712  typedef typename ResultType::TransposeType TransposeType;
3713  typedef typename CPE::ElementType ElementType;
3714  typedef typename CPE::ReturnType ReturnType;
3715  typedef const ResultType CompositeType;
3716  //**********************************************************************************************
3717 
3718  //**Compilation flags***************************************************************************
3720  enum { vectorizable = 0 };
3721 
3723  enum { smpAssignable = 0 };
3724  //**********************************************************************************************
3725 
3726  //**Constructor*********************************************************************************
3733  explicit inline DenseSubvector( const CPE& vector, size_t index, size_t n )
3734  : vector_( vector ) // The dense vector/dense vector cross product expression
3735  , offset_( index ) // The offset of the subvector within the cross product expression
3736  , size_ ( n ) // The size of the subvector
3737  {}
3738  //**********************************************************************************************
3739 
3740  //**Subscript operator**************************************************************************
3746  inline ReturnType operator[]( size_t index ) const {
3747  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
3748  return vector_[offset_+index];
3749  }
3750  //**********************************************************************************************
3751 
3752  //**Size function*******************************************************************************
3757  inline size_t size() const {
3758  return size_;
3759  }
3760  //**********************************************************************************************
3761 
3762  //**********************************************************************************************
3768  template< typename T >
3769  inline bool canAlias( const T* alias ) const {
3770  return vector_.canAlias( alias );
3771  }
3772  //**********************************************************************************************
3773 
3774  //**********************************************************************************************
3780  template< typename T >
3781  inline bool isAliased( const T* alias ) const {
3782  return vector_.isAliased( alias );
3783  }
3784  //**********************************************************************************************
3785 
3786  private:
3787  //**Member variables****************************************************************************
3790  CPE vector_;
3791  const size_t offset_;
3792  const size_t size_;
3793 
3794  //**********************************************************************************************
3795 
3796  //**Friend declarations*************************************************************************
3797  template< bool AF1, typename VT, bool AF2, bool TF >
3798  friend const DenseSubvector<VT,AF1,TF>
3799  subvector( const DenseSubvector<VT,AF2,TF>& dv, size_t index, size_t size );
3800  //**********************************************************************************************
3801 };
3803 //*************************************************************************************************
3804 
3805 
3806 
3807 
3808 
3809 
3810 
3811 
3812 //=================================================================================================
3813 //
3814 // CLASS TEMPLATE SPECIALIZATION FOR DVECSVECCROSSEXPR
3815 //
3816 //=================================================================================================
3817 
3818 //*************************************************************************************************
3826 template< typename VT1 // Type of the left-hand side dense vector
3827  , typename VT2 > // Type of the right-hand side sparse vector
3828 class DenseSubvector< DVecSVecCrossExpr<VT1,VT2>, unaligned, false >
3829  : public DenseVector< DenseSubvector< DVecSVecCrossExpr<VT1,VT2>, unaligned, false >, false >
3830  , private Subvector
3831 {
3832  private:
3833  //**Type definitions****************************************************************************
3834  typedef DVecSVecCrossExpr<VT1,VT2> CPE;
3835  typedef typename CPE::ResultType RT;
3836  //**********************************************************************************************
3837 
3838  public:
3839  //**Type definitions****************************************************************************
3840  typedef DenseSubvector<CPE,unaligned,false> This;
3841  typedef typename SubvectorTrait<RT>::Type ResultType;
3842  typedef typename ResultType::TransposeType TransposeType;
3843  typedef typename CPE::ElementType ElementType;
3844  typedef typename CPE::ReturnType ReturnType;
3845  typedef const ResultType CompositeType;
3846  //**********************************************************************************************
3847 
3848  //**Compilation flags***************************************************************************
3850  enum { vectorizable = 0 };
3851 
3853  enum { smpAssignable = 0 };
3854  //**********************************************************************************************
3855 
3856  //**Constructor*********************************************************************************
3863  explicit inline DenseSubvector( const CPE& vector, size_t index, size_t n )
3864  : vector_( vector ) // The dense vector/sparse vector cross product expression
3865  , offset_( index ) // The offset of the subvector within the cross product expression
3866  , size_ ( n ) // The size of the subvector
3867  {}
3868  //**********************************************************************************************
3869 
3870  //**Subscript operator**************************************************************************
3876  inline ReturnType operator[]( size_t index ) const {
3877  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
3878  return vector_[offset_+index];
3879  }
3880  //**********************************************************************************************
3881 
3882  //**Size function*******************************************************************************
3887  inline size_t size() const {
3888  return size_;
3889  }
3890  //**********************************************************************************************
3891 
3892  //**********************************************************************************************
3898  template< typename T >
3899  inline bool canAlias( const T* alias ) const {
3900  return vector_.canAlias( alias );
3901  }
3902  //**********************************************************************************************
3903 
3904  //**********************************************************************************************
3910  template< typename T >
3911  inline bool isAliased( const T* alias ) const {
3912  return vector_.isAliased( alias );
3913  }
3914  //**********************************************************************************************
3915 
3916  private:
3917  //**Member variables****************************************************************************
3920  CPE vector_;
3921  const size_t offset_;
3922  const size_t size_;
3923 
3924  //**********************************************************************************************
3925 
3926  //**Friend declarations*************************************************************************
3927  template< bool AF1, typename VT, bool AF2, bool TF >
3928  friend const DenseSubvector<VT,AF1,TF>
3929  subvector( const DenseSubvector<VT,AF2,TF>& dv, size_t index, size_t size );
3930  //**********************************************************************************************
3931 };
3933 //*************************************************************************************************
3934 
3935 
3936 
3937 
3938 
3939 
3940 
3941 
3942 //=================================================================================================
3943 //
3944 // CLASS TEMPLATE SPECIALIZATION FOR SVECDVECCROSSEXPR
3945 //
3946 //=================================================================================================
3947 
3948 //*************************************************************************************************
3956 template< typename VT1 // Type of the left-hand side sparse vector
3957  , typename VT2 > // Type of the right-hand side dense vector
3958 class DenseSubvector< SVecDVecCrossExpr<VT1,VT2>, unaligned, false >
3959  : public DenseVector< DenseSubvector< SVecDVecCrossExpr<VT1,VT2>, unaligned, false >, false >
3960  , private Subvector
3961 {
3962  private:
3963  //**Type definitions****************************************************************************
3964  typedef SVecDVecCrossExpr<VT1,VT2> CPE;
3965  typedef typename CPE::ResultType RT;
3966  //**********************************************************************************************
3967 
3968  public:
3969  //**Type definitions****************************************************************************
3970  typedef DenseSubvector<CPE,unaligned,false> This;
3971  typedef typename SubvectorTrait<RT>::Type ResultType;
3972  typedef typename ResultType::TransposeType TransposeType;
3973  typedef typename CPE::ElementType ElementType;
3974  typedef typename CPE::ReturnType ReturnType;
3975  typedef const ResultType CompositeType;
3976  //**********************************************************************************************
3977 
3978  //**Compilation flags***************************************************************************
3980  enum { vectorizable = 0 };
3981 
3983  enum { smpAssignable = 0 };
3984  //**********************************************************************************************
3985 
3986  //**Constructor*********************************************************************************
3993  explicit inline DenseSubvector( const CPE& vector, size_t index, size_t n )
3994  : vector_( vector ) // The sparse vector/dense vector cross product expression
3995  , offset_( index ) // The offset of the subvector within the cross product expression
3996  , size_ ( n ) // The size of the subvector
3997  {}
3998  //**********************************************************************************************
3999 
4000  //**Subscript operator**************************************************************************
4006  inline ReturnType operator[]( size_t index ) const {
4007  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
4008  return vector_[offset_+index];
4009  }
4010  //**********************************************************************************************
4011 
4012  //**Size function*******************************************************************************
4017  inline size_t size() const {
4018  return size_;
4019  }
4020  //**********************************************************************************************
4021 
4022  //**********************************************************************************************
4028  template< typename T >
4029  inline bool canAlias( const T* alias ) const {
4030  return vector_.canAlias( alias );
4031  }
4032  //**********************************************************************************************
4033 
4034  //**********************************************************************************************
4040  template< typename T >
4041  inline bool isAliased( const T* alias ) const {
4042  return vector_.isAliased( alias );
4043  }
4044  //**********************************************************************************************
4045 
4046  private:
4047  //**Member variables****************************************************************************
4050  CPE vector_;
4051  const size_t offset_;
4052  const size_t size_;
4053 
4054  //**********************************************************************************************
4055 
4056  //**Friend declarations*************************************************************************
4057  template< bool AF1, typename VT, bool AF2, bool TF >
4058  friend const DenseSubvector<VT,AF1,TF>
4059  subvector( const DenseSubvector<VT,AF2,TF>& dv, size_t index, size_t size );
4060  //**********************************************************************************************
4061 };
4063 //*************************************************************************************************
4064 
4065 
4066 
4067 
4068 
4069 
4070 
4071 
4072 //=================================================================================================
4073 //
4074 // CLASS TEMPLATE SPECIALIZATION FOR SVECSVECCROSSEXPR
4075 //
4076 //=================================================================================================
4077 
4078 //*************************************************************************************************
4086 template< typename VT1 // Type of the left-hand side sparse vector
4087  , typename VT2 > // Type of the right-hand side sparse vector
4088 class DenseSubvector< SVecSVecCrossExpr<VT1,VT2>, unaligned, false >
4089  : public DenseVector< DenseSubvector< SVecSVecCrossExpr<VT1,VT2>, unaligned, false >, false >
4090  , private Subvector
4091 {
4092  private:
4093  //**Type definitions****************************************************************************
4094  typedef SVecSVecCrossExpr<VT1,VT2> CPE;
4095  typedef typename CPE::ResultType RT;
4096  //**********************************************************************************************
4097 
4098  public:
4099  //**Type definitions****************************************************************************
4100  typedef DenseSubvector<CPE,unaligned,false> This;
4101  typedef typename SubvectorTrait<RT>::Type ResultType;
4102  typedef typename ResultType::TransposeType TransposeType;
4103  typedef typename CPE::ElementType ElementType;
4104  typedef typename CPE::ReturnType ReturnType;
4105  typedef const ResultType CompositeType;
4106  //**********************************************************************************************
4107 
4108  //**Compilation flags***************************************************************************
4110  enum { vectorizable = 0 };
4111 
4113  enum { smpAssignable = 0 };
4114  //**********************************************************************************************
4115 
4116  //**Constructor*********************************************************************************
4123  explicit inline DenseSubvector( const CPE& vector, size_t index, size_t n )
4124  : vector_( vector ) // The sparse vector/sparse vector cross product expression
4125  , offset_( index ) // The offset of the subvector within the cross product expression
4126  , size_ ( n ) // The size of the subvector
4127  {}
4128  //**********************************************************************************************
4129 
4130  //**Subscript operator**************************************************************************
4136  inline ReturnType operator[]( size_t index ) const {
4137  BLAZE_INTERNAL_ASSERT( index < size_, "Invalid vector access index" );
4138  return vector_[offset_+index];
4139  }
4140  //**********************************************************************************************
4141 
4142  //**Size function*******************************************************************************
4147  inline size_t size() const {
4148  return size_;
4149  }
4150  //**********************************************************************************************
4151 
4152  //**********************************************************************************************
4158  template< typename T >
4159  inline bool canAlias( const T* alias ) const {
4160  return vector_.canAlias( alias );
4161  }
4162  //**********************************************************************************************
4163 
4164  //**********************************************************************************************
4170  template< typename T >
4171  inline bool isAliased( const T* alias ) const {
4172  return vector_.isAliased( alias );
4173  }
4174  //**********************************************************************************************
4175 
4176  private:
4177  //**Member variables****************************************************************************
4180  CPE vector_;
4181  const size_t offset_;
4182  const size_t size_;
4183 
4184  //**********************************************************************************************
4185 
4186  //**Friend declarations*************************************************************************
4187  template< bool AF1, typename VT, bool AF2, bool TF >
4188  friend const DenseSubvector<VT,AF1,TF>
4189  subvector( const DenseSubvector<VT,AF2,TF>& dv, size_t index, size_t size );
4190  //**********************************************************************************************
4191 };
4193 //*************************************************************************************************
4194 
4195 
4196 
4197 
4198 
4199 
4200 
4201 
4202 //=================================================================================================
4203 //
4204 // DENSESUBVECTOR OPERATORS
4205 //
4206 //=================================================================================================
4207 
4208 //*************************************************************************************************
4211 template< typename VT, bool AF, bool TF >
4212 inline void reset( DenseSubvector<VT,AF,TF>& dv );
4213 
4214 template< typename VT, bool AF, bool TF >
4215 inline void clear( DenseSubvector<VT,AF,TF>& dv );
4216 
4217 template< typename VT, bool AF, bool TF >
4218 inline bool isDefault( const DenseSubvector<VT,AF,TF>& dv );
4220 //*************************************************************************************************
4221 
4222 
4223 //*************************************************************************************************
4230 template< typename VT // Type of the dense vector
4231  , bool AF // Alignment flag
4232  , bool TF > // Transpose flag
4234 {
4235  dv.reset();
4236 }
4237 //*************************************************************************************************
4238 
4239 
4240 //*************************************************************************************************
4247 template< typename VT // Type of the dense vector
4248  , bool AF // Alignment flag
4249  , bool TF > // Transpose flag
4251 {
4252  dv.reset();
4253 }
4254 //*************************************************************************************************
4255 
4256 
4257 //*************************************************************************************************
4276 template< typename VT // Type of the dense vector
4277  , bool AF // Alignment flag
4278  , bool TF > // Transpose flag
4279 inline bool isDefault( const DenseSubvector<VT,AF,TF>& dv )
4280 {
4281  for( size_t i=0UL; i<dv.size(); ++i )
4282  if( !isDefault( dv[i] ) ) return false;
4283  return true;
4284 }
4285 //*************************************************************************************************
4286 
4287 
4288 
4289 
4290 //=================================================================================================
4291 //
4292 // GLOBAL RESTRUCTURING OPERATORS
4293 //
4294 //=================================================================================================
4295 
4296 //*************************************************************************************************
4309 template< bool AF1 // Required alignment flag
4310  , typename VT // Type of the dense vector
4311  , bool AF2 // Present alignment flag
4312  , bool TF > // Transpose flag
4313 inline const DenseSubvector<VT,AF1,TF>
4314  subvector( const DenseSubvector<VT,AF2,TF>& dv, size_t index, size_t size )
4315 {
4317 
4318  if( index + size > dv.size() )
4319  throw std::invalid_argument( "Invalid subvector specification" );
4320 
4321  return DenseSubvector<VT,AF1,TF>( dv.vector_, dv.offset_ + index, size );
4322 }
4324 //*************************************************************************************************
4325 
4326 
4327 
4328 
4329 //=================================================================================================
4330 //
4331 // SUBVECTORTRAIT SPECIALIZATIONS
4332 //
4333 //=================================================================================================
4334 
4335 //*************************************************************************************************
4337 template< typename VT, bool AF, bool TF >
4338 struct SubvectorTrait< DenseSubvector<VT,AF,TF> >
4339 {
4341 };
4343 //*************************************************************************************************
4344 
4345 
4346 
4347 
4348 //=================================================================================================
4349 //
4350 // SUBVECTOREXPRTRAIT SPECIALIZATIONS
4351 //
4352 //=================================================================================================
4353 
4354 //*************************************************************************************************
4356 template< typename VT, bool AF1, bool TF, bool AF2 >
4357 struct SubvectorExprTrait< DenseSubvector<VT,AF1,TF>, AF2 >
4358 {
4359  typedef DenseSubvector<VT,AF2,TF> Type;
4360 };
4362 //*************************************************************************************************
4363 
4364 
4365 //*************************************************************************************************
4367 template< typename VT, bool AF1, bool TF, bool AF2 >
4368 struct SubvectorExprTrait< const DenseSubvector<VT,AF1,TF>, AF2 >
4369 {
4370  typedef DenseSubvector<VT,AF2,TF> Type;
4371 };
4373 //*************************************************************************************************
4374 
4375 
4376 //*************************************************************************************************
4378 template< typename VT, bool AF1, bool TF, bool AF2 >
4379 struct SubvectorExprTrait< volatile DenseSubvector<VT,AF1,TF>, AF2 >
4380 {
4381  typedef DenseSubvector<VT,AF2,TF> Type;
4382 };
4384 //*************************************************************************************************
4385 
4386 
4387 //*************************************************************************************************
4389 template< typename VT, bool AF1, bool TF, bool AF2 >
4390 struct SubvectorExprTrait< const volatile DenseSubvector<VT,AF1,TF>, AF2 >
4391 {
4392  typedef DenseSubvector<VT,AF2,TF> Type;
4393 };
4395 //*************************************************************************************************
4396 
4397 
4398 //*************************************************************************************************
4400 template< typename VT1, typename VT2, bool AF >
4401 struct SubvectorExprTrait< DVecDVecCrossExpr<VT1,VT2>, AF >
4402 {
4403  public:
4404  //**********************************************************************************************
4405  typedef DenseSubvector< DVecDVecCrossExpr<VT1,VT2>, unaligned, false > Type;
4406  //**********************************************************************************************
4407 };
4409 //*************************************************************************************************
4410 
4411 
4412 //*************************************************************************************************
4414 template< typename VT1, typename VT2, bool AF >
4415 struct SubvectorExprTrait< DVecSVecCrossExpr<VT1,VT2>, AF >
4416 {
4417  public:
4418  //**********************************************************************************************
4419  typedef DenseSubvector< DVecSVecCrossExpr<VT1,VT2>, unaligned, false > Type;
4420  //**********************************************************************************************
4421 };
4423 //*************************************************************************************************
4424 
4425 
4426 //*************************************************************************************************
4428 template< typename VT1, typename VT2, bool AF >
4429 struct SubvectorExprTrait< SVecDVecCrossExpr<VT1,VT2>, AF >
4430 {
4431  public:
4432  //**********************************************************************************************
4433  typedef DenseSubvector< SVecDVecCrossExpr<VT1,VT2>, unaligned, false > Type;
4434  //**********************************************************************************************
4435 };
4437 //*************************************************************************************************
4438 
4439 
4440 //*************************************************************************************************
4442 template< typename VT1, typename VT2, bool AF >
4443 struct SubvectorExprTrait< SVecSVecCrossExpr<VT1,VT2>, AF >
4444 {
4445  public:
4446  //**********************************************************************************************
4447  typedef DenseSubvector< SVecSVecCrossExpr<VT1,VT2>, unaligned, false > Type;
4448  //**********************************************************************************************
4449 };
4451 //*************************************************************************************************
4452 
4453 } // namespace blaze
4454 
4455 #endif
const ElementType * ConstPointer
Pointer to a constant subvector value.
Definition: DenseSubvector.h:417
Constraint on the data type.
const size_t final_
The final index for unaligned intrinsic operations.
Definition: DenseSubvector.h:899
Constraint on the data type.
const size_t OPENMP_DVECASSIGN_THRESHOLD
OpenMP dense vector assignment threshold.This threshold specifies when an assignment of a plain dense...
Definition: Thresholds.h:200
bool canAlias(const Other *alias) const
Returns whether the dense subvector can alias with the given address alias.
Definition: DenseSubvector.h:1540
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4579
#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
EnableIf< IsIntegral< T >, Load< T, sizeof(T)> >::Type::Type load(const T *address)
Loads a vector of integral values.
Definition: Load.h:222
Header file for the subvector/submatrix alignment flag values.
const size_t rest_
The number of remaining elements in an unaligned intrinsic operation.
Definition: DenseSubvector.h:898
void smpSubAssign(DenseMatrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:151
IT::Type IntrinsicType
Intrinsic type of the subvector elements.
Definition: DenseSubvector.h:406
bool isDefault(const DynamicMatrix< Type, SO > &m)
Returns whether the given dense matrix is in default state.
Definition: DynamicMatrix.h:4622
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:197
#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:118
void smpMultAssign(DenseVector< 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:178
ReferenceType reference
Reference return type.
Definition: DenseSubvector.h:450
EnableIf< IsIntegral< T >, Loadu< T, sizeof(T)> >::Type::Type loadu(const T *address)
Loads a vector of integral values.
Definition: Loadu.h:219
Header file for the IsSame and IsStrictlySame type traits.
size_t nonZeros() const
Returns the number of non-zero elements in the subvector.
Definition: DenseSubvector.h:1464
const bool useStreaming
Configuration of the streaming behavior.For large vectors and matrices non-temporal stores can provid...
Definition: Streaming.h:50
bool isAligned_
Memory alignment flag.
Definition: DenseSubvector.h:705
Header file for the IsRowVector type trait.
const DenseSubvector & CompositeType
Data type for composite expression templates.
Definition: DenseSubvector.h:408
void storeu(float *address, const sse_float_t &value)
Unaligned store of a vector of &#39;float&#39; values.
Definition: Storeu.h:234
Header file for the DenseVector base class.
SelectType< useConst, ConstReference, typename VT::Reference >::Type Reference
Reference to a non-constant subvector value.
Definition: DenseSubvector.h:414
Header file for the Computation base class.
IntrinsicType loadu() const
Unaligned load of an intrinsic element of the dense subvector.
Definition: DenseSubvector.h:571
#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:118
bool operator==(const SubvectorIterator &rhs) const
Equality comparison between two SubvectorIterator objects.
Definition: DenseSubvector.h:593
DenseSubvector(Operand vector, size_t index, size_t n)
The constructor for DenseSubvector.
Definition: DenseSubvector.h:961
IntrinsicTrait< typename VT::ElementType > IT
Intrinsic trait for the vector element type.
Definition: DenseSubvector.h:386
void clear(DynamicMatrix< Type, SO > &m)
Clearing the given dense matrix.
Definition: DynamicMatrix.h:4595
const size_t offset_
The offset of the subvector within the dense vector.
Definition: DenseSubvector.h:896
size_t capacity() const
Returns the maximum capacity of the dense subvector.
Definition: DenseSubvector.h:1446
SubvectorIterator(IteratorType iterator, IteratorType final, size_t rest, bool isAligned)
Constructor for the SubvectorIterator class.
Definition: DenseSubvector.h:462
Iterator begin()
Returns an iterator to the first element of the subvector.
Definition: DenseSubvector.h:1064
DenseSubvector & operator=(const ElementType &rhs)
Homogenous assignment to all subvector elements.
Definition: DenseSubvector.h:1179
const bool aligned
Alignment flag for aligned subvectors and submatrices.
Definition: AlignmentFlag.h:83
Base template for the SubvectorTrait class.
Definition: SubvectorTrait.h:122
void stream(size_t index, const IntrinsicType &value)
Aligned, non-temporal store of an intrinsic element of the subvector.
Definition: DenseSubvector.h:1744
Constraint on the data type.
void reset()
Reset to the default initial values.
Definition: DenseSubvector.h:1487
Pointer data()
Low-level data access to the subvector elements.
Definition: DenseSubvector.h:1030
DifferenceType difference_type
Difference between two iterators.
Definition: DenseSubvector.h:451
void smpAddAssign(DenseMatrix< 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:121
SubvectorTrait< VT >::Type ResultType
Result type for expression template evaluations.
Definition: DenseSubvector.h:403
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
Header file for the DisableIf class template.
void store(size_t index, const IntrinsicType &value)
Aligned store of an intrinsic element of the subvector.
Definition: DenseSubvector.h:1685
Operand vector_
The dense vector containing the subvector.
Definition: DenseSubvector.h:895
const SubvectorIterator operator--(int)
Post-decrement operator.
Definition: DenseSubvector.h:531
Header file for the dense vector SMP implementation.
Header file for nested template disabiguation.
Header file for the Subvector base class.
Reference operator[](size_t index)
Subscript operator for the direct access to the subvector elements.
Definition: DenseSubvector.h:994
SubvectorIterator & operator++()
Pre-increment operator.
Definition: DenseSubvector.h:499
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2388
Header file for the Or class template.
friend const SubvectorIterator operator-(const SubvectorIterator &it, size_t dec)
Subtraction between a SubvectorIterator and an integral value.
Definition: DenseSubvector.h:695
std::iterator_traits< IteratorType >::difference_type DifferenceType
Difference between two iterators.
Definition: DenseSubvector.h:444
ConstIterator cbegin() const
Returns an iterator to the first element of the subvector.
Definition: DenseSubvector.h:1100
DifferenceType operator-(const SubvectorIterator &rhs) const
Calculating the number of elements between two iterators.
Definition: DenseSubvector.h:659
VT::ReturnType ReturnType
Return type for expression template evaluations.
Definition: DenseSubvector.h:407
Header file for the subvector trait.
DenseSubvector< VT, AF, TF > This
Type of this DenseSubvector instance.
Definition: DenseSubvector.h:402
void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:179
friend const SubvectorIterator operator+(size_t inc, const SubvectorIterator &it)
Addition between an integral value and a SubvectorIterator.
Definition: DenseSubvector.h:683
bool operator!=(const SubvectorIterator &rhs) const
Inequality comparison between two SubvectorIterator objects.
Definition: DenseSubvector.h:604
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:70
Compile time check for sparse vector types.This type trait tests whether or not the given template pa...
Definition: IsSparseVector.h:103
SubvectorIterator & operator--()
Pre-decrement operator.
Definition: DenseSubvector.h:520
IteratorType iterator_
Iterator to the current subvector element.
Definition: DenseSubvector.h:702
Constraint on the data type.
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:79
Constraint on the data type.
size_t size() const
Returns the current size/dimension of the dense subvector.
Definition: DenseSubvector.h:1431
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2382
void multAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the multiplication assignment of a matrix to a matrix.
Definition: Matrix.h:269
Constraint on the data type.
Header file for the SelectType class template.
Header file for all forward declarations for expression class templates.
Constraint on the data type.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2386
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: DenseSubvector.h:404
SelectType< useConst, ConstPointer, ElementType * >::Type Pointer
Pointer to a constant subvector value.
Definition: DenseSubvector.h:420
System settings for streaming (non-temporal stores)
Header file for the EnableIf class template.
const bool unaligned
Alignment flag for unaligned subvectors and submatrices.
Definition: AlignmentFlag.h:63
std::iterator_traits< IteratorType >::iterator_category IteratorCategory
The iterator category.
Definition: DenseSubvector.h:432
Header file for the CrossExpr base class.
void smpAssign(DenseMatrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:91
Header file for the IsNumeric type trait.
size_t rest_
The number of remaining elements beyond the final iterator.
Definition: DenseSubvector.h:704
SelectType< useConst, ConstIterator, SubvectorIterator< typename VT::Iterator > >::Type Iterator
Iterator over non-constant elements.
Definition: DenseSubvector.h:715
Header file for the IsSparseVector type trait.
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2383
Header file for the IsConst type trait.
Iterator end()
Returns an iterator just past the last element of the subvector.
Definition: DenseSubvector.h:1118
Intrinsic characteristics of data types.The IntrinsicTrait class template provides the intrinsic char...
Definition: IntrinsicTrait.h:748
Header file for run time assertion macros.
Base class for all subvectors.The Subvector class serves as a tag for all subvectors (i...
Definition: Subvector.h:64
void addAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a matrix to a matrix.
Definition: Matrix.h:209
View on a specific subvector of a dense vector.The DenseSubvector template represents a view on a spe...
Definition: DenseSubvector.h:377
SubvectorIterator & operator+=(size_t inc)
Addition assignment operator.
Definition: DenseSubvector.h:476
bool operator>(const SubvectorIterator &rhs) const
Greater-than comparison between two SubvectorIterator objects.
Definition: DenseSubvector.h:626
bool isAligned() const
Returns whether the subvector is properly aligned in memory.
Definition: DenseSubvector.h:1580
std::iterator_traits< IteratorType >::pointer PointerType
Pointer return type.
Definition: DenseSubvector.h:438
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
SubvectorExprTrait< VT, unaligned >::Type 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:133
Header file for the reset shim.
ValueType value_type
Type of the underlying elements.
Definition: DenseSubvector.h:448
Header file for the cache size of the target architecture.
void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:239
bool canSMPAssign() const
Returns whether the subvector can be used in SMP assignments.
Definition: DenseSubvector.h:1600
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2387
Header file for the isDefault shim.
ReferenceType operator*() const
Direct access to the element at the current iterator position.
Definition: DenseSubvector.h:541
const size_t size_
The size of the subvector.
Definition: DenseSubvector.h:897
#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:118
IntrinsicType load() const
Aligned load of an intrinsic element of the dense subvector.
Definition: DenseSubvector.h:556
const SubvectorIterator operator++(int)
Post-increment operator.
Definition: DenseSubvector.h:510
IteratorCategory iterator_category
The iterator category.
Definition: DenseSubvector.h:447
Substitution Failure Is Not An Error (SFINAE) class.The DisableIf class template is an auxiliary tool...
Definition: DisableIf.h:184
Compile time check for constant data types.The IsConst type trait tests whether or not the given temp...
Definition: IsConst.h:94
VT::ConstReference ConstReference
Reference to a constant subvector value.
Definition: DenseSubvector.h:411
SubvectorIterator< typename VT::ConstIterator > ConstIterator
Iterator over constant elements.
Definition: DenseSubvector.h:712
Header file for all intrinsic functionality.
IntrinsicType loadu(size_t index) const
Unaligned load of an intrinsic element of the dense subvector.
Definition: DenseSubvector.h:1648
friend const SubvectorIterator operator+(const SubvectorIterator &it, size_t inc)
Addition between a SubvectorIterator and an integral value.
Definition: DenseSubvector.h:671
bool isAliased(const Other *alias) const
Returns whether the dense subvector is aliased with the given address alias.
Definition: DenseSubvector.h:1561
#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:79
#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:118
PointerType pointer
Pointer return type.
Definition: DenseSubvector.h:449
const bool isAligned_
Memory alignment flag.
Definition: DenseSubvector.h:904
IteratorType final_
The final iterator for intrinsic operations.
Definition: DenseSubvector.h:703
Base class for N-dimensional vectors.The Vector class is a base class for all arbitrarily sized (N-di...
Definition: Forward.h:147
IntrinsicType load(size_t index) const
Aligned load of an intrinsic element of the dense subvector.
Definition: DenseSubvector.h:1624
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:248
Header file for the sparse vector SMP implementation.
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:105
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
bool operator>=(const SubvectorIterator &rhs) const
Greater-than comparison between two SubvectorIterator objects.
Definition: DenseSubvector.h:648
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2379
ConstIterator cend() const
Returns an iterator just past the last element of the subvector.
Definition: DenseSubvector.h:1154
Header file for basic type definitions.
Header file for the SubvectorExprTrait class template.
SubvectorIterator & operator-=(size_t dec)
Subtraction assignment operator.
Definition: DenseSubvector.h:488
Iterator over the elements of the sparse subvector.
Definition: DenseSubvector.h:427
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2385
std::iterator_traits< IteratorType >::value_type ValueType
Type of the underlying elements.
Definition: DenseSubvector.h:435
VT::ElementType ElementType
Type of the subvector elements.
Definition: DenseSubvector.h:405
void storeu(size_t index, const IntrinsicType &value)
Unaligned store of an intrinsic element of the subvector.
Definition: DenseSubvector.h:1709
SelectType< IsExpression< VT >::value, VT, VT & >::Type Operand
Composite data type of the dense vector expression.
Definition: DenseSubvector.h:383
const size_t cacheSize
Cache size of the target architecture.This setting specifies the available cache size in Byte of the ...
Definition: CacheSize.h:48
bool operator<(const SubvectorIterator &rhs) const
Less-than comparison between two SubvectorIterator objects.
Definition: DenseSubvector.h:615
bool operator<=(const SubvectorIterator &rhs) const
Less-than comparison between two SubvectorIterator objects.
Definition: DenseSubvector.h:637
#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:238
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
void store(float *address, const sse_float_t &value)
Aligned store of a vector of &#39;float&#39; values.
Definition: Store.h:242
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.
std::iterator_traits< IteratorType >::reference ReferenceType
Reference return type.
Definition: DenseSubvector.h:441