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 <cmath>
32 #include <functional>
33 #include <stdexcept>
37 #include <blaze/math/Forward.h>
38 #include <blaze/math/Functions.h>
40 #include <blaze/math/shims/IsNaN.h>
52 #include <blaze/system/Precision.h>
54 #include <blaze/util/Assert.h>
63 #include <blaze/util/EnableIf.h>
64 #include <blaze/util/mpl/If.h>
65 #include <blaze/util/Null.h>
66 #include <blaze/util/Types.h>
69 
70 
71 namespace blaze {
72 
73 //=================================================================================================
74 //
75 // CLASS DEFINITION
76 //
77 //=================================================================================================
78 
79 //*************************************************************************************************
168 template< typename Type // Data type of the vector
169  , bool TF = defaultTransposeFlag > // Transpose flag
170 class CompressedVector : public SparseVector< CompressedVector<Type,TF>, TF >
171 {
172  private:
173  //**Type definitions****************************************************************************
175  //**********************************************************************************************
176 
177  //**Private class Element***********************************************************************
181  struct Element : public ElementBase
182  {
183  using ElementBase::operator=;
184  friend class CompressedVector;
185  };
187  //**********************************************************************************************
188 
189  //**Private class FindIndex*********************************************************************
193  struct FindIndex : public std::binary_function<Element,size_t,bool>
194  {
195  inline bool operator()( const Element& element, size_t index ) const {
196  return element.index() < index;
197  }
198  inline bool operator()( size_t index, const Element& element ) const {
199  return index < element.index();
200  }
201  inline bool operator()( const Element& element1, const Element& element2 ) const {
202  return element1.index() < element2.index();
203  }
204  };
206  //**********************************************************************************************
207 
208  public:
209  //**Type definitions****************************************************************************
211  typedef This ResultType;
213  typedef Type ElementType;
214  typedef const Type& ReturnType;
217  typedef const Type& ConstReference;
218  typedef Element* Iterator;
219  typedef const Element* ConstIterator;
220 
222 
224  //**********************************************************************************************
225 
226  //**Constructors********************************************************************************
229  explicit inline CompressedVector();
230  explicit inline CompressedVector( size_t size );
231  explicit inline CompressedVector( size_t size, size_t nonzeros );
232  inline CompressedVector( const CompressedVector& sv );
233  template< typename VT > inline CompressedVector( const DenseVector<VT,TF>& dv );
234  template< typename VT > inline CompressedVector( const SparseVector<VT,TF>& sv );
236  //**********************************************************************************************
237 
238  //**Destructor**********************************************************************************
241  inline ~CompressedVector();
243  //**********************************************************************************************
244 
245  //**Data access functions***********************************************************************
248  inline Reference operator[]( size_t index );
249  inline ConstReference operator[]( size_t index ) const;
250  inline Iterator begin ();
251  inline ConstIterator begin () const;
252  inline ConstIterator cbegin() const;
253  inline Iterator end ();
254  inline ConstIterator end () const;
255  inline ConstIterator cend () const;
257  //**********************************************************************************************
258 
259  //**Assignment operators************************************************************************
262  inline CompressedVector& operator= ( const CompressedVector& rhs );
263  template< typename VT > inline CompressedVector& operator= ( const DenseVector<VT,TF>& rhs );
264  template< typename VT > inline CompressedVector& operator= ( const SparseVector<VT,TF>& rhs );
265  template< typename VT > inline CompressedVector& operator+=( const Vector<VT,TF>& rhs );
266  template< typename VT > inline CompressedVector& operator-=( const Vector<VT,TF>& rhs );
267  template< typename VT > inline CompressedVector& operator*=( const Vector<VT,TF>& rhs );
268 
269  template< typename Other >
270  inline typename EnableIf< IsNumeric<Other>, CompressedVector >::Type&
271  operator*=( Other rhs );
272 
273  template< typename Other >
274  inline typename EnableIf< IsNumeric<Other>, CompressedVector >::Type&
275  operator/=( Other rhs );
277  //**********************************************************************************************
278 
279  //**Utility functions***************************************************************************
282  inline size_t size() const;
283  inline size_t capacity() const;
284  inline size_t nonZeros() const;
285  inline void reset();
286  inline void clear();
287  Iterator insert( size_t index, const Type& value );
288  inline void erase ( size_t index );
289  inline Iterator erase ( Iterator pos );
290  inline Iterator find ( size_t index );
291  inline ConstIterator find ( size_t index ) const;
292  inline void resize( size_t n, bool preserve=true );
293  void reserve( size_t n );
294  inline LengthType length() const;
295  inline const Type sqrLength() const;
297  const CompressedVector getNormalized() const;
298  template< typename Other > inline CompressedVector& scale( Other scalar );
299  inline void swap( CompressedVector& sv ) /* throw() */;
301  //**********************************************************************************************
302 
303  //**Low-level utility functions*****************************************************************
306  inline void append( size_t index, const Type& value, bool check=false );
308  //**********************************************************************************************
309 
310  //**Expression template evaluation functions****************************************************
313  template< typename Other > inline bool canAlias ( const Other* alias ) const;
314  template< typename Other > inline bool isAliased( const Other* alias ) const;
315  template< typename VT > inline void assign ( const DenseVector <VT,TF>& rhs );
316  template< typename VT > inline void assign ( const SparseVector<VT,TF>& rhs );
317  template< typename VT > inline void addAssign( const DenseVector <VT,TF>& rhs );
318  template< typename VT > inline void addAssign( const SparseVector<VT,TF>& rhs );
319  template< typename VT > inline void subAssign( const DenseVector <VT,TF>& rhs );
320  template< typename VT > inline void subAssign( const SparseVector<VT,TF>& rhs );
322  //**********************************************************************************************
323 
324  private:
325  //**Utility functions***************************************************************************
328  inline size_t extendCapacity() const;
330  //**********************************************************************************************
331 
332  //**Member variables****************************************************************************
335  size_t size_;
336  size_t capacity_;
339 
340  static const Type zero_;
341 
342  //**********************************************************************************************
343 
344  //**Compile time checks*************************************************************************
352  //**********************************************************************************************
353 };
354 //*************************************************************************************************
355 
356 
357 
358 
359 //=================================================================================================
360 //
361 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
362 //
363 //=================================================================================================
364 
365 template< typename Type // Data type of the vector
366  , bool TF > // Transpose flag
367 const Type CompressedVector<Type,TF>::zero_ = Type();
368 
369 
370 
371 
372 //=================================================================================================
373 //
374 // CONSTRUCTORS
375 //
376 //=================================================================================================
377 
378 //*************************************************************************************************
381 template< typename Type // Data type of the vector
382  , bool TF > // Transpose flag
384  : size_ ( 0UL ) // The current size/dimension of the compressed vector
385  , capacity_( 0UL ) // The maximum capacity of the compressed vector
386  , begin_ ( NULL ) // Pointer to the first non-zero element of the compressed vector
387  , end_ ( NULL ) // Pointer to the last non-zero element of the compressed vector
388 {}
389 //*************************************************************************************************
390 
391 
392 //*************************************************************************************************
397 template< typename Type // Data type of the vector
398  , bool TF > // Transpose flag
400  : size_ ( n ) // The current size/dimension of the compressed vector
401  , capacity_( 0UL ) // The maximum capacity of the compressed vector
402  , begin_ ( NULL ) // Pointer to the first non-zero element of the compressed vector
403  , end_ ( NULL ) // Pointer to the last non-zero element of the compressed vector
404 {}
405 //*************************************************************************************************
406 
407 
408 //*************************************************************************************************
414 template< typename Type // Data type of the vector
415  , bool TF > // Transpose flag
416 inline CompressedVector<Type,TF>::CompressedVector( size_t n, size_t nonzeros )
417  : size_ ( n ) // The current size/dimension of the compressed vector
418  , capacity_( nonzeros ) // The maximum capacity of the compressed vector
419  , begin_ ( new Element[capacity_] ) // Pointer to the first non-zero element of the compressed vector
420  , end_ ( begin_ ) // Pointer to the last non-zero element of the compressed vector
421 {}
422 //*************************************************************************************************
423 
424 
425 //*************************************************************************************************
433 template< typename Type // Data type of the vector
434  , bool TF > // Transpose flag
436  : size_ ( sv.size_ ) // The current size/dimension of the compressed vector
437  , capacity_( sv.nonZeros() ) // The maximum capacity of the compressed vector
438  , begin_ ( new Element[capacity_] ) // Pointer to the first non-zero element of the compressed vector
439  , end_ ( begin_+capacity_ ) // Pointer to the last non-zero element of the compressed vector
440 {
441  std::copy( sv.begin_, sv.end_, begin_ );
442 }
443 //*************************************************************************************************
444 
445 
446 //*************************************************************************************************
451 template< typename Type // Data type of the vector
452  , bool TF > // Transpose flag
453 template< typename VT > // Type of the foreign dense vector
455  : size_ ( (~dv).size() ) // The current size/dimension of the compressed vector
456  , capacity_( 0UL ) // The maximum capacity of the compressed vector
457  , begin_ ( NULL ) // Pointer to the first non-zero element of the compressed vector
458  , end_ ( NULL ) // Pointer to the last non-zero element of the compressed vector
459 {
460  using blaze::assign;
461  assign( *this, ~dv );
462 }
463 //*************************************************************************************************
464 
465 
466 //*************************************************************************************************
471 template< typename Type // Data type of the vector
472  , bool TF > // Transpose flag
473 template< typename VT > // Type of the foreign sparse vector
475  : size_ ( (~sv).size() ) // The current size/dimension of the compressed vector
476  , capacity_( (~sv).nonZeros() ) // The maximum capacity of the compressed vector
477  , begin_ ( new Element[capacity_] ) // Pointer to the first non-zero element of the compressed vector
478  , end_ ( begin_ ) // Pointer to the last non-zero element of the compressed vector
479 {
480  using blaze::assign;
481  assign( *this, ~sv );
482 }
483 //*************************************************************************************************
484 
485 
486 
487 
488 //=================================================================================================
489 //
490 // DESTRUCTOR
491 //
492 //=================================================================================================
493 
494 //*************************************************************************************************
497 template< typename Type // Data type of the vector
498  , bool TF > // Transpose flag
500 {
501  delete [] begin_;
502 }
503 //*************************************************************************************************
504 
505 
506 
507 
508 //=================================================================================================
509 //
510 // DATA ACCESS FUNCTIONS
511 //
512 //=================================================================================================
513 
514 //*************************************************************************************************
525 template< typename Type // Data type of the vector
526  , bool TF > // Transpose flag
529 {
530  BLAZE_USER_ASSERT( index < size_, "Invalid compressed vector access index" );
531 
532  return Reference( *this, index );
533 }
534 //*************************************************************************************************
535 
536 
537 //*************************************************************************************************
543 template< typename Type // Data type of the vector
544  , bool TF > // Transpose flag
547 {
548  BLAZE_USER_ASSERT( index < size_, "Invalid compressed vector access index" );
549 
550  const Iterator pos( std::lower_bound( begin_, end_, index, FindIndex() ) );
551 
552  if( pos == end_ || pos->index_ != index )
553  return zero_;
554  else
555  return pos->value_;
556 }
557 //*************************************************************************************************
558 
559 
560 //*************************************************************************************************
565 template< typename Type // Data type of the vector
566  , bool TF > // Transpose flag
568 {
569  return Iterator( begin_ );
570 }
571 //*************************************************************************************************
572 
573 
574 //*************************************************************************************************
579 template< typename Type // Data type of the vector
580  , bool TF > // Transpose flag
582 {
583  return ConstIterator( begin_ );
584 }
585 //*************************************************************************************************
586 
587 
588 //*************************************************************************************************
593 template< typename Type // Data type of the vector
594  , bool TF > // Transpose flag
596 {
597  return ConstIterator( begin_ );
598 }
599 //*************************************************************************************************
600 
601 
602 //*************************************************************************************************
607 template< typename Type // Data type of the vector
608  , bool TF > // Transpose flag
610 {
611  return Iterator( end_ );
612 }
613 //*************************************************************************************************
614 
615 
616 //*************************************************************************************************
621 template< typename Type // Data type of the vector
622  , bool TF > // Transpose flag
624 {
625  return ConstIterator( end_ );
626 }
627 //*************************************************************************************************
628 
629 
630 //*************************************************************************************************
635 template< typename Type // Data type of the vector
636  , bool TF > // Transpose flag
638 {
639  return ConstIterator( end_ );
640 }
641 //*************************************************************************************************
642 
643 
644 
645 
646 //=================================================================================================
647 //
648 // ASSIGNMENT OPERATORS
649 //
650 //=================================================================================================
651 
652 //*************************************************************************************************
661 template< typename Type // Data type of the vector
662  , bool TF > // Transpose flag
665 {
666  if( &rhs == this ) return *this;
667 
668  const size_t nonzeros( rhs.nonZeros() );
669 
670  if( nonzeros > capacity_ ) {
671  Iterator newBegin( new Element[nonzeros] );
672  end_ = std::copy( rhs.begin_, rhs.end_, newBegin );
673  std::swap( begin_, newBegin );
674  delete [] newBegin;
675 
676  size_ = rhs.size_;
677  capacity_ = nonzeros;
678  }
679  else {
680  end_ = std::copy( rhs.begin_, rhs.end_, begin_ );
681  size_ = rhs.size_;
682  }
683 
684  return *this;
685 }
686 //*************************************************************************************************
687 
688 
689 //*************************************************************************************************
698 template< typename Type // Data type of the vector
699  , bool TF > // Transpose flag
700 template< typename VT > // Type of the right-hand side dense vector
703 {
704  using blaze::assign;
705 
706  if( (~rhs).canAlias( this ) ) {
707  CompressedVector tmp( rhs );
708  swap( tmp );
709  }
710  else {
711  size_ = (~rhs).size();
712  end_ = begin_;
713  assign( *this, ~rhs );
714  }
715 
716  return *this;
717 }
718 //*************************************************************************************************
719 
720 
721 //*************************************************************************************************
730 template< typename Type // Data type of the vector
731  , bool TF > // Transpose flag
732 template< typename VT > // Type of the right-hand side sparse vector
735 {
736  using blaze::assign;
737 
738  if( (~rhs).canAlias( this ) || (~rhs).nonZeros() > capacity_ ) {
739  CompressedVector tmp( rhs );
740  swap( tmp );
741  }
742  else {
743  size_ = (~rhs).size();
744  end_ = begin_;
745  assign( *this, ~rhs );
746  }
747 
748  return *this;
749 }
750 //*************************************************************************************************
751 
752 
753 //*************************************************************************************************
763 template< typename Type // Data type of the vector
764  , bool TF > // Transpose flag
765 template< typename VT > // Type of the right-hand side vector
767 {
768  using blaze::addAssign;
769 
770  if( (~rhs).size() != size_ )
771  throw std::invalid_argument( "Vector sizes do not match" );
772 
773  addAssign( *this, ~rhs );
774 
775  return *this;
776 }
777 //*************************************************************************************************
778 
779 
780 //*************************************************************************************************
790 template< typename Type // Data type of the vector
791  , bool TF > // Transpose flag
792 template< typename VT > // Type of the right-hand side vector
794 {
795  using blaze::subAssign;
796 
797  if( (~rhs).size() != size_ )
798  throw std::invalid_argument( "Vector sizes do not match" );
799 
800  subAssign( *this, ~rhs );
801 
802  return *this;
803 }
804 //*************************************************************************************************
805 
806 
807 //*************************************************************************************************
818 template< typename Type // Data type of the vector
819  , bool TF > // Transpose flag
820 template< typename VT > // Type of the right-hand side vector
822 {
823  if( (~rhs).size() != size_ )
824  throw std::invalid_argument( "Vector sizes do not match" );
825 
826  CompressedVector<Type,TF> tmp( *this * (~rhs) );
827  swap( tmp );
828 
829  return *this;
830 }
831 //*************************************************************************************************
832 
833 
834 //*************************************************************************************************
845 template< typename Type // Data type of the vector
846  , bool TF > // Transpose flag
847 template< typename Other > // Data type of the right-hand side scalar
850 {
851  for( Iterator element=begin_; element!=end_; ++element )
852  element->value_ *= rhs;
853  return *this;
854 }
855 //*************************************************************************************************
856 
857 
858 //*************************************************************************************************
870 template< typename Type // Data type of the vector
871  , bool TF > // Transpose flag
872 template< typename Other > // Data type of the right-hand side scalar
875 {
876  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
877 
878  typedef typename DivTrait<Type,Other>::Type DT;
879  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
880 
881  // Depending on the two involved data types, an integer division is applied or a
882  // floating point division is selected.
884  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
885  for( Iterator element=begin_; element!=end_; ++element )
886  element->value_ *= tmp;
887  }
888  else {
889  for( Iterator element=begin_; element!=end_; ++element )
890  element->value_ /= rhs;
891  }
892 
893  return *this;
894 }
895 //*************************************************************************************************
896 
897 
898 
899 
900 //=================================================================================================
901 //
902 // UTILITY FUNCTIONS
903 //
904 //=================================================================================================
905 
906 //*************************************************************************************************
911 template< typename Type // Data type of the vector
912  , bool TF > // Transpose flag
913 inline size_t CompressedVector<Type,TF>::size() const
914 {
915  return size_;
916 }
917 //*************************************************************************************************
918 
919 
920 //*************************************************************************************************
925 template< typename Type // Data type of the vector
926  , bool TF > // Transpose flag
928 {
929  return capacity_;
930 }
931 //*************************************************************************************************
932 
933 
934 //*************************************************************************************************
942 template< typename Type // Data type of the vector
943  , bool TF > // Transpose flag
945 {
946  return end_ - begin_;
947 }
948 //*************************************************************************************************
949 
950 
951 //*************************************************************************************************
956 template< typename Type // Data type of the vector
957  , bool TF > // Transpose flag
959 {
960  end_ = begin_;
961 }
962 //*************************************************************************************************
963 
964 
965 //*************************************************************************************************
972 template< typename Type // Data type of the vector
973  , bool TF > // Transpose flag
975 {
976  size_ = 0UL;
977  end_ = begin_;
978 }
979 //*************************************************************************************************
980 
981 
982 //*************************************************************************************************
994 template< typename Type // Data type of the vector
995  , bool TF > // Transpose flag
997  CompressedVector<Type,TF>::insert( size_t index, const Type& value )
998 {
999  BLAZE_USER_ASSERT( index < size_, "Invalid compressed vector access index" );
1000 
1001  const Iterator pos( std::lower_bound( begin_, end_, index, FindIndex() ) );
1002 
1003  if( pos != end_ && pos->index_ == index )
1004  throw std::invalid_argument( "Bad access index" );
1005 
1006  if( nonZeros() != capacity_ ) {
1007  std::copy_backward( pos, end_, end_+1 );
1008  pos->value_ = value;
1009  pos->index_ = index;
1010  ++end_;
1011 
1012  return pos;
1013  }
1014  else {
1015  size_t newCapacity( extendCapacity() );
1016 
1017  Iterator newBegin = new Element[newCapacity];
1018  Iterator tmp = std::copy( begin_, pos, newBegin );
1019  tmp->value_ = value;
1020  tmp->index_ = index;
1021  end_ = std::copy( pos, end_, tmp+1 );
1022 
1023  std::swap( newBegin, begin_ );
1024  delete [] newBegin;
1025  capacity_ = newCapacity;
1026 
1027  return tmp;
1028  }
1029 }
1030 //*************************************************************************************************
1031 
1032 
1033 //*************************************************************************************************
1041 template< typename Type // Data type of the vector
1042  , bool TF > // Transpose flag
1043 inline void CompressedVector<Type,TF>::erase( size_t index )
1044 {
1045  BLAZE_USER_ASSERT( index < size_, "Invalid compressed vector access index" );
1046 
1047  const Iterator pos( find( index ) );
1048  if( pos != end_ )
1049  end_ = std::copy( pos+1, end_, pos );
1050 }
1051 //*************************************************************************************************
1052 
1053 
1054 //*************************************************************************************************
1062 template< typename Type // Data type of the vector
1063  , bool TF > // Transpose flag
1065 {
1066  BLAZE_USER_ASSERT( pos >= begin_ && pos <= end_, "Invalid compressed vector iterator" );
1067 
1068  if( pos != end_ )
1069  end_ = std::copy( pos+1, end_, pos );
1070  return pos;
1071 }
1072 //*************************************************************************************************
1073 
1074 
1075 //*************************************************************************************************
1088 template< typename Type // Data type of the vector
1089  , bool TF > // Transpose flag
1091 {
1092  return const_cast<Iterator>( const_cast<const This&>( *this ).find( index ) );
1093 }
1094 //*************************************************************************************************
1095 
1096 
1097 //*************************************************************************************************
1110 template< typename Type // Data type of the vector
1111  , bool TF > // Transpose flag
1113 {
1114  const Iterator pos( std::lower_bound( begin_, end_, index, FindIndex() ) );
1115  if( pos != end_ && pos->index_ == index )
1116  return pos;
1117  else return end_;
1118 }
1119 //*************************************************************************************************
1120 
1121 
1122 //*************************************************************************************************
1134 template< typename Type // Data type of the vector
1135  , bool TF > // Transpose flag
1136 inline void CompressedVector<Type,TF>::resize( size_t n, bool preserve )
1137 {
1138  if( preserve ) {
1139  end_ = std::lower_bound( begin_, end_, n, FindIndex() );
1140  }
1141  else {
1142  end_ = begin_;
1143  }
1144 
1145  size_ = n;
1146 }
1147 //*************************************************************************************************
1148 
1149 
1150 //*************************************************************************************************
1159 template< typename Type // Data type of the vector
1160  , bool TF > // Transpose flag
1162 {
1163  if( n > capacity_ ) {
1164  const size_t newCapacity( n );
1165 
1166  // Allocating a new data and index array
1167  Iterator newBegin = new Element[newCapacity];
1168 
1169  // Replacing the old data and index array
1170  end_ = std::copy( begin_, end_, newBegin );
1171  std::swap( newBegin, begin_ );
1172  capacity_ = newCapacity;
1173  delete [] newBegin;
1174  }
1175 }
1176 //*************************************************************************************************
1177 
1178 
1179 //*************************************************************************************************
1209 template< typename Type // Data type of the vector
1210  , bool TF > // Transpose flag
1211 #ifndef WIN32
1213 #else
1215 #endif
1216 {
1218 
1219  LengthType sum( 0 );
1220  for( Iterator element=begin_; element!=end_; ++element )
1221  sum += element->value_ * element->value_;
1222  return std::sqrt( sum );
1223 }
1224 //*************************************************************************************************
1225 
1226 
1227 //*************************************************************************************************
1237 template< typename Type // Data type of the vector
1238  , bool TF > // Transpose flag
1239 inline const Type CompressedVector<Type,TF>::sqrLength() const
1240 {
1242 
1243  Type sum( 0 );
1244  for( Iterator element=begin_; element!=end_; ++element )
1245  sum += element->value_ * element->value_;
1246  return sum;
1247 }
1248 //*************************************************************************************************
1249 
1250 
1251 //*************************************************************************************************
1260 template< typename Type // Data type of the vector
1261  , bool TF > // Transpose flag
1263 {
1265 
1266  const Type len( length() );
1267 
1268  if( len == Type(0) )
1269  return *this;
1270 
1271  const Type ilen( Type(1) / len );
1272 
1273  for( Iterator element=begin_; element!=end_; ++element )
1274  element->value_ *= ilen;
1275 
1276  return *this;
1277 }
1278 //*************************************************************************************************
1279 
1280 
1281 //*************************************************************************************************
1290 template< typename Type // Data type of the vector
1291  , bool TF > // Transpose flag
1293 {
1295 
1296  const Type len( length() );
1297 
1298  if( len == Type(0) )
1299  return *this;
1300 
1301  const Type ilen( Type(1) / len );
1302  CompressedVector tmp( *this );
1303 
1304  for( Iterator element=tmp.begin_; element!=tmp.end_; ++element ) {
1305  element->value_ *= ilen;
1306  }
1307 
1308  return tmp;
1309 }
1310 //*************************************************************************************************
1311 
1312 
1313 //*************************************************************************************************
1319 template< typename Type // Data type of the vector
1320  , bool TF > // Transpose flag
1321 template< typename Other > // Data type of the scalar value
1323 {
1324  for( Iterator element=begin_; element!=end_; ++element )
1325  element->value_ *= scalar;
1326  return *this;
1327 }
1328 //*************************************************************************************************
1329 
1330 
1331 //*************************************************************************************************
1338 template< typename Type // Data type of the vector
1339  , bool TF > // Transpose flag
1340 inline void CompressedVector<Type,TF>::swap( CompressedVector& sv ) /* throw() */
1341 {
1342  std::swap( size_, sv.size_ );
1343  std::swap( capacity_, sv.capacity_ );
1344  std::swap( begin_, sv.begin_ );
1345  std::swap( end_, sv.end_ );
1346 }
1347 //*************************************************************************************************
1348 
1349 
1350 //*************************************************************************************************
1358 template< typename Type // Data type of the vector
1359  , bool TF > // Transpose flag
1361 {
1362  using blaze::max;
1363  using blaze::min;
1364 
1365  size_t nonzeros( 2UL*capacity_+1UL );
1366  nonzeros = max( nonzeros, 7UL );
1367  nonzeros = min( nonzeros, size_ );
1368 
1369  BLAZE_INTERNAL_ASSERT( nonzeros > capacity_, "Invalid capacity value" );
1370 
1371  return nonzeros;
1372 }
1373 //*************************************************************************************************
1374 
1375 
1376 
1377 
1378 //=================================================================================================
1379 //
1380 // LOW-LEVEL UTILITY FUNCTIONS
1381 //
1382 //=================================================================================================
1383 
1384 //*************************************************************************************************
1408 template< typename Type // Data type of the vector
1409  , bool TF > // Transpose flag
1410 inline void CompressedVector<Type,TF>::append( size_t index, const Type& value, bool check )
1411 {
1412  BLAZE_USER_ASSERT( index < size_, "Invalid compressed vector access index" );
1413  BLAZE_USER_ASSERT( nonZeros() < capacity(), "Not enough reserved space" );
1414  BLAZE_USER_ASSERT( begin_ == end_ || (end_-1UL)->index_ < index, "Index is not strictly increasing" );
1415 
1416  end_->value_ = value;
1417 
1418  if( !check || !isDefault( end_->value_ ) ) {
1419  end_->index_ = index;
1420  ++end_;
1421  }
1422 }
1423 //*************************************************************************************************
1424 
1425 
1426 
1427 
1428 //=================================================================================================
1429 //
1430 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1431 //
1432 //=================================================================================================
1433 
1434 //*************************************************************************************************
1444 template< typename Type // Data type of the vector
1445  , bool TF > // Transpose flag
1446 template< typename Other > // Data type of the foreign expression
1447 inline bool CompressedVector<Type,TF>::canAlias( const Other* alias ) const
1448 {
1449  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1450 }
1451 //*************************************************************************************************
1452 
1453 
1454 //*************************************************************************************************
1464 template< typename Type // Data type of the vector
1465  , bool TF > // Transpose flag
1466 template< typename Other > // Data type of the foreign expression
1467 inline bool CompressedVector<Type,TF>::isAliased( const Other* alias ) const
1468 {
1469  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1470 }
1471 //*************************************************************************************************
1472 
1473 
1474 //*************************************************************************************************
1485 template< typename Type // Data type of the vector
1486  , bool TF > // Transpose flag
1487 template< typename VT > // Type of the right-hand side dense vector
1489 {
1490  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
1491 
1492  size_t nonzeros( 0UL );
1493 
1494  for( size_t i=0UL; i<size_; ++i )
1495  {
1496  if( nonzeros == capacity_ )
1497  reserve( extendCapacity() );
1498 
1499  end_->value_ = (~rhs)[i];
1500 
1501  if( !isDefault( end_->value_ ) ) {
1502  end_->index_ = i;
1503  ++end_;
1504  ++nonzeros;
1505  }
1506  }
1507 }
1508 //*************************************************************************************************
1509 
1510 
1511 //*************************************************************************************************
1522 template< typename Type // Data type of the vector
1523  , bool TF > // Transpose flag
1524 template< typename VT > // Type of the right-hand side sparse vector
1526 {
1527  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
1528 
1529  // Using the following formulation instead of a std::copy function call of the form
1530  //
1531  // end_ = std::copy( (~rhs).begin(), (~rhs).end(), begin_ );
1532  //
1533  // results in much less requirements on the ConstIterator type provided from the right-hand
1534  // sparse vector type
1535  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1536  append( element->index(), element->value() );
1537 }
1538 //*************************************************************************************************
1539 
1540 
1541 //*************************************************************************************************
1552 template< typename Type // Data type of the vector
1553  , bool TF > // Transpose flag
1554 template< typename VT > // Type of the right-hand side dense vector
1556 {
1557  typedef typename AddTrait<This,typename VT::ResultType>::Type AddType;
1558 
1561  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename AddType::CompositeType );
1562 
1563  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
1564 
1565  const AddType tmp( *this + (~rhs) );
1566  reset();
1567  assign( tmp );
1568 }
1569 //*************************************************************************************************
1570 
1571 
1572 //*************************************************************************************************
1583 template< typename Type // Data type of the vector
1584  , bool TF > // Transpose flag
1585 template< typename VT > // Type of the right-hand side sparse vector
1587 {
1588  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
1589 
1590  CompressedVector<Type,TF> tmp( *this + (~rhs) );
1591  swap( tmp );
1592 }
1593 //*************************************************************************************************
1594 
1595 
1596 //*************************************************************************************************
1607 template< typename Type // Data type of the vector
1608  , bool TF > // Transpose flag
1609 template< typename VT > // Type of the right-hand side dense vector
1611 {
1612  typedef typename SubTrait<This,typename VT::ResultType>::Type SubType;
1613 
1616  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename SubType::CompositeType );
1617 
1618  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
1619 
1620  const SubType tmp( *this - (~rhs) );
1621  reset();
1622  assign( tmp );
1623 }
1624 //*************************************************************************************************
1625 
1626 
1627 //*************************************************************************************************
1638 template< typename Type // Data type of the vector
1639  , bool TF > // Transpose flag
1640 template< typename VT > // Type of the right-hand side sparse vector
1642 {
1643  BLAZE_INTERNAL_ASSERT( size_ == (~rhs).size(), "Invalid vector sizes" );
1644 
1645  CompressedVector<Type,TF> tmp( *this - (~rhs) );
1646  swap( tmp );
1647 }
1648 //*************************************************************************************************
1649 
1650 
1651 
1652 
1653 //=================================================================================================
1654 //
1655 // COMPRESSEDVECTOR OPERATORS
1656 //
1657 //=================================================================================================
1658 
1659 //*************************************************************************************************
1662 template< typename Type, bool TF >
1663 inline void reset( CompressedVector<Type,TF>& v );
1664 
1665 template< typename Type, bool TF >
1666 inline void clear( CompressedVector<Type,TF>& v );
1667 
1668 template< typename Type, bool TF >
1669 inline bool isnan( const CompressedVector<Type,TF>& v );
1670 
1671 template< typename Type, bool TF >
1672 inline bool isDefault( const CompressedVector<Type,TF>& v );
1673 
1674 template< typename Type, bool TF >
1675 inline void swap( CompressedVector<Type,TF>& a, CompressedVector<Type,TF>& b ) /* throw() */;
1677 //*************************************************************************************************
1678 
1679 
1680 //*************************************************************************************************
1687 template< typename Type // Data type of the vector
1688  , bool TF > // Transpose flag
1690 {
1691  v.reset();
1692 }
1693 //*************************************************************************************************
1694 
1695 
1696 //*************************************************************************************************
1703 template< typename Type // Data type of the vector
1704  , bool TF > // Transpose flag
1706 {
1707  v.clear();
1708 }
1709 //*************************************************************************************************
1710 
1711 
1712 //*************************************************************************************************
1729 template< typename Type // Data type of the vector
1730  , bool TF > // Transpose flag
1731 inline bool isnan( const CompressedVector<Type,TF>& v )
1732 {
1733  typedef typename CompressedVector<Type,TF>::ConstIterator ConstIterator;
1734 
1735  const ConstIterator end( v.end() );
1736  for( ConstIterator element=v.begin(); element!=end; ++element ) {
1737  if( isnan( element->value() ) ) return true;
1738  }
1739  return false;
1740 }
1741 //*************************************************************************************************
1742 
1743 
1744 //*************************************************************************************************
1763 template< typename Type // Data type of the vector
1764  , bool TF > // Transpose flag
1765 inline bool isDefault( const CompressedVector<Type,TF>& v )
1766 {
1767  typedef typename CompressedVector<Type,TF>::ConstIterator ConstIterator;
1768 
1769  for( ConstIterator element=v.begin(); element!=v.end(); ++element )
1770  if( !isDefault( element->value() ) ) return false;
1771  return true;
1772 }
1773 //*************************************************************************************************
1774 
1775 
1776 //*************************************************************************************************
1785 template< typename Type // Data type of the vector
1786  , bool TF > // Transpose flag
1787 inline void swap( CompressedVector<Type,TF>& a, CompressedVector<Type,TF>& b ) /* throw() */
1788 {
1789  a.swap( b );
1790 }
1791 //*************************************************************************************************
1792 
1793 
1794 
1795 
1796 //=================================================================================================
1797 //
1798 // ISRESIZABLE SPECIALIZATIONS
1799 //
1800 //=================================================================================================
1801 
1802 //*************************************************************************************************
1804 template< typename T, bool TF >
1805 struct IsResizable< CompressedVector<T,TF> > : public TrueType
1806 {
1807  enum { value = 1 };
1808  typedef TrueType Type;
1809 };
1810 
1811 template< typename T, bool TF >
1812 struct IsResizable< const CompressedVector<T,TF> > : public TrueType
1813 {
1814  enum { value = 1 };
1815  typedef TrueType Type;
1816 };
1817 
1818 template< typename T, bool TF >
1819 struct IsResizable< volatile CompressedVector<T,TF> > : public TrueType
1820 {
1821  enum { value = 1 };
1822  typedef TrueType Type;
1823 };
1824 
1825 template< typename T, bool TF >
1826 struct IsResizable< const volatile CompressedVector<T,TF> > : public TrueType
1827 {
1828  enum { value = 1 };
1829  typedef TrueType Type;
1830 };
1832 //*************************************************************************************************
1833 
1834 
1835 
1836 
1837 //=================================================================================================
1838 //
1839 // ADDTRAIT SPECIALIZATIONS
1840 //
1841 //=================================================================================================
1842 
1843 //*************************************************************************************************
1845 template< typename T1, bool TF, typename T2, size_t N >
1846 struct AddTrait< CompressedVector<T1,TF>, StaticVector<T2,N,TF> >
1847 {
1848  typedef StaticVector< typename AddTrait<T1,T2>::Type, N, TF > Type;
1849 };
1850 
1851 template< typename T1, size_t N, bool TF, typename T2 >
1852 struct AddTrait< StaticVector<T1,N,TF>, CompressedVector<T2,TF> >
1853 {
1854  typedef StaticVector< typename AddTrait<T1,T2>::Type, N, TF > Type;
1855 };
1856 
1857 template< typename T1, bool TF, typename T2 >
1858 struct AddTrait< CompressedVector<T1,TF>, DynamicVector<T2,TF> >
1859 {
1860  typedef DynamicVector< typename AddTrait<T1,T2>::Type, TF > Type;
1861 };
1862 
1863 template< typename T1, bool TF, typename T2 >
1864 struct AddTrait< DynamicVector<T1,TF>, CompressedVector<T2,TF> >
1865 {
1866  typedef DynamicVector< typename AddTrait<T1,T2>::Type, TF > Type;
1867 };
1868 
1869 template< typename T1, bool TF, typename T2 >
1870 struct AddTrait< CompressedVector<T1,TF>, CompressedVector<T2,TF> >
1871 {
1872  typedef CompressedVector< typename AddTrait<T1,T2>::Type, TF > Type;
1873 };
1875 //*************************************************************************************************
1876 
1877 
1878 
1879 
1880 //=================================================================================================
1881 //
1882 // SUBTRAIT SPECIALIZATIONS
1883 //
1884 //=================================================================================================
1885 
1886 //*************************************************************************************************
1888 template< typename T1, bool TF, typename T2, size_t N >
1889 struct SubTrait< CompressedVector<T1,TF>, StaticVector<T2,N,TF> >
1890 {
1891  typedef StaticVector< typename SubTrait<T1,T2>::Type, N, TF > Type;
1892 };
1893 
1894 template< typename T1, size_t N, bool TF, typename T2 >
1895 struct SubTrait< StaticVector<T1,N,TF>, CompressedVector<T2,TF> >
1896 {
1897  typedef StaticVector< typename SubTrait<T1,T2>::Type, N, TF > Type;
1898 };
1899 
1900 template< typename T1, bool TF, typename T2 >
1901 struct SubTrait< CompressedVector<T1,TF>, DynamicVector<T2,TF> >
1902 {
1903  typedef DynamicVector< typename SubTrait<T1,T2>::Type, TF > Type;
1904 };
1905 
1906 template< typename T1, bool TF, typename T2 >
1907 struct SubTrait< DynamicVector<T1,TF>, CompressedVector<T2,TF> >
1908 {
1909  typedef DynamicVector< typename SubTrait<T1,T2>::Type, TF > Type;
1910 };
1911 
1912 template< typename T1, bool TF, typename T2 >
1913 struct SubTrait< CompressedVector<T1,TF>, CompressedVector<T2,TF> >
1914 {
1915  typedef CompressedVector< typename SubTrait<T1,T2>::Type, TF > Type;
1916 };
1918 //*************************************************************************************************
1919 
1920 
1921 
1922 
1923 //=================================================================================================
1924 //
1925 // MULTTRAIT SPECIALIZATIONS
1926 //
1927 //=================================================================================================
1928 
1929 //*************************************************************************************************
1931 template< typename T1, bool TF, typename T2 >
1932 struct MultTrait< CompressedVector<T1,TF>, T2 >
1933 {
1934  typedef CompressedVector< typename MultTrait<T1,T2>::Type, TF > Type;
1936 };
1937 
1938 template< typename T1, typename T2, bool TF >
1939 struct MultTrait< T1, CompressedVector<T2,TF> >
1940 {
1941  typedef CompressedVector< typename MultTrait<T1,T2>::Type, TF > Type;
1943 };
1944 
1945 template< typename T1, bool TF, typename T2, size_t N >
1946 struct MultTrait< CompressedVector<T1,TF>, StaticVector<T2,N,TF> >
1947 {
1948  typedef CompressedVector< typename MultTrait<T1,T2>::Type, TF > Type;
1949 };
1950 
1951 template< typename T1, typename T2, size_t N >
1952 struct MultTrait< CompressedVector<T1,false>, StaticVector<T2,N,true> >
1953 {
1954  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, true > Type;
1955 };
1956 
1957 template< typename T1, typename T2, size_t N >
1958 struct MultTrait< CompressedVector<T1,true>, StaticVector<T2,N,false> >
1959 {
1960  typedef typename MultTrait<T1,T2>::Type Type;
1961 };
1962 
1963 template< typename T1, size_t N, bool TF, typename T2 >
1964 struct MultTrait< StaticVector<T1,N,TF>, CompressedVector<T2,TF> >
1965 {
1966  typedef CompressedVector< typename MultTrait<T1,T2>::Type, TF > Type;
1967 };
1968 
1969 template< typename T1, size_t N, typename T2 >
1970 struct MultTrait< StaticVector<T1,N,false>, CompressedVector<T2,true> >
1971 {
1972  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, false > Type;
1973 };
1974 
1975 template< typename T1, size_t N, typename T2 >
1976 struct MultTrait< StaticVector<T1,N,true>, CompressedVector<T2,false> >
1977 {
1978  typedef typename MultTrait<T1,T2>::Type Type;
1979 };
1980 
1981 template< typename T1, bool TF, typename T2 >
1982 struct MultTrait< CompressedVector<T1,TF>, DynamicVector<T2,TF> >
1983 {
1984  typedef CompressedVector< typename MultTrait<T1,T2>::Type, TF > Type;
1985 };
1986 
1987 template< typename T1, typename T2 >
1988 struct MultTrait< CompressedVector<T1,false>, DynamicVector<T2,true> >
1989 {
1990  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, true > Type;
1991 };
1992 
1993 template< typename T1, typename T2 >
1994 struct MultTrait< CompressedVector<T1,true>, DynamicVector<T2,false> >
1995 {
1996  typedef typename MultTrait<T1,T2>::Type Type;
1997 };
1998 
1999 template< typename T1, bool TF, typename T2 >
2000 struct MultTrait< DynamicVector<T1,TF>, CompressedVector<T2,TF> >
2001 {
2002  typedef CompressedVector< typename MultTrait<T1,T2>::Type, TF > Type;
2003 };
2004 
2005 template< typename T1, typename T2 >
2006 struct MultTrait< DynamicVector<T1,false>, CompressedVector<T2,true> >
2007 {
2008  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, false > Type;
2009 };
2010 
2011 template< typename T1, typename T2 >
2012 struct MultTrait< DynamicVector<T1,true>, CompressedVector<T2,false> >
2013 {
2014  typedef typename MultTrait<T1,T2>::Type Type;
2015 };
2016 
2017 template< typename T1, bool TF, typename T2 >
2018 struct MultTrait< CompressedVector<T1,TF>, CompressedVector<T2,TF> >
2019 {
2020  typedef CompressedVector< typename MultTrait<T1,T2>::Type, TF > Type;
2021 };
2022 
2023 template< typename T1, typename T2 >
2024 struct MultTrait< CompressedVector<T1,false>, CompressedVector<T2,true> >
2025 {
2026  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, false > Type;
2027 };
2028 
2029 template< typename T1, typename T2 >
2030 struct MultTrait< CompressedVector<T1,true>, CompressedVector<T2,false> >
2031 {
2032  typedef typename MultTrait<T1,T2>::Type Type;
2033 };
2035 //*************************************************************************************************
2036 
2037 
2038 
2039 
2040 //=================================================================================================
2041 //
2042 // CROSSTRAIT SPECIALIZATIONS
2043 //
2044 //=================================================================================================
2045 
2046 //*************************************************************************************************
2048 template< typename T1, typename T2 >
2049 struct CrossTrait< CompressedVector<T1,false>, StaticVector<T2,3UL,false> >
2050 {
2051  private:
2052  typedef typename MultTrait<T1,T2>::Type T;
2053 
2054  public:
2055  typedef StaticVector< typename SubTrait<T,T>::Type, 3UL, false > Type;
2056 };
2057 
2058 template< typename T1, typename T2 >
2059 struct CrossTrait< StaticVector<T1,3UL,false>, CompressedVector<T2,false> >
2060 {
2061  private:
2062  typedef typename MultTrait<T1,T2>::Type T;
2063 
2064  public:
2065  typedef StaticVector< typename SubTrait<T,T>::Type, 3UL, false > Type;
2066 };
2067 
2068 template< typename T1, typename T2 >
2069 struct CrossTrait< CompressedVector<T1,false>, DynamicVector<T2,false> >
2070 {
2071  private:
2072  typedef typename MultTrait<T1,T2>::Type T;
2073 
2074  public:
2075  typedef StaticVector< typename SubTrait<T,T>::Type, 3UL, false > Type;
2076 };
2077 
2078 template< typename T1, typename T2 >
2079 struct CrossTrait< DynamicVector<T1,false>, CompressedVector<T2,false> >
2080 {
2081  private:
2082  typedef typename MultTrait<T1,T2>::Type T;
2083 
2084  public:
2085  typedef StaticVector< typename SubTrait<T,T>::Type, 3UL, false > Type;
2086 };
2087 
2088 template< typename T1, typename T2 >
2089 struct CrossTrait< CompressedVector<T1,false>, CompressedVector<T2,false> >
2090 {
2091  private:
2092  typedef typename MultTrait<T1,T2>::Type T;
2093 
2094  public:
2095  typedef StaticVector< typename SubTrait<T,T>::Type, 3UL, false > Type;
2096 };
2098 //*************************************************************************************************
2099 
2100 
2101 
2102 
2103 //=================================================================================================
2104 //
2105 // DIVTRAIT SPECIALIZATIONS
2106 //
2107 //=================================================================================================
2108 
2109 //*************************************************************************************************
2111 template< typename T1, bool TF, typename T2 >
2112 struct DivTrait< CompressedVector<T1,TF>, T2 >
2113 {
2114  typedef CompressedVector< typename DivTrait<T1,T2>::Type, TF > Type;
2116 };
2118 //*************************************************************************************************
2119 
2120 
2121 
2122 
2123 //=================================================================================================
2124 //
2125 // MATHTRAIT SPECIALIZATIONS
2126 //
2127 //=================================================================================================
2128 
2129 //*************************************************************************************************
2131 template< typename T1, bool TF, typename T2 >
2132 struct MathTrait< CompressedVector<T1,TF>, CompressedVector<T2,TF> >
2133 {
2134  typedef CompressedVector< typename MathTrait<T1,T2>::HighType, TF > HighType;
2135  typedef CompressedVector< typename MathTrait<T1,T2>::LowType , TF > LowType;
2136 };
2138 //*************************************************************************************************
2139 
2140 } // namespace blaze
2141 
2142 #endif