All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CompressedVector.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_SPARSE_COMPRESSEDVECTOR_H_
23 #define _BLAZE_MATH_SPARSE_COMPRESSEDVECTOR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <algorithm>
31 #include <functional>
32 #include <stdexcept>
36 #include <blaze/math/Forward.h>
37 #include <blaze/math/Functions.h>
39 #include <blaze/math/shims/IsNaN.h>
50 #include <blaze/system/Precision.h>
52 #include <blaze/util/Assert.h>
59 #include <blaze/util/EnableIf.h>
60 #include <blaze/util/mpl/If.h>
61 #include <blaze/util/Null.h>
62 #include <blaze/util/Types.h>
65 
66 
67 namespace blaze {
68 
69 //=================================================================================================
70 //
71 // CLASS DEFINITION
72 //
73 //=================================================================================================
74 
75 //*************************************************************************************************
164 template< typename Type // Data type of the vector
165  , bool TF = defaultTransposeFlag > // Transpose flag
166 class CompressedVector : public SparseVector< CompressedVector<Type,TF>, TF >
167 {
168  private:
169  //**Type definitions****************************************************************************
171  //**********************************************************************************************
172 
173  //**Private class Element***********************************************************************
177  struct Element : public ElementBase
178  {
179  using ElementBase::operator=;
180  friend class CompressedVector;
181  };
183  //**********************************************************************************************
184 
185  //**Private class FindIndex*********************************************************************
189  struct FindIndex : public std::binary_function<Element,size_t,bool>
190  {
191  inline bool operator()( const Element& element, size_t index ) const {
192  return element.index() < index;
193  }
194  inline bool operator()( size_t index, const Element& element ) const {
195  return index < element.index();
196  }
197  inline bool operator()( const Element& element1, const Element& element2 ) const {
198  return element1.index() < element2.index();
199  }
200  };
202  //**********************************************************************************************
203 
204  public:
205  //**Type definitions****************************************************************************
207  typedef This ResultType;
209  typedef Type ElementType;
210  typedef const Type& ReturnType;
213  typedef const Type& ConstReference;
214  typedef Element* Iterator;
215  typedef const Element* ConstIterator;
216  //**********************************************************************************************
217 
218  //**Constructors********************************************************************************
221  explicit inline CompressedVector();
222  explicit inline CompressedVector( size_t size );
223  explicit inline CompressedVector( size_t size, size_t nonzeros );
224  inline CompressedVector( const CompressedVector& sv );
225  template< typename VT > inline CompressedVector( const DenseVector<VT,TF>& dv );
226  template< typename VT > inline CompressedVector( const SparseVector<VT,TF>& sv );
228  //**********************************************************************************************
229 
230  //**Destructor**********************************************************************************
233  inline ~CompressedVector();
235  //**********************************************************************************************
236 
237  //**Data access functions***********************************************************************
240  inline Reference operator[]( size_t index );
241  inline ConstReference operator[]( size_t index ) const;
242  inline Iterator begin ();
243  inline ConstIterator begin () const;
244  inline ConstIterator cbegin() const;
245  inline Iterator end ();
246  inline ConstIterator end () const;
247  inline ConstIterator cend () const;
249  //**********************************************************************************************
250 
251  //**Assignment operators************************************************************************
254  inline CompressedVector& operator= ( const CompressedVector& rhs );
255  template< typename VT > inline CompressedVector& operator= ( const DenseVector<VT,TF>& rhs );
256  template< typename VT > inline CompressedVector& operator= ( const SparseVector<VT,TF>& rhs );
257  template< typename VT > inline CompressedVector& operator+=( const Vector<VT,TF>& rhs );
258  template< typename VT > inline CompressedVector& operator-=( const Vector<VT,TF>& rhs );
259  template< typename VT > inline CompressedVector& operator*=( const Vector<VT,TF>& rhs );
260 
261  template< typename Other >
262  inline typename EnableIf< IsNumeric<Other>, CompressedVector >::Type&
263  operator*=( Other rhs );
264 
265  template< typename Other >
266  inline typename EnableIf< IsNumeric<Other>, CompressedVector >::Type&
267  operator/=( Other rhs );
269  //**********************************************************************************************
270 
271  //**Utility functions***************************************************************************
274  inline size_t size() const;
275  inline size_t capacity() const;
276  inline size_t nonZeros() const;
277  inline void reset();
278  inline void clear();
279  Iterator insert( size_t index, const Type& value );
280  inline void erase ( size_t index );
281  inline Iterator erase ( Iterator pos );
282  inline Iterator find ( size_t index );
283  inline ConstIterator find ( size_t index ) const;
284  inline void resize( size_t n, bool preserve=true );
285  void reserve( size_t n );
286  template< typename Other > inline CompressedVector& scale( Other scalar );
287  inline void swap( CompressedVector& sv ) /* throw() */;
289  //**********************************************************************************************
290 
291  //**Low-level utility functions*****************************************************************
294  inline void append( size_t index, const Type& value, bool check=false );
296  //**********************************************************************************************
297 
298  //**Expression template evaluation functions****************************************************
301  template< typename Other > inline bool canAlias ( const Other* alias ) const;
302  template< typename Other > inline bool isAliased( const Other* alias ) const;
303  template< typename VT > inline void assign ( const DenseVector <VT,TF>& rhs );
304  template< typename VT > inline void assign ( const SparseVector<VT,TF>& rhs );
305  template< typename VT > inline void addAssign( const DenseVector <VT,TF>& rhs );
306  template< typename VT > inline void addAssign( const SparseVector<VT,TF>& rhs );
307  template< typename VT > inline void subAssign( const DenseVector <VT,TF>& rhs );
308  template< typename VT > inline void subAssign( const SparseVector<VT,TF>& rhs );
310  //**********************************************************************************************
311 
312  private:
313  //**Utility functions***************************************************************************
316  inline size_t extendCapacity() const;
318  //**********************************************************************************************
319 
320  //**Member variables****************************************************************************
323  size_t size_;
324  size_t capacity_;
327 
328  static const Type zero_;
329 
330  //**********************************************************************************************
331 
332  //**Compile time checks*************************************************************************
340  //**********************************************************************************************
341 };
342 //*************************************************************************************************
343 
344 
345 
346 
347 //=================================================================================================
348 //
349 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
350 //
351 //=================================================================================================
352 
353 template< typename Type // Data type of the vector
354  , bool TF > // Transpose flag
355 const Type CompressedVector<Type,TF>::zero_ = Type();
356 
357 
358 
359 
360 //=================================================================================================
361 //
362 // CONSTRUCTORS
363 //
364 //=================================================================================================
365 
366 //*************************************************************************************************
369 template< typename Type // Data type of the vector
370  , bool TF > // Transpose flag
372  : size_ ( 0UL ) // The current size/dimension of the compressed vector
373  , capacity_( 0UL ) // The maximum capacity of the compressed vector
374  , begin_ ( NULL ) // Pointer to the first non-zero element of the compressed vector
375  , end_ ( NULL ) // Pointer to the last non-zero element of the compressed vector
376 {}
377 //*************************************************************************************************
378 
379 
380 //*************************************************************************************************
385 template< typename Type // Data type of the vector
386  , bool TF > // Transpose flag
388  : size_ ( n ) // The current size/dimension of the compressed vector
389  , capacity_( 0UL ) // The maximum capacity of the compressed vector
390  , begin_ ( NULL ) // Pointer to the first non-zero element of the compressed vector
391  , end_ ( NULL ) // Pointer to the last non-zero element of the compressed vector
392 {}
393 //*************************************************************************************************
394 
395 
396 //*************************************************************************************************
402 template< typename Type // Data type of the vector
403  , bool TF > // Transpose flag
404 inline CompressedVector<Type,TF>::CompressedVector( size_t n, size_t nonzeros )
405  : size_ ( n ) // The current size/dimension of the compressed vector
406  , capacity_( nonzeros ) // The maximum capacity of the compressed vector
407  , begin_ ( new Element[capacity_] ) // Pointer to the first non-zero element of the compressed vector
408  , end_ ( begin_ ) // Pointer to the last non-zero element of the compressed vector
409 {}
410 //*************************************************************************************************
411 
412 
413 //*************************************************************************************************
421 template< typename Type // Data type of the vector
422  , bool TF > // Transpose flag
424  : size_ ( sv.size_ ) // The current size/dimension of the compressed vector
425  , capacity_( sv.nonZeros() ) // The maximum capacity of the compressed vector
426  , begin_ ( new Element[capacity_] ) // Pointer to the first non-zero element of the compressed vector
427  , end_ ( begin_+capacity_ ) // Pointer to the last non-zero element of the compressed vector
428 {
429  std::copy( sv.begin_, sv.end_, begin_ );
430 }
431 //*************************************************************************************************
432 
433 
434 //*************************************************************************************************
439 template< typename Type // Data type of the vector
440  , bool TF > // Transpose flag
441 template< typename VT > // Type of the foreign dense vector
443  : size_ ( (~dv).size() ) // The current size/dimension of the compressed vector
444  , capacity_( 0UL ) // The maximum capacity of the compressed vector
445  , begin_ ( NULL ) // Pointer to the first non-zero element of the compressed vector
446  , end_ ( NULL ) // Pointer to the last non-zero element of the compressed vector
447 {
448  using blaze::assign;
449  assign( *this, ~dv );
450 }
451 //*************************************************************************************************
452 
453 
454 //*************************************************************************************************
459 template< typename Type // Data type of the vector
460  , bool TF > // Transpose flag
461 template< typename VT > // Type of the foreign sparse vector
463  : size_ ( (~sv).size() ) // The current size/dimension of the compressed vector
464  , capacity_( (~sv).nonZeros() ) // The maximum capacity of the compressed vector
465  , begin_ ( new Element[capacity_] ) // Pointer to the first non-zero element of the compressed vector
466  , end_ ( begin_ ) // Pointer to the last non-zero element of the compressed vector
467 {
468  using blaze::assign;
469  assign( *this, ~sv );
470 }
471 //*************************************************************************************************
472 
473 
474 
475 
476 //=================================================================================================
477 //
478 // DESTRUCTOR
479 //
480 //=================================================================================================
481 
482 //*************************************************************************************************
485 template< typename Type // Data type of the vector
486  , bool TF > // Transpose flag
488 {
489  delete [] begin_;
490 }
491 //*************************************************************************************************
492 
493 
494 
495 
496 //=================================================================================================
497 //
498 // DATA ACCESS FUNCTIONS
499 //
500 //=================================================================================================
501 
502 //*************************************************************************************************
513 template< typename Type // Data type of the vector
514  , bool TF > // Transpose flag
517 {
518  BLAZE_USER_ASSERT( index < size_, "Invalid compressed vector access index" );
519 
520  return Reference( *this, index );
521 }
522 //*************************************************************************************************
523 
524 
525 //*************************************************************************************************
531 template< typename Type // Data type of the vector
532  , bool TF > // Transpose flag
535 {
536  BLAZE_USER_ASSERT( index < size_, "Invalid compressed vector access index" );
537 
538  const Iterator pos( std::lower_bound( begin_, end_, index, FindIndex() ) );
539 
540  if( pos == end_ || pos->index_ != index )
541  return zero_;
542  else
543  return pos->value_;
544 }
545 //*************************************************************************************************
546 
547 
548 //*************************************************************************************************
553 template< typename Type // Data type of the vector
554  , bool TF > // Transpose flag
556 {
557  return Iterator( begin_ );
558 }
559 //*************************************************************************************************
560 
561 
562 //*************************************************************************************************
567 template< typename Type // Data type of the vector
568  , bool TF > // Transpose flag
570 {
571  return ConstIterator( begin_ );
572 }
573 //*************************************************************************************************
574 
575 
576 //*************************************************************************************************
581 template< typename Type // Data type of the vector
582  , bool TF > // Transpose flag
584 {
585  return ConstIterator( begin_ );
586 }
587 //*************************************************************************************************
588 
589 
590 //*************************************************************************************************
595 template< typename Type // Data type of the vector
596  , bool TF > // Transpose flag
598 {
599  return Iterator( end_ );
600 }
601 //*************************************************************************************************
602 
603 
604 //*************************************************************************************************
609 template< typename Type // Data type of the vector
610  , bool TF > // Transpose flag
612 {
613  return ConstIterator( end_ );
614 }
615 //*************************************************************************************************
616 
617 
618 //*************************************************************************************************
623 template< typename Type // Data type of the vector
624  , bool TF > // Transpose flag
626 {
627  return ConstIterator( end_ );
628 }
629 //*************************************************************************************************
630 
631 
632 
633 
634 //=================================================================================================
635 //
636 // ASSIGNMENT OPERATORS
637 //
638 //=================================================================================================
639 
640 //*************************************************************************************************
649 template< typename Type // Data type of the vector
650  , bool TF > // Transpose flag
653 {
654  if( &rhs == this ) return *this;
655 
656  const size_t nonzeros( rhs.nonZeros() );
657 
658  if( nonzeros > capacity_ ) {
659  Iterator newBegin( new Element[nonzeros] );
660  end_ = std::copy( rhs.begin_, rhs.end_, newBegin );
661  std::swap( begin_, newBegin );
662  delete [] newBegin;
663 
664  size_ = rhs.size_;
665  capacity_ = nonzeros;
666  }
667  else {
668  end_ = std::copy( rhs.begin_, rhs.end_, begin_ );
669  size_ = rhs.size_;
670  }
671 
672  return *this;
673 }
674 //*************************************************************************************************
675 
676 
677 //*************************************************************************************************
686 template< typename Type // Data type of the vector
687  , bool TF > // Transpose flag
688 template< typename VT > // Type of the right-hand side dense vector
691 {
692  using blaze::assign;
693 
694  if( (~rhs).canAlias( this ) ) {
695  CompressedVector tmp( rhs );
696  swap( tmp );
697  }
698  else {
699  size_ = (~rhs).size();
700  end_ = begin_;
701  assign( *this, ~rhs );
702  }
703 
704  return *this;
705 }
706 //*************************************************************************************************
707 
708 
709 //*************************************************************************************************
718 template< typename Type // Data type of the vector
719  , bool TF > // Transpose flag
720 template< typename VT > // Type of the right-hand side sparse vector
723 {
724  using blaze::assign;
725 
726  if( (~rhs).canAlias( this ) || (~rhs).nonZeros() > capacity_ ) {
727  CompressedVector tmp( rhs );
728  swap( tmp );
729  }
730  else {
731  size_ = (~rhs).size();
732  end_ = begin_;
733  assign( *this, ~rhs );
734  }
735 
736  return *this;
737 }
738 //*************************************************************************************************
739 
740 
741 //*************************************************************************************************
751 template< typename Type // Data type of the vector
752  , bool TF > // Transpose flag
753 template< typename VT > // Type of the right-hand side vector
755 {
756  using blaze::addAssign;
757 
758  if( (~rhs).size() != size_ )
759  throw std::invalid_argument( "Vector sizes do not match" );
760 
761  addAssign( *this, ~rhs );
762 
763  return *this;
764 }
765 //*************************************************************************************************
766 
767 
768 //*************************************************************************************************
778 template< typename Type // Data type of the vector
779  , bool TF > // Transpose flag
780 template< typename VT > // Type of the right-hand side vector
782 {
783  using blaze::subAssign;
784 
785  if( (~rhs).size() != size_ )
786  throw std::invalid_argument( "Vector sizes do not match" );
787 
788  subAssign( *this, ~rhs );
789 
790  return *this;
791 }
792 //*************************************************************************************************
793 
794 
795 //*************************************************************************************************
806 template< typename Type // Data type of the vector
807  , bool TF > // Transpose flag
808 template< typename VT > // Type of the right-hand side vector
810 {
811  if( (~rhs).size() != size_ )
812  throw std::invalid_argument( "Vector sizes do not match" );
813 
814  CompressedVector<Type,TF> tmp( *this * (~rhs) );
815  swap( tmp );
816 
817  return *this;
818 }
819 //*************************************************************************************************
820 
821 
822 //*************************************************************************************************
833 template< typename Type // Data type of the vector
834  , bool TF > // Transpose flag
835 template< typename Other > // Data type of the right-hand side scalar
838 {
839  for( Iterator element=begin_; element!=end_; ++element )
840  element->value_ *= rhs;
841  return *this;
842 }
843 //*************************************************************************************************
844 
845 
846 //*************************************************************************************************
858 template< typename Type // Data type of the vector
859  , bool TF > // Transpose flag
860 template< typename Other > // Data type of the right-hand side scalar
863 {
864  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
865 
866  typedef typename DivTrait<Type,Other>::Type DT;
867  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
868 
869  // Depending on the two involved data types, an integer division is applied or a
870  // floating point division is selected.
872  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
873  for( Iterator element=begin_; element!=end_; ++element )
874  element->value_ *= tmp;
875  }
876  else {
877  for( Iterator element=begin_; element!=end_; ++element )
878  element->value_ /= rhs;
879  }
880 
881  return *this;
882 }
883 //*************************************************************************************************
884 
885 
886 
887 
888 //=================================================================================================
889 //
890 // UTILITY FUNCTIONS
891 //
892 //=================================================================================================
893 
894 //*************************************************************************************************
899 template< typename Type // Data type of the vector
900  , bool TF > // Transpose flag
901 inline size_t CompressedVector<Type,TF>::size() const
902 {
903  return size_;
904 }
905 //*************************************************************************************************
906 
907 
908 //*************************************************************************************************
913 template< typename Type // Data type of the vector
914  , bool TF > // Transpose flag
916 {
917  return capacity_;
918 }
919 //*************************************************************************************************
920 
921 
922 //*************************************************************************************************
930 template< typename Type // Data type of the vector
931  , bool TF > // Transpose flag
933 {
934  return end_ - begin_;
935 }
936 //*************************************************************************************************
937 
938 
939 //*************************************************************************************************
944 template< typename Type // Data type of the vector
945  , bool TF > // Transpose flag
947 {
948  end_ = begin_;
949 }
950 //*************************************************************************************************
951 
952 
953 //*************************************************************************************************
960 template< typename Type // Data type of the vector
961  , bool TF > // Transpose flag
963 {
964  size_ = 0UL;
965  end_ = begin_;
966 }
967 //*************************************************************************************************
968 
969 
970 //*************************************************************************************************
982 template< typename Type // Data type of the vector
983  , bool TF > // Transpose flag
985  CompressedVector<Type,TF>::insert( size_t index, const Type& value )
986 {
987  BLAZE_USER_ASSERT( index < size_, "Invalid compressed vector access index" );
988 
989  const Iterator pos( std::lower_bound( begin_, end_, index, FindIndex() ) );
990 
991  if( pos != end_ && pos->index_ == index )
992  throw std::invalid_argument( "Bad access index" );
993 
994  if( nonZeros() != capacity_ ) {
995  std::copy_backward( pos, end_, end_+1 );
996  pos->value_ = value;
997  pos->index_ = index;
998  ++end_;
999 
1000  return pos;
1001  }
1002  else {
1003  size_t newCapacity( extendCapacity() );
1004 
1005  Iterator newBegin = new Element[newCapacity];
1006  Iterator tmp = std::copy( begin_, pos, newBegin );
1007  tmp->value_ = value;
1008  tmp->index_ = index;
1009  end_ = std::copy( pos, end_, tmp+1 );
1010 
1011  std::swap( newBegin, begin_ );
1012  delete [] newBegin;
1013  capacity_ = newCapacity;
1014 
1015  return tmp;
1016  }
1017 }
1018 //*************************************************************************************************
1019 
1020 
1021 //*************************************************************************************************
1029 template< typename Type // Data type of the vector
1030  , bool TF > // Transpose flag
1031 inline void CompressedVector<Type,TF>::erase( size_t index )
1032 {
1033  BLAZE_USER_ASSERT( index < size_, "Invalid compressed vector access index" );
1034 
1035  const Iterator pos( find( index ) );
1036  if( pos != end_ )
1037  end_ = std::copy( pos+1, end_, pos );
1038 }
1039 //*************************************************************************************************
1040 
1041 
1042 //*************************************************************************************************
1050 template< typename Type // Data type of the vector
1051  , bool TF > // Transpose flag
1053 {
1054  BLAZE_USER_ASSERT( pos >= begin_ && pos <= end_, "Invalid compressed vector iterator" );
1055 
1056  if( pos != end_ )
1057  end_ = std::copy( pos+1, end_, pos );
1058  return pos;
1059 }
1060 //*************************************************************************************************
1061 
1062 
1063 //*************************************************************************************************
1076 template< typename Type // Data type of the vector
1077  , bool TF > // Transpose flag
1079 {
1080  return const_cast<Iterator>( const_cast<const This&>( *this ).find( index ) );
1081 }
1082 //*************************************************************************************************
1083 
1084 
1085 //*************************************************************************************************
1098 template< typename Type // Data type of the vector
1099  , bool TF > // Transpose flag
1101 {
1102  const Iterator pos( std::lower_bound( begin_, end_, index, FindIndex() ) );
1103  if( pos != end_ && pos->index_ == index )
1104  return pos;
1105  else return end_;
1106 }
1107 //*************************************************************************************************
1108 
1109 
1110 //*************************************************************************************************
1122 template< typename Type // Data type of the vector
1123  , bool TF > // Transpose flag
1124 inline void CompressedVector<Type,TF>::resize( size_t n, bool preserve )
1125 {
1126  if( preserve ) {
1127  end_ = std::lower_bound( begin_, end_, n, FindIndex() );
1128  }
1129  else {
1130  end_ = begin_;
1131  }
1132 
1133  size_ = n;
1134 }
1135 //*************************************************************************************************
1136 
1137 
1138 //*************************************************************************************************
1147 template< typename Type // Data type of the vector
1148  , bool TF > // Transpose flag
1150 {
1151  if( n > capacity_ ) {
1152  const size_t newCapacity( n );
1153 
1154  // Allocating a new data and index array
1155  Iterator newBegin = new Element[newCapacity];
1156 
1157  // Replacing the old data and index array
1158  end_ = std::copy( begin_, end_, newBegin );
1159  std::swap( newBegin, begin_ );
1160  capacity_ = newCapacity;
1161  delete [] newBegin;
1162  }
1163 }
1164 //*************************************************************************************************
1165 
1166 
1167 //*************************************************************************************************
1173 template< typename Type // Data type of the vector
1174  , bool TF > // Transpose flag
1175 template< typename Other > // Data type of the scalar value
1177 {
1178  for( Iterator element=begin_; element!=end_; ++element )
1179  element->value_ *= scalar;
1180  return *this;
1181 }
1182 //*************************************************************************************************
1183 
1184 
1185 //*************************************************************************************************
1192 template< typename Type // Data type of the vector
1193  , bool TF > // Transpose flag
1194 inline void CompressedVector<Type,TF>::swap( CompressedVector& sv ) /* throw() */
1195 {
1196  std::swap( size_, sv.size_ );
1197  std::swap( capacity_, sv.capacity_ );
1198  std::swap( begin_, sv.begin_ );
1199  std::swap( end_, sv.end_ );
1200 }
1201 //*************************************************************************************************
1202 
1203 
1204 //*************************************************************************************************
1212 template< typename Type // Data type of the vector
1213  , bool TF > // Transpose flag
1215 {
1216  using blaze::max;
1217  using blaze::min;
1218 
1219  size_t nonzeros( 2UL*capacity_+1UL );
1220  nonzeros = max( nonzeros, 7UL );
1221  nonzeros = min( nonzeros, size_ );
1222 
1223  BLAZE_INTERNAL_ASSERT( nonzeros > capacity_, "Invalid capacity value" );
1224 
1225  return nonzeros;
1226 }
1227 //*************************************************************************************************
1228 
1229 
1230 
1231 
1232 //=================================================================================================
1233 //
1234 // LOW-LEVEL UTILITY FUNCTIONS
1235 //
1236 //=================================================================================================
1237 
1238 //*************************************************************************************************
1262 template< typename Type // Data type of the vector
1263  , bool TF > // Transpose flag
1264 inline void CompressedVector<Type,TF>::append( size_t index, const Type& value, bool check )
1265 {
1266  BLAZE_USER_ASSERT( index < size_, "Invalid compressed vector access index" );
1267  BLAZE_USER_ASSERT( nonZeros() < capacity(), "Not enough reserved space" );
1268  BLAZE_USER_ASSERT( begin_ == end_ || (end_-1UL)->index_ < index, "Index is not strictly increasing" );
1269 
1270  end_->value_ = value;
1271 
1272  if( !check || !isDefault( end_->value_ ) ) {
1273  end_->index_ = index;
1274  ++end_;
1275  }
1276 }
1277 //*************************************************************************************************
1278 
1279 
1280 
1281 
1282 //=================================================================================================
1283 //
1284 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1285 //
1286 //=================================================================================================
1287 
1288 //*************************************************************************************************
1298 template< typename Type // Data type of the vector
1299  , bool TF > // Transpose flag
1300 template< typename Other > // Data type of the foreign expression
1301 inline bool CompressedVector<Type,TF>::canAlias( const Other* alias ) const
1302 {
1303  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1304 }
1305 //*************************************************************************************************
1306 
1307 
1308 //*************************************************************************************************
1318 template< typename Type // Data type of the vector
1319  , bool TF > // Transpose flag
1320 template< typename Other > // Data type of the foreign expression
1321 inline bool CompressedVector<Type,TF>::isAliased( const Other* alias ) const
1322 {
1323  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1324 }
1325 //*************************************************************************************************
1326 
1327 
1328 //*************************************************************************************************
1339 template< typename Type // Data type of the vector
1340  , bool TF > // Transpose flag
1341 template< typename VT > // Type of the right-hand side dense vector
1343 {
1344  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
1345 
1346  size_t nonzeros( 0UL );
1347 
1348  for( size_t i=0UL; i<size_; ++i )
1349  {
1350  if( nonzeros == capacity_ )
1351  reserve( extendCapacity() );
1352 
1353  end_->value_ = (~rhs)[i];
1354 
1355  if( !isDefault( end_->value_ ) ) {
1356  end_->index_ = i;
1357  ++end_;
1358  ++nonzeros;
1359  }
1360  }
1361 }
1362 //*************************************************************************************************
1363 
1364 
1365 //*************************************************************************************************
1376 template< typename Type // Data type of the vector
1377  , bool TF > // Transpose flag
1378 template< typename VT > // Type of the right-hand side sparse vector
1380 {
1381  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
1382 
1383  // Using the following formulation instead of a std::copy function call of the form
1384  //
1385  // end_ = std::copy( (~rhs).begin(), (~rhs).end(), begin_ );
1386  //
1387  // results in much less requirements on the ConstIterator type provided from the right-hand
1388  // sparse vector type
1389  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1390  append( element->index(), element->value() );
1391 }
1392 //*************************************************************************************************
1393 
1394 
1395 //*************************************************************************************************
1406 template< typename Type // Data type of the vector
1407  , bool TF > // Transpose flag
1408 template< typename VT > // Type of the right-hand side dense vector
1410 {
1411  typedef typename AddTrait<This,typename VT::ResultType>::Type AddType;
1412 
1415  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename AddType::CompositeType );
1416 
1417  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
1418 
1419  const AddType tmp( *this + (~rhs) );
1420  reset();
1421  assign( tmp );
1422 }
1423 //*************************************************************************************************
1424 
1425 
1426 //*************************************************************************************************
1437 template< typename Type // Data type of the vector
1438  , bool TF > // Transpose flag
1439 template< typename VT > // Type of the right-hand side sparse vector
1441 {
1442  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
1443 
1444  CompressedVector<Type,TF> tmp( *this + (~rhs) );
1445  swap( tmp );
1446 }
1447 //*************************************************************************************************
1448 
1449 
1450 //*************************************************************************************************
1461 template< typename Type // Data type of the vector
1462  , bool TF > // Transpose flag
1463 template< typename VT > // Type of the right-hand side dense vector
1465 {
1466  typedef typename SubTrait<This,typename VT::ResultType>::Type SubType;
1467 
1470  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename SubType::CompositeType );
1471 
1472  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
1473 
1474  const SubType tmp( *this - (~rhs) );
1475  reset();
1476  assign( tmp );
1477 }
1478 //*************************************************************************************************
1479 
1480 
1481 //*************************************************************************************************
1492 template< typename Type // Data type of the vector
1493  , bool TF > // Transpose flag
1494 template< typename VT > // Type of the right-hand side sparse vector
1496 {
1497  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
1498 
1499  CompressedVector<Type,TF> tmp( *this - (~rhs) );
1500  swap( tmp );
1501 }
1502 //*************************************************************************************************
1503 
1504 
1505 
1506 
1507 //=================================================================================================
1508 //
1509 // COMPRESSEDVECTOR OPERATORS
1510 //
1511 //=================================================================================================
1512 
1513 //*************************************************************************************************
1516 template< typename Type, bool TF >
1517 inline void reset( CompressedVector<Type,TF>& v );
1518 
1519 template< typename Type, bool TF >
1520 inline void clear( CompressedVector<Type,TF>& v );
1521 
1522 template< typename Type, bool TF >
1523 inline bool isnan( const CompressedVector<Type,TF>& v );
1524 
1525 template< typename Type, bool TF >
1526 inline bool isDefault( const CompressedVector<Type,TF>& v );
1527 
1528 template< typename Type, bool TF >
1529 inline void swap( CompressedVector<Type,TF>& a, CompressedVector<Type,TF>& b ) /* throw() */;
1531 //*************************************************************************************************
1532 
1533 
1534 //*************************************************************************************************
1541 template< typename Type // Data type of the vector
1542  , bool TF > // Transpose flag
1544 {
1545  v.reset();
1546 }
1547 //*************************************************************************************************
1548 
1549 
1550 //*************************************************************************************************
1557 template< typename Type // Data type of the vector
1558  , bool TF > // Transpose flag
1560 {
1561  v.clear();
1562 }
1563 //*************************************************************************************************
1564 
1565 
1566 //*************************************************************************************************
1583 template< typename Type // Data type of the vector
1584  , bool TF > // Transpose flag
1585 inline bool isnan( const CompressedVector<Type,TF>& v )
1586 {
1587  typedef typename CompressedVector<Type,TF>::ConstIterator ConstIterator;
1588 
1589  const ConstIterator end( v.end() );
1590  for( ConstIterator element=v.begin(); element!=end; ++element ) {
1591  if( isnan( element->value() ) ) return true;
1592  }
1593  return false;
1594 }
1595 //*************************************************************************************************
1596 
1597 
1598 //*************************************************************************************************
1617 template< typename Type // Data type of the vector
1618  , bool TF > // Transpose flag
1619 inline bool isDefault( const CompressedVector<Type,TF>& v )
1620 {
1621  typedef typename CompressedVector<Type,TF>::ConstIterator ConstIterator;
1622 
1623  for( ConstIterator element=v.begin(); element!=v.end(); ++element )
1624  if( !isDefault( element->value() ) ) return false;
1625  return true;
1626 }
1627 //*************************************************************************************************
1628 
1629 
1630 //*************************************************************************************************
1639 template< typename Type // Data type of the vector
1640  , bool TF > // Transpose flag
1641 inline void swap( CompressedVector<Type,TF>& a, CompressedVector<Type,TF>& b ) /* throw() */
1642 {
1643  a.swap( b );
1644 }
1645 //*************************************************************************************************
1646 
1647 
1648 
1649 
1650 //=================================================================================================
1651 //
1652 // ISRESIZABLE SPECIALIZATIONS
1653 //
1654 //=================================================================================================
1655 
1656 //*************************************************************************************************
1658 template< typename T, bool TF >
1659 struct IsResizable< CompressedVector<T,TF> > : public TrueType
1660 {
1661  enum { value = 1 };
1662  typedef TrueType Type;
1663 };
1664 
1665 template< typename T, bool TF >
1666 struct IsResizable< const CompressedVector<T,TF> > : public TrueType
1667 {
1668  enum { value = 1 };
1669  typedef TrueType Type;
1670 };
1671 
1672 template< typename T, bool TF >
1673 struct IsResizable< volatile CompressedVector<T,TF> > : public TrueType
1674 {
1675  enum { value = 1 };
1676  typedef TrueType Type;
1677 };
1678 
1679 template< typename T, bool TF >
1680 struct IsResizable< const volatile CompressedVector<T,TF> > : public TrueType
1681 {
1682  enum { value = 1 };
1683  typedef TrueType Type;
1684 };
1686 //*************************************************************************************************
1687 
1688 
1689 
1690 
1691 //=================================================================================================
1692 //
1693 // ADDTRAIT SPECIALIZATIONS
1694 //
1695 //=================================================================================================
1696 
1697 //*************************************************************************************************
1699 template< typename T1, bool TF, typename T2, size_t N >
1700 struct AddTrait< CompressedVector<T1,TF>, StaticVector<T2,N,TF> >
1701 {
1702  typedef StaticVector< typename AddTrait<T1,T2>::Type, N, TF > Type;
1703 };
1704 
1705 template< typename T1, size_t N, bool TF, typename T2 >
1706 struct AddTrait< StaticVector<T1,N,TF>, CompressedVector<T2,TF> >
1707 {
1708  typedef StaticVector< typename AddTrait<T1,T2>::Type, N, TF > Type;
1709 };
1710 
1711 template< typename T1, bool TF, typename T2 >
1712 struct AddTrait< CompressedVector<T1,TF>, DynamicVector<T2,TF> >
1713 {
1714  typedef DynamicVector< typename AddTrait<T1,T2>::Type, TF > Type;
1715 };
1716 
1717 template< typename T1, bool TF, typename T2 >
1718 struct AddTrait< DynamicVector<T1,TF>, CompressedVector<T2,TF> >
1719 {
1720  typedef DynamicVector< typename AddTrait<T1,T2>::Type, TF > Type;
1721 };
1722 
1723 template< typename T1, bool TF, typename T2 >
1724 struct AddTrait< CompressedVector<T1,TF>, CompressedVector<T2,TF> >
1725 {
1726  typedef CompressedVector< typename AddTrait<T1,T2>::Type, TF > Type;
1727 };
1729 //*************************************************************************************************
1730 
1731 
1732 
1733 
1734 //=================================================================================================
1735 //
1736 // SUBTRAIT SPECIALIZATIONS
1737 //
1738 //=================================================================================================
1739 
1740 //*************************************************************************************************
1742 template< typename T1, bool TF, typename T2, size_t N >
1743 struct SubTrait< CompressedVector<T1,TF>, StaticVector<T2,N,TF> >
1744 {
1745  typedef StaticVector< typename SubTrait<T1,T2>::Type, N, TF > Type;
1746 };
1747 
1748 template< typename T1, size_t N, bool TF, typename T2 >
1749 struct SubTrait< StaticVector<T1,N,TF>, CompressedVector<T2,TF> >
1750 {
1751  typedef StaticVector< typename SubTrait<T1,T2>::Type, N, TF > Type;
1752 };
1753 
1754 template< typename T1, bool TF, typename T2 >
1755 struct SubTrait< CompressedVector<T1,TF>, DynamicVector<T2,TF> >
1756 {
1757  typedef DynamicVector< typename SubTrait<T1,T2>::Type, TF > Type;
1758 };
1759 
1760 template< typename T1, bool TF, typename T2 >
1761 struct SubTrait< DynamicVector<T1,TF>, CompressedVector<T2,TF> >
1762 {
1763  typedef DynamicVector< typename SubTrait<T1,T2>::Type, TF > Type;
1764 };
1765 
1766 template< typename T1, bool TF, typename T2 >
1767 struct SubTrait< CompressedVector<T1,TF>, CompressedVector<T2,TF> >
1768 {
1769  typedef CompressedVector< typename SubTrait<T1,T2>::Type, TF > Type;
1770 };
1772 //*************************************************************************************************
1773 
1774 
1775 
1776 
1777 //=================================================================================================
1778 //
1779 // MULTTRAIT SPECIALIZATIONS
1780 //
1781 //=================================================================================================
1782 
1783 //*************************************************************************************************
1785 template< typename T1, bool TF, typename T2 >
1786 struct MultTrait< CompressedVector<T1,TF>, T2 >
1787 {
1788  typedef CompressedVector< typename MultTrait<T1,T2>::Type, TF > Type;
1790 };
1791 
1792 template< typename T1, typename T2, bool TF >
1793 struct MultTrait< T1, CompressedVector<T2,TF> >
1794 {
1795  typedef CompressedVector< typename MultTrait<T1,T2>::Type, TF > Type;
1797 };
1798 
1799 template< typename T1, bool TF, typename T2, size_t N >
1800 struct MultTrait< CompressedVector<T1,TF>, StaticVector<T2,N,TF> >
1801 {
1802  typedef CompressedVector< typename MultTrait<T1,T2>::Type, TF > Type;
1803 };
1804 
1805 template< typename T1, typename T2, size_t N >
1806 struct MultTrait< CompressedVector<T1,false>, StaticVector<T2,N,true> >
1807 {
1808  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, true > Type;
1809 };
1810 
1811 template< typename T1, typename T2, size_t N >
1812 struct MultTrait< CompressedVector<T1,true>, StaticVector<T2,N,false> >
1813 {
1814  typedef typename MultTrait<T1,T2>::Type Type;
1815 };
1816 
1817 template< typename T1, size_t N, bool TF, typename T2 >
1818 struct MultTrait< StaticVector<T1,N,TF>, CompressedVector<T2,TF> >
1819 {
1820  typedef CompressedVector< typename MultTrait<T1,T2>::Type, TF > Type;
1821 };
1822 
1823 template< typename T1, size_t N, typename T2 >
1824 struct MultTrait< StaticVector<T1,N,false>, CompressedVector<T2,true> >
1825 {
1826  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, false > Type;
1827 };
1828 
1829 template< typename T1, size_t N, typename T2 >
1830 struct MultTrait< StaticVector<T1,N,true>, CompressedVector<T2,false> >
1831 {
1832  typedef typename MultTrait<T1,T2>::Type Type;
1833 };
1834 
1835 template< typename T1, bool TF, typename T2 >
1836 struct MultTrait< CompressedVector<T1,TF>, DynamicVector<T2,TF> >
1837 {
1838  typedef CompressedVector< typename MultTrait<T1,T2>::Type, TF > Type;
1839 };
1840 
1841 template< typename T1, typename T2 >
1842 struct MultTrait< CompressedVector<T1,false>, DynamicVector<T2,true> >
1843 {
1844  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, true > Type;
1845 };
1846 
1847 template< typename T1, typename T2 >
1848 struct MultTrait< CompressedVector<T1,true>, DynamicVector<T2,false> >
1849 {
1850  typedef typename MultTrait<T1,T2>::Type Type;
1851 };
1852 
1853 template< typename T1, bool TF, typename T2 >
1854 struct MultTrait< DynamicVector<T1,TF>, CompressedVector<T2,TF> >
1855 {
1856  typedef CompressedVector< typename MultTrait<T1,T2>::Type, TF > Type;
1857 };
1858 
1859 template< typename T1, typename T2 >
1860 struct MultTrait< DynamicVector<T1,false>, CompressedVector<T2,true> >
1861 {
1862  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, false > Type;
1863 };
1864 
1865 template< typename T1, typename T2 >
1866 struct MultTrait< DynamicVector<T1,true>, CompressedVector<T2,false> >
1867 {
1868  typedef typename MultTrait<T1,T2>::Type Type;
1869 };
1870 
1871 template< typename T1, bool TF, typename T2 >
1872 struct MultTrait< CompressedVector<T1,TF>, CompressedVector<T2,TF> >
1873 {
1874  typedef CompressedVector< typename MultTrait<T1,T2>::Type, TF > Type;
1875 };
1876 
1877 template< typename T1, typename T2 >
1878 struct MultTrait< CompressedVector<T1,false>, CompressedVector<T2,true> >
1879 {
1880  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, false > Type;
1881 };
1882 
1883 template< typename T1, typename T2 >
1884 struct MultTrait< CompressedVector<T1,true>, CompressedVector<T2,false> >
1885 {
1886  typedef typename MultTrait<T1,T2>::Type Type;
1887 };
1889 //*************************************************************************************************
1890 
1891 
1892 
1893 
1894 //=================================================================================================
1895 //
1896 // CROSSTRAIT SPECIALIZATIONS
1897 //
1898 //=================================================================================================
1899 
1900 //*************************************************************************************************
1902 template< typename T1, typename T2 >
1903 struct CrossTrait< CompressedVector<T1,false>, StaticVector<T2,3UL,false> >
1904 {
1905  private:
1906  typedef typename MultTrait<T1,T2>::Type T;
1907 
1908  public:
1909  typedef StaticVector< typename SubTrait<T,T>::Type, 3UL, false > Type;
1910 };
1911 
1912 template< typename T1, typename T2 >
1913 struct CrossTrait< StaticVector<T1,3UL,false>, CompressedVector<T2,false> >
1914 {
1915  private:
1916  typedef typename MultTrait<T1,T2>::Type T;
1917 
1918  public:
1919  typedef StaticVector< typename SubTrait<T,T>::Type, 3UL, false > Type;
1920 };
1921 
1922 template< typename T1, typename T2 >
1923 struct CrossTrait< CompressedVector<T1,false>, DynamicVector<T2,false> >
1924 {
1925  private:
1926  typedef typename MultTrait<T1,T2>::Type T;
1927 
1928  public:
1929  typedef StaticVector< typename SubTrait<T,T>::Type, 3UL, false > Type;
1930 };
1931 
1932 template< typename T1, typename T2 >
1933 struct CrossTrait< DynamicVector<T1,false>, CompressedVector<T2,false> >
1934 {
1935  private:
1936  typedef typename MultTrait<T1,T2>::Type T;
1937 
1938  public:
1939  typedef StaticVector< typename SubTrait<T,T>::Type, 3UL, false > Type;
1940 };
1941 
1942 template< typename T1, typename T2 >
1943 struct CrossTrait< CompressedVector<T1,false>, CompressedVector<T2,false> >
1944 {
1945  private:
1946  typedef typename MultTrait<T1,T2>::Type T;
1947 
1948  public:
1949  typedef StaticVector< typename SubTrait<T,T>::Type, 3UL, false > Type;
1950 };
1952 //*************************************************************************************************
1953 
1954 
1955 
1956 
1957 //=================================================================================================
1958 //
1959 // DIVTRAIT SPECIALIZATIONS
1960 //
1961 //=================================================================================================
1962 
1963 //*************************************************************************************************
1965 template< typename T1, bool TF, typename T2 >
1966 struct DivTrait< CompressedVector<T1,TF>, T2 >
1967 {
1968  typedef CompressedVector< typename DivTrait<T1,T2>::Type, TF > Type;
1970 };
1972 //*************************************************************************************************
1973 
1974 
1975 
1976 
1977 //=================================================================================================
1978 //
1979 // MATHTRAIT SPECIALIZATIONS
1980 //
1981 //=================================================================================================
1982 
1983 //*************************************************************************************************
1985 template< typename T1, bool TF, typename T2 >
1986 struct MathTrait< CompressedVector<T1,TF>, CompressedVector<T2,TF> >
1987 {
1988  typedef CompressedVector< typename MathTrait<T1,T2>::HighType, TF > HighType;
1989  typedef CompressedVector< typename MathTrait<T1,T2>::LowType , TF > LowType;
1990 };
1992 //*************************************************************************************************
1993 
1994 } // namespace blaze
1995 
1996 #endif