CompressedMatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_SPARSE_COMPRESSEDMATRIX_H_
36 #define _BLAZE_MATH_SPARSE_COMPRESSEDMATRIX_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <functional>
45 #include <vector>
48 #include <blaze/math/Forward.h>
49 #include <blaze/math/Functions.h>
71 #include <blaze/util/Assert.h>
77 #include <blaze/util/EnableIf.h>
78 #include <blaze/util/Exception.h>
79 #include <blaze/util/Memory.h>
80 #include <blaze/util/mpl/If.h>
81 #include <blaze/util/Null.h>
82 #include <blaze/util/Types.h>
85 
86 
87 namespace blaze {
88 
89 //=================================================================================================
90 //
91 // CLASS DEFINITION
92 //
93 //=================================================================================================
94 
95 //*************************************************************************************************
205 template< typename Type // Data type of the sparse matrix
206  , bool SO = defaultStorageOrder > // Storage order
207 class CompressedMatrix : public SparseMatrix< CompressedMatrix<Type,SO>, SO >
208 {
209  private:
210  //**Type definitions****************************************************************************
212  //**********************************************************************************************
213 
214  //**Private class Element***********************************************************************
218  struct Element : public ElementBase
219  {
220  // This operator is required due to a bug in all versions of the the MSVC compiler.
221  // A simple 'using ElementBase::operator=;' statement results in ambiguity problems.
222  template< typename Other >
223  inline Element& operator=( const Other& rhs )
224  {
225  ElementBase::operator=( rhs );
226  return *this;
227  }
228 
229  friend class CompressedMatrix;
230  };
232  //**********************************************************************************************
233 
234  //**Private class FindIndex*********************************************************************
238  struct FindIndex : public std::binary_function<Element,size_t,bool>
239  {
240  inline bool operator()( const Element& element, size_t index ) const {
241  return element.index() < index;
242  }
243  inline bool operator()( size_t index, const Element& element ) const {
244  return index < element.index();
245  }
246  inline bool operator()( const Element& element1, const Element& element2 ) const {
247  return element1.index() < element2.index();
248  }
249  };
251  //**********************************************************************************************
252 
253  public:
254  //**Type definitions****************************************************************************
256  typedef This ResultType;
259  typedef Type ElementType;
260  typedef const Type& ReturnType;
261  typedef const This& CompositeType;
263  typedef const Type& ConstReference;
264  typedef Element* Iterator;
265  typedef const Element* ConstIterator;
266  //**********************************************************************************************
267 
268  //**Rebind struct definition********************************************************************
271  template< typename ET > // Data type of the other matrix
272  struct Rebind {
274  };
275  //**********************************************************************************************
276 
277  //**Compilation flags***************************************************************************
279 
282  enum { smpAssignable = !IsSMPAssignable<Type>::value };
283  //**********************************************************************************************
284 
285  //**Constructors********************************************************************************
288  explicit inline CompressedMatrix();
289  explicit inline CompressedMatrix( size_t m, size_t n );
290  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
291  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
292  inline CompressedMatrix( const CompressedMatrix& sm );
293  template< typename MT, bool SO2 > inline CompressedMatrix( const DenseMatrix<MT,SO2>& dm );
294  template< typename MT, bool SO2 > inline CompressedMatrix( const SparseMatrix<MT,SO2>& sm );
296  //**********************************************************************************************
297 
298  //**Destructor**********************************************************************************
301  inline ~CompressedMatrix();
303  //**********************************************************************************************
304 
305  //**Data access functions***********************************************************************
308  inline Reference operator()( size_t i, size_t j );
309  inline ConstReference operator()( size_t i, size_t j ) const;
310  inline Reference at( size_t i, size_t j );
311  inline ConstReference at( size_t i, size_t j ) const;
312  inline Iterator begin ( size_t i );
313  inline ConstIterator begin ( size_t i ) const;
314  inline ConstIterator cbegin( size_t i ) const;
315  inline Iterator end ( size_t i );
316  inline ConstIterator end ( size_t i ) const;
317  inline ConstIterator cend ( size_t i ) const;
319  //**********************************************************************************************
320 
321  //**Assignment operators************************************************************************
324  inline CompressedMatrix& operator= ( const CompressedMatrix& rhs );
325  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO2>& rhs );
326  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO2>& rhs );
327  template< typename MT, bool SO2 > inline CompressedMatrix& operator+=( const Matrix<MT,SO2>& rhs );
328  template< typename MT, bool SO2 > inline CompressedMatrix& operator-=( const Matrix<MT,SO2>& rhs );
329  template< typename MT, bool SO2 > inline CompressedMatrix& operator*=( const Matrix<MT,SO2>& rhs );
330 
331  template< typename Other >
332  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
333  operator*=( Other rhs );
334 
335  template< typename Other >
336  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
337  operator/=( Other rhs );
339  //**********************************************************************************************
340 
341  //**Utility functions***************************************************************************
344  inline size_t rows() const;
345  inline size_t columns() const;
346  inline size_t capacity() const;
347  inline size_t capacity( size_t i ) const;
348  inline size_t nonZeros() const;
349  inline size_t nonZeros( size_t i ) const;
350  inline void reset();
351  inline void reset( size_t i );
352  inline void clear();
353  inline Iterator set ( size_t i, size_t j, const Type& value );
354  inline Iterator insert ( size_t i, size_t j, const Type& value );
355  inline void erase ( size_t i, size_t j );
356  inline Iterator erase ( size_t i, Iterator pos );
357  inline Iterator erase ( size_t i, Iterator first, Iterator last );
358  void resize ( size_t m, size_t n, bool preserve=true );
359  inline void reserve( size_t nonzeros );
360  void reserve( size_t i, size_t nonzeros );
361  inline void trim ();
362  inline void trim ( size_t i );
363  inline CompressedMatrix& transpose();
364  inline CompressedMatrix& ctranspose();
365  template< typename Other > inline CompressedMatrix& scale( const Other& scalar );
366  template< typename Other > inline CompressedMatrix& scaleDiagonal( Other scalar );
367  inline void swap( CompressedMatrix& sm ) /* throw() */;
369  //**********************************************************************************************
370 
371  //**Lookup functions****************************************************************************
374  inline Iterator find ( size_t i, size_t j );
375  inline ConstIterator find ( size_t i, size_t j ) const;
376  inline Iterator lowerBound( size_t i, size_t j );
377  inline ConstIterator lowerBound( size_t i, size_t j ) const;
378  inline Iterator upperBound( size_t i, size_t j );
379  inline ConstIterator upperBound( size_t i, size_t j ) const;
381  //**********************************************************************************************
382 
383  //**Low-level utility functions*****************************************************************
386  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
387  inline void finalize( size_t i );
389  //**********************************************************************************************
390 
391  //**Expression template evaluation functions****************************************************
394  template< typename Other > inline bool canAlias ( const Other* alias ) const;
395  template< typename Other > inline bool isAliased( const Other* alias ) const;
396 
397  inline bool canSMPAssign() const;
398 
399  template< typename MT, bool SO2 > inline void assign ( const DenseMatrix<MT,SO2>& rhs );
400  template< typename MT > inline void assign ( const SparseMatrix<MT,SO>& rhs );
401  template< typename MT > inline void assign ( const SparseMatrix<MT,!SO>& rhs );
402  template< typename MT, bool SO2 > inline void addAssign( const DenseMatrix<MT,SO2>& rhs );
403  template< typename MT, bool SO2 > inline void addAssign( const SparseMatrix<MT,SO2>& rhs );
404  template< typename MT, bool SO2 > inline void subAssign( const DenseMatrix<MT,SO2>& rhs );
405  template< typename MT, bool SO2 > inline void subAssign( const SparseMatrix<MT,SO2>& rhs );
407  //**********************************************************************************************
408 
409  private:
410  //**Utility functions***************************************************************************
413  Iterator insert( Iterator pos, size_t i, size_t j, const Type& value );
414  inline size_t extendCapacity() const;
415  void reserveElements( size_t nonzeros );
417  //**********************************************************************************************
418 
419  //**Member variables****************************************************************************
422  size_t m_;
423  size_t n_;
424  size_t capacity_;
425  Iterator* begin_;
426  Iterator* end_;
427 
428  static const Type zero_;
429 
430  //**********************************************************************************************
431 
432  //**Compile time checks*************************************************************************
438  BLAZE_CONSTRAINT_MUST_HAVE_SAME_SIZE ( ElementBase, Element );
440  //**********************************************************************************************
441 };
442 //*************************************************************************************************
443 
444 
445 
446 
447 //=================================================================================================
448 //
449 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
450 //
451 //=================================================================================================
452 
453 template< typename Type, bool SO >
454 const Type CompressedMatrix<Type,SO>::zero_ = Type();
455 
456 
457 
458 
459 //=================================================================================================
460 //
461 // CONSTRUCTORS
462 //
463 //=================================================================================================
464 
465 //*************************************************************************************************
468 template< typename Type // Data type of the sparse matrix
469  , bool SO > // Storage order
471  : m_ ( 0UL ) // The current number of rows of the sparse matrix
472  , n_ ( 0UL ) // The current number of columns of the sparse matrix
473  , capacity_( 0UL ) // The current capacity of the pointer array
474  , begin_( new Iterator[2] ) // Pointers to the first non-zero element of each row
475  , end_ ( begin_+1 ) // Pointers one past the last non-zero element of each row
476 {
477  begin_[0] = end_[0] = NULL;
478 }
479 //*************************************************************************************************
480 
481 
482 //*************************************************************************************************
490 template< typename Type // Data type of the sparse matrix
491  , bool SO > // Storage order
493  : m_ ( m ) // The current number of rows of the sparse matrix
494  , n_ ( n ) // The current number of columns of the sparse matrix
495  , capacity_( m ) // The current capacity of the pointer array
496  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
497  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
498 {
499  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
500  begin_[i] = NULL;
501 }
502 //*************************************************************************************************
503 
504 
505 //*************************************************************************************************
514 template< typename Type // Data type of the sparse matrix
515  , bool SO > // Storage order
516 inline CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
517  : m_ ( m ) // The current number of rows of the sparse matrix
518  , n_ ( n ) // The current number of columns of the sparse matrix
519  , capacity_( m ) // The current capacity of the pointer array
520  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
521  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
522 {
523  begin_[0UL] = allocate<Element>( nonzeros );
524  for( size_t i=1UL; i<(2UL*m_+1UL); ++i )
525  begin_[i] = begin_[0UL];
526  end_[m_] = begin_[0UL]+nonzeros;
527 }
528 //*************************************************************************************************
529 
530 
531 //*************************************************************************************************
542 template< typename Type // Data type of the sparse matrix
543  , bool SO > // Storage order
544 CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
545  : m_ ( m ) // The current number of rows of the sparse matrix
546  , n_ ( n ) // The current number of columns of the sparse matrix
547  , capacity_( m ) // The current capacity of the pointer array
548  , begin_( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
549  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
550 {
551  BLAZE_USER_ASSERT( nonzeros.size() == m, "Size of capacity vector and number of rows don't match" );
552 
553  size_t newCapacity( 0UL );
554  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
555  newCapacity += *it;
556 
557  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
558  for( size_t i=0UL; i<m_; ++i ) {
559  begin_[i+1UL] = end_[i+1UL] = begin_[i] + nonzeros[i];
560  }
561 }
562 //*************************************************************************************************
563 
564 
565 //*************************************************************************************************
570 template< typename Type // Data type of the sparse matrix
571  , bool SO > // Storage order
573  : m_ ( sm.m_ ) // The current number of rows of the sparse matrix
574  , n_ ( sm.n_ ) // The current number of columns of the sparse matrix
575  , capacity_( sm.m_ ) // The current capacity of the pointer array
576  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
577  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
578 {
579  const size_t nonzeros( sm.nonZeros() );
580 
581  begin_[0UL] = allocate<Element>( nonzeros );
582  for( size_t i=0UL; i<m_; ++i )
583  begin_[i+1UL] = end_[i] = std::copy( sm.begin(i), sm.end(i), begin_[i] );
584  end_[m_] = begin_[0UL]+nonzeros;
585 }
586 //*************************************************************************************************
587 
588 
589 //*************************************************************************************************
594 template< typename Type // Data type of the sparse matrix
595  , bool SO > // Storage order
596 template< typename MT // Type of the foreign dense matrix
597  , bool SO2 > // Storage order of the foreign dense matrix
599  : m_ ( (~dm).rows() ) // The current number of rows of the sparse matrix
600  , n_ ( (~dm).columns() ) // The current number of columns of the sparse matrix
601  , capacity_( m_ ) // The current capacity of the pointer array
602  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
603  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
604 {
605  using blaze::assign;
606 
607  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
608  begin_[i] = NULL;
609 
610  assign( *this, ~dm );
611 }
612 //*************************************************************************************************
613 
614 
615 //*************************************************************************************************
620 template< typename Type // Data type of the sparse matrix
621  , bool SO > // Storage order
622 template< typename MT // Type of the foreign sparse matrix
623  , bool SO2 > // Storage order of the foreign sparse matrix
625  : m_ ( (~sm).rows() ) // The current number of rows of the sparse matrix
626  , n_ ( (~sm).columns() ) // The current number of columns of the sparse matrix
627  , capacity_( m_ ) // The current capacity of the pointer array
628  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
629  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
630 {
631  using blaze::assign;
632 
633  const size_t nonzeros( (~sm).nonZeros() );
634 
635  begin_[0UL] = allocate<Element>( nonzeros );
636  for( size_t i=0UL; i<m_; ++i )
637  begin_[i+1UL] = end_[i] = begin_[0UL];
638  end_[m_] = begin_[0UL]+nonzeros;
639 
640  assign( *this, ~sm );
641 }
642 //*************************************************************************************************
643 
644 
645 
646 
647 //=================================================================================================
648 //
649 // DESTRUCTOR
650 //
651 //=================================================================================================
652 
653 //*************************************************************************************************
656 template< typename Type // Data type of the sparse matrix
657  , bool SO > // Storage order
659 {
660  deallocate( begin_[0UL] );
661  delete [] begin_;
662 }
663 //*************************************************************************************************
664 
665 
666 
667 
668 //=================================================================================================
669 //
670 // DATA ACCESS FUNCTIONS
671 //
672 //=================================================================================================
673 
674 //*************************************************************************************************
684 template< typename Type // Data type of the sparse matrix
685  , bool SO > // Storage order
688 {
689  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
690  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
691 
692  return Reference( *this, i, j );
693 }
694 //*************************************************************************************************
695 
696 
697 //*************************************************************************************************
707 template< typename Type // Data type of the sparse matrix
708  , bool SO > // Storage order
710  CompressedMatrix<Type,SO>::operator()( size_t i, size_t j ) const
711 {
712  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
713  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
714 
715  const ConstIterator pos( lowerBound( i, j ) );
716 
717  if( pos == end_[i] || pos->index_ != j )
718  return zero_;
719  else
720  return pos->value_;
721 }
722 //*************************************************************************************************
723 
724 
725 //*************************************************************************************************
736 template< typename Type // Data type of the sparse matrix
737  , bool SO > // Storage order
739  CompressedMatrix<Type,SO>::at( size_t i, size_t j )
740 {
741  if( i >= m_ ) {
742  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
743  }
744  if( j >= n_ ) {
745  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
746  }
747  return (*this)(i,j);
748 }
749 //*************************************************************************************************
750 
751 
752 //*************************************************************************************************
763 template< typename Type // Data type of the sparse matrix
764  , bool SO > // Storage order
766  CompressedMatrix<Type,SO>::at( size_t i, size_t j ) const
767 {
768  if( i >= m_ ) {
769  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
770  }
771  if( j >= n_ ) {
772  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
773  }
774  return (*this)(i,j);
775 }
776 //*************************************************************************************************
777 
778 
779 //*************************************************************************************************
790 template< typename Type // Data type of the sparse matrix
791  , bool SO > // Storage order
794 {
795  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
796  return begin_[i];
797 }
798 //*************************************************************************************************
799 
800 
801 //*************************************************************************************************
812 template< typename Type // Data type of the sparse matrix
813  , bool SO > // Storage order
816 {
817  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
818  return begin_[i];
819 }
820 //*************************************************************************************************
821 
822 
823 //*************************************************************************************************
834 template< typename Type // Data type of the sparse matrix
835  , bool SO > // Storage order
838 {
839  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
840  return begin_[i];
841 }
842 //*************************************************************************************************
843 
844 
845 //*************************************************************************************************
856 template< typename Type // Data type of the sparse matrix
857  , bool SO > // Storage order
860 {
861  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
862  return end_[i];
863 }
864 //*************************************************************************************************
865 
866 
867 //*************************************************************************************************
878 template< typename Type // Data type of the sparse matrix
879  , bool SO > // Storage order
882 {
883  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
884  return end_[i];
885 }
886 //*************************************************************************************************
887 
888 
889 //*************************************************************************************************
900 template< typename Type // Data type of the sparse matrix
901  , bool SO > // Storage order
904 {
905  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
906  return end_[i];
907 }
908 //*************************************************************************************************
909 
910 
911 
912 
913 //=================================================================================================
914 //
915 // ASSIGNMENT OPERATORS
916 //
917 //=================================================================================================
918 
919 //*************************************************************************************************
928 template< typename Type // Data type of the sparse matrix
929  , bool SO > // Storage order
932 {
933  if( &rhs == this ) return *this;
934 
935  const size_t nonzeros( rhs.nonZeros() );
936 
937  if( rhs.m_ > capacity_ || nonzeros > capacity() )
938  {
939  Iterator* newBegin( new Iterator[2UL*rhs.m_+2UL] );
940  Iterator* newEnd ( newBegin+(rhs.m_+1UL) );
941 
942  newBegin[0UL] = allocate<Element>( nonzeros );
943  for( size_t i=0UL; i<rhs.m_; ++i ) {
944  newBegin[i+1UL] = newEnd[i] = std::copy( rhs.begin_[i], rhs.end_[i], newBegin[i] );
945  }
946  newEnd[rhs.m_] = newBegin[0UL]+nonzeros;
947 
948  std::swap( begin_, newBegin );
949  end_ = newEnd;
950  deallocate( newBegin[0UL] );
951  delete [] newBegin;
952  capacity_ = rhs.m_;
953  }
954  else {
955  for( size_t i=0UL; i<rhs.m_; ++i ) {
956  begin_[i+1UL] = end_[i] = std::copy( rhs.begin_[i], rhs.end_[i], begin_[i] );
957  }
958  }
959 
960  m_ = rhs.m_;
961  n_ = rhs.n_;
962 
963  return *this;
964 }
965 //*************************************************************************************************
966 
967 
968 //*************************************************************************************************
977 template< typename Type // Data type of the sparse matrix
978  , bool SO > // Storage order
979 template< typename MT // Type of the right-hand side dense matrix
980  , bool SO2 > // Storage order of the right-hand side dense matrix
983 {
984  using blaze::assign;
985 
986  if( (~rhs).canAlias( this ) ) {
987  CompressedMatrix tmp( ~rhs );
988  swap( tmp );
989  }
990  else {
991  resize( (~rhs).rows(), (~rhs).columns(), false );
992  assign( *this, ~rhs );
993  }
994 
995  return *this;
996 }
997 //*************************************************************************************************
998 
999 
1000 //*************************************************************************************************
1009 template< typename Type // Data type of the sparse matrix
1010  , bool SO > // Storage order
1011 template< typename MT // Type of the right-hand side sparse matrix
1012  , bool SO2 > // Storage order of the right-hand side sparse matrix
1015 {
1016  using blaze::assign;
1017 
1018  if( (~rhs).canAlias( this ) ||
1019  (~rhs).rows() > capacity_ ||
1020  (~rhs).nonZeros() > capacity() ) {
1021  CompressedMatrix tmp( ~rhs );
1022  swap( tmp );
1023  }
1024  else {
1025  resize( (~rhs).rows(), (~rhs).columns(), false );
1026  reset();
1027  assign( *this, ~rhs );
1028  }
1029 
1030  return *this;
1031 }
1032 //*************************************************************************************************
1033 
1034 
1035 //*************************************************************************************************
1045 template< typename Type // Data type of the sparse matrix
1046  , bool SO > // Storage order
1047 template< typename MT // Type of the right-hand side matrix
1048  , bool SO2 > // Storage order of the right-hand side matrix
1051 {
1052  using blaze::addAssign;
1053 
1054  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1055  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1056  }
1057 
1058  addAssign( *this, ~rhs );
1059  return *this;
1060 }
1061 //*************************************************************************************************
1062 
1063 
1064 //*************************************************************************************************
1074 template< typename Type // Data type of the sparse matrix
1075  , bool SO > // Storage order
1076 template< typename MT // Type of the right-hand side matrix
1077  , bool SO2 > // Storage order of the right-hand side matrix
1079 {
1080  using blaze::subAssign;
1081 
1082  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1083  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1084  }
1085 
1086  subAssign( *this, ~rhs );
1087  return *this;
1088 }
1089 //*************************************************************************************************
1090 
1091 
1092 //*************************************************************************************************
1102 template< typename Type // Data type of the sparse matrix
1103  , bool SO > // Storage order
1104 template< typename MT // Type of the right-hand side matrix
1105  , bool SO2 > // Storage order of the right-hand side matrix
1108 {
1109  if( (~rhs).rows() != n_ ) {
1110  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1111  }
1112 
1113  CompressedMatrix tmp( *this * (~rhs) );
1114  swap( tmp );
1115 
1116  return *this;
1117 }
1118 //*************************************************************************************************
1119 
1120 
1121 //*************************************************************************************************
1128 template< typename Type // Data type of the sparse matrix
1129  , bool SO > // Storage order
1130 template< typename Other > // Data type of the right-hand side scalar
1131 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,SO> >::Type&
1133 {
1134  for( size_t i=0UL; i<m_; ++i ) {
1135  const Iterator last( end(i) );
1136  for( Iterator element=begin(i); element!=last; ++element )
1137  element->value_ *= rhs;
1138  }
1139  return *this;
1140 }
1141 //*************************************************************************************************
1142 
1143 
1144 //*************************************************************************************************
1151 template< typename Type // Data type of the sparse matrix
1152  , bool SO > // Storage order
1153 template< typename Other > // Data type of the right-hand side scalar
1154 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,SO> >::Type&
1156 {
1157  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1158 
1159  typedef typename DivTrait<Type,Other>::Type DT;
1160  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
1161 
1162  // Depending on the two involved data types, an integer division is applied or a
1163  // floating point division is selected.
1165  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1166  for( size_t i=0UL; i<m_; ++i ) {
1167  const Iterator last( end(i) );
1168  for( Iterator element=begin(i); element!=last; ++element )
1169  element->value_ *= tmp;
1170  }
1171  }
1172  else {
1173  for( size_t i=0UL; i<m_; ++i ) {
1174  const Iterator last( end(i) );
1175  for( Iterator element=begin(i); element!=last; ++element )
1176  element->value_ /= rhs;
1177  }
1178  }
1179 
1180  return *this;
1181 }
1182 //*************************************************************************************************
1183 
1184 
1185 
1186 
1187 //=================================================================================================
1188 //
1189 // UTILITY FUNCTIONS
1190 //
1191 //=================================================================================================
1192 
1193 //*************************************************************************************************
1198 template< typename Type // Data type of the sparse matrix
1199  , bool SO > // Storage order
1200 inline size_t CompressedMatrix<Type,SO>::rows() const
1201 {
1202  return m_;
1203 }
1204 //*************************************************************************************************
1205 
1206 
1207 //*************************************************************************************************
1212 template< typename Type // Data type of the sparse matrix
1213  , bool SO > // Storage order
1215 {
1216  return n_;
1217 }
1218 //*************************************************************************************************
1219 
1220 
1221 //*************************************************************************************************
1226 template< typename Type // Data type of the sparse matrix
1227  , bool SO > // Storage order
1229 {
1230  return end_[m_] - begin_[0UL];
1231 }
1232 //*************************************************************************************************
1233 
1234 
1235 //*************************************************************************************************
1246 template< typename Type // Data type of the sparse matrix
1247  , bool SO > // Storage order
1248 inline size_t CompressedMatrix<Type,SO>::capacity( size_t i ) const
1249 {
1250  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1251  return begin_[i+1UL] - begin_[i];
1252 }
1253 //*************************************************************************************************
1254 
1255 
1256 //*************************************************************************************************
1261 template< typename Type // Data type of the sparse matrix
1262  , bool SO > // Storage order
1264 {
1265  size_t nonzeros( 0UL );
1266 
1267  for( size_t i=0UL; i<m_; ++i )
1268  nonzeros += nonZeros( i );
1269 
1270  return nonzeros;
1271 }
1272 //*************************************************************************************************
1273 
1274 
1275 //*************************************************************************************************
1286 template< typename Type // Data type of the sparse matrix
1287  , bool SO > // Storage order
1288 inline size_t CompressedMatrix<Type,SO>::nonZeros( size_t i ) const
1289 {
1290  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1291  return end_[i] - begin_[i];
1292 }
1293 //*************************************************************************************************
1294 
1295 
1296 //*************************************************************************************************
1301 template< typename Type // Data type of the sparse matrix
1302  , bool SO > // Storage order
1304 {
1305  for( size_t i=0UL; i<m_; ++i )
1306  end_[i] = begin_[i];
1307 }
1308 //*************************************************************************************************
1309 
1310 
1311 //*************************************************************************************************
1322 template< typename Type // Data type of the sparse matrix
1323  , bool SO > // Storage order
1324 inline void CompressedMatrix<Type,SO>::reset( size_t i )
1325 {
1326  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1327  end_[i] = begin_[i];
1328 }
1329 //*************************************************************************************************
1330 
1331 
1332 //*************************************************************************************************
1339 template< typename Type // Data type of the sparse matrix
1340  , bool SO > // Storage order
1342 {
1343  end_[0UL] = end_[m_];
1344  m_ = 0UL;
1345  n_ = 0UL;
1346 }
1347 //*************************************************************************************************
1348 
1349 
1350 //*************************************************************************************************
1362 template< typename Type // Data type of the sparse matrix
1363  , bool SO > // Storage order
1365  CompressedMatrix<Type,SO>::set( size_t i, size_t j, const Type& value )
1366 {
1367  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1368  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1369 
1370  const Iterator pos( lowerBound( i, j ) );
1371 
1372  if( pos != end_[i] && pos->index_ == j ) {
1373  pos->value() = value;
1374  return pos;
1375  }
1376  else return insert( pos, i, j, value );
1377 }
1378 //*************************************************************************************************
1379 
1380 
1381 //*************************************************************************************************
1394 template< typename Type // Data type of the sparse matrix
1395  , bool SO > // Storage order
1397  CompressedMatrix<Type,SO>::insert( size_t i, size_t j, const Type& value )
1398 {
1399  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1400  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1401 
1402  const Iterator pos( lowerBound( i, j ) );
1403 
1404  if( pos != end_[i] && pos->index_ == j ) {
1405  BLAZE_THROW_INVALID_ARGUMENT( "Bad access index" );
1406  }
1407 
1408  return insert( pos, i, j, value );
1409 }
1410 //*************************************************************************************************
1411 
1412 
1413 //*************************************************************************************************
1423 template< typename Type // Data type of the sparse matrix
1424  , bool SO > // Storage order
1426  CompressedMatrix<Type,SO>::insert( Iterator pos, size_t i, size_t j, const Type& value )
1427 {
1428  if( begin_[i+1UL] - end_[i] != 0 ) {
1429  std::copy_backward( pos, end_[i], end_[i]+1 );
1430  pos->value_ = value;
1431  pos->index_ = j;
1432  ++end_[i];
1433 
1434  return pos;
1435  }
1436  else if( end_[m_] - begin_[m_] != 0 ) {
1437  std::copy_backward( pos, end_[m_-1UL], end_[m_-1UL]+1 );
1438 
1439  pos->value_ = value;
1440  pos->index_ = j;
1441 
1442  for( size_t k=i+1UL; k<m_+1UL; ++k ) {
1443  ++begin_[k];
1444  ++end_[k-1UL];
1445  }
1446 
1447  return pos;
1448  }
1449  else {
1450  size_t newCapacity( extendCapacity() );
1451 
1452  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1453  Iterator* newEnd = newBegin+capacity_+1UL;
1454 
1455  newBegin[0UL] = allocate<Element>( newCapacity );
1456 
1457  for( size_t k=0UL; k<i; ++k ) {
1458  const size_t nonzeros( end_[k] - begin_[k] );
1459  const size_t total( begin_[k+1UL] - begin_[k] );
1460  newEnd [k] = newBegin[k] + nonzeros;
1461  newBegin[k+1UL] = newBegin[k] + total;
1462  }
1463  newEnd [i] = newBegin[i] + ( end_[i] - begin_[i] ) + 1;
1464  newBegin[i+1UL] = newBegin[i] + ( begin_[i+1] - begin_[i] ) + 1;
1465  for( size_t k=i+1UL; k<m_; ++k ) {
1466  const size_t nonzeros( end_[k] - begin_[k] );
1467  const size_t total( begin_[k+1UL] - begin_[k] );
1468  newEnd [k] = newBegin[k] + nonzeros;
1469  newBegin[k+1UL] = newBegin[k] + total;
1470  }
1471 
1472  newEnd[m_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
1473 
1474  Iterator tmp = std::copy( begin_[0UL], pos, newBegin[0UL] );
1475  tmp->value_ = value;
1476  tmp->index_ = j;
1477  std::copy( pos, end_[m_-1UL], tmp+1UL );
1478 
1479  std::swap( newBegin, begin_ );
1480  end_ = newEnd;
1481  deallocate( newBegin[0UL] );
1482  delete [] newBegin;
1483 
1484  return tmp;
1485  }
1486 }
1487 //*************************************************************************************************
1488 
1489 
1490 //*************************************************************************************************
1499 template< typename Type // Data type of the sparse matrix
1500  , bool SO > // Storage order
1501 inline void CompressedMatrix<Type,SO>::erase( size_t i, size_t j )
1502 {
1503  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1504  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1505 
1506  const Iterator pos( find( i, j ) );
1507  if( pos != end_[i] )
1508  end_[i] = std::copy( pos+1, end_[i], pos );
1509 }
1510 //*************************************************************************************************
1511 
1512 
1513 //*************************************************************************************************
1524 template< typename Type // Data type of the sparse matrix
1525  , bool SO > // Storage order
1528 {
1529  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1530  BLAZE_USER_ASSERT( pos >= begin_[i] && pos <= end_[i], "Invalid compressed matrix iterator" );
1531 
1532  if( pos != end_[i] )
1533  end_[i] = std::copy( pos+1, end_[i], pos );
1534 
1535  return pos;
1536 }
1537 //*************************************************************************************************
1538 
1539 
1540 //*************************************************************************************************
1552 template< typename Type // Data type of the sparse matrix
1553  , bool SO > // Storage order
1556 {
1557  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1558  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
1559  BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i], "Invalid compressed matrix iterator" );
1560  BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i], "Invalid compressed matrix iterator" );
1561 
1562  if( first != last )
1563  end_[i] = std::copy( last, end_[i], first );
1564 
1565  return first;
1566 }
1567 //*************************************************************************************************
1568 
1569 
1570 //*************************************************************************************************
1585 template< typename Type // Data type of the sparse matrix
1586  , bool SO > // Storage order
1587 void CompressedMatrix<Type,SO>::resize( size_t m, size_t n, bool preserve )
1588 {
1589  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1590  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1591 
1592  if( m == m_ && n == n_ ) return;
1593 
1594  if( m > capacity_ )
1595  {
1596  Iterator* newBegin( new Iterator[2UL*m+2UL] );
1597  Iterator* newEnd ( newBegin+m+1UL );
1598 
1599  newBegin[0UL] = begin_[0UL];
1600 
1601  if( preserve ) {
1602  for( size_t i=0UL; i<m_; ++i ) {
1603  newEnd [i] = end_ [i];
1604  newBegin[i+1UL] = begin_[i+1UL];
1605  }
1606  for( size_t i=m_; i<m; ++i ) {
1607  newBegin[i+1UL] = newEnd[i] = begin_[m_];
1608  }
1609  }
1610  else {
1611  for( size_t i=0UL; i<m; ++i ) {
1612  newBegin[i+1UL] = newEnd[i] = begin_[0UL];
1613  }
1614  }
1615 
1616  newEnd[m] = end_[m_];
1617 
1618  std::swap( newBegin, begin_ );
1619  delete [] newBegin;
1620 
1621  end_ = newEnd;
1622  capacity_ = m;
1623  }
1624  else if( m > m_ )
1625  {
1626  end_[m] = end_[m_];
1627 
1628  if( !preserve ) {
1629  for( size_t i=0UL; i<m_; ++i )
1630  end_[i] = begin_[i];
1631  }
1632 
1633  for( size_t i=m_; i<m; ++i )
1634  begin_[i+1UL] = end_[i] = begin_[m_];
1635  }
1636  else
1637  {
1638  if( preserve ) {
1639  for( size_t i=0UL; i<m; ++i )
1640  end_[i] = lowerBound( i, n );
1641  }
1642  else {
1643  for( size_t i=0UL; i<m; ++i )
1644  end_[i] = begin_[i];
1645  }
1646 
1647  end_[m] = end_[m_];
1648  }
1649 
1650  m_ = m;
1651  n_ = n;
1652 
1653  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1654  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1655 }
1656 //*************************************************************************************************
1657 
1658 
1659 //*************************************************************************************************
1669 template< typename Type // Data type of the sparse matrix
1670  , bool SO > // Storage order
1671 inline void CompressedMatrix<Type,SO>::reserve( size_t nonzeros )
1672 {
1673  if( nonzeros > capacity() )
1674  reserveElements( nonzeros );
1675 }
1676 //*************************************************************************************************
1677 
1678 
1679 //*************************************************************************************************
1693 template< typename Type // Data type of the sparse matrix
1694  , bool SO > // Storage order
1695 void CompressedMatrix<Type,SO>::reserve( size_t i, size_t nonzeros )
1696 {
1697  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1698 
1699  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1700  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1701 
1702  const size_t current( capacity(i) );
1703 
1704  if( current >= nonzeros ) return;
1705 
1706  const ptrdiff_t additional( nonzeros - current );
1707 
1708  if( end_[m_] - begin_[m_] < additional )
1709  {
1710  const size_t newCapacity( begin_[m_] - begin_[0UL] + additional );
1711  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
1712 
1713  Iterator* newBegin( new Iterator[2UL*m_+2UL] );
1714  Iterator* newEnd ( newBegin+m_+1UL );
1715 
1716  newBegin[0UL] = allocate<Element>( newCapacity );
1717  newEnd [m_ ] = newBegin[0UL]+newCapacity;
1718 
1719  for( size_t k=0UL; k<i; ++k ) {
1720  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
1721  newBegin[k+1UL] = newBegin[k] + capacity(k);
1722  }
1723  newEnd [i ] = std::copy( begin_[i], end_[i], newBegin[i] );
1724  newBegin[i+1UL] = newBegin[i] + nonzeros;
1725  for( size_t k=i+1UL; k<m_; ++k ) {
1726  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
1727  newBegin[k+1UL] = newBegin[k] + capacity(k);
1728  }
1729 
1730  BLAZE_INTERNAL_ASSERT( newBegin[m_] == newEnd[m_], "Invalid pointer calculations" );
1731 
1732  std::swap( newBegin, begin_ );
1733  deallocate( newBegin[0UL] );
1734  delete [] newBegin;
1735  end_ = newEnd;
1736  capacity_ = m_;
1737  }
1738  else
1739  {
1740  begin_[m_] += additional;
1741  for( size_t j=m_-1UL; j>i; --j ) {
1742  begin_[j] = std::copy_backward( begin_[j], end_[j], end_[j]+additional );
1743  end_ [j] += additional;
1744  }
1745  }
1746 
1747  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1748  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1749 }
1750 //*************************************************************************************************
1751 
1752 
1753 //*************************************************************************************************
1763 template< typename Type // Data type of the sparse matrix
1764  , bool SO > // Storage order
1766 {
1767  for( size_t i=0UL; i<m_; ++i )
1768  trim( i );
1769 }
1770 //*************************************************************************************************
1771 
1772 
1773 //*************************************************************************************************
1784 template< typename Type // Data type of the sparse matrix
1785  , bool SO > // Storage order
1786 inline void CompressedMatrix<Type,SO>::trim( size_t i )
1787 {
1788  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1789 
1790  if( i < ( m_ - 1UL ) )
1791  end_[i+1] = std::copy( begin_[i+1], end_[i+1], end_[i] );
1792  begin_[i+1] = end_[i];
1793 }
1794 //*************************************************************************************************
1795 
1796 
1797 //*************************************************************************************************
1802 template< typename Type // Data type of the sparse matrix
1803  , bool SO > // Storage order
1805 {
1806  CompressedMatrix tmp( trans( *this ) );
1807  swap( tmp );
1808  return *this;
1809 }
1810 //*************************************************************************************************
1811 
1812 
1813 //*************************************************************************************************
1818 template< typename Type // Data type of the sparse matrix
1819  , bool SO > // Storage order
1821 {
1822  CompressedMatrix tmp( ctrans( *this ) );
1823  swap( tmp );
1824  return *this;
1825 }
1826 //*************************************************************************************************
1827 
1828 
1829 //*************************************************************************************************
1835 template< typename Type // Data type of the sparse matrix
1836  , bool SO > // Storage order
1837 template< typename Other > // Data type of the scalar value
1839 {
1840  for( size_t i=0UL; i<m_; ++i )
1841  for( Iterator element=begin_[i]; element!=end_[i]; ++element )
1842  element->value_ *= scalar;
1843 
1844  return *this;
1845 }
1846 //*************************************************************************************************
1847 
1848 
1849 //*************************************************************************************************
1855 template< typename Type // Data type of the sparse matrix
1856  , bool SO > // Storage order
1857 template< typename Other > // Data type of the scalar value
1859 {
1860  const size_t size( blaze::min( m_, n_ ) );
1861 
1862  for( size_t i=0UL; i<size; ++i ) {
1863  Iterator pos = lowerBound( i, i );
1864  if( pos != end_[i] && pos->index_ == i )
1865  pos->value_ *= scalar;
1866  }
1867 
1868  return *this;
1869 }
1870 //*************************************************************************************************
1871 
1872 
1873 //*************************************************************************************************
1880 template< typename Type // Data type of the sparse matrix
1881  , bool SO > // Storage order
1882 inline void CompressedMatrix<Type,SO>::swap( CompressedMatrix& sm ) /* throw() */
1883 {
1884  std::swap( m_, sm.m_ );
1885  std::swap( n_, sm.n_ );
1886  std::swap( capacity_, sm.capacity_ );
1887  std::swap( begin_, sm.begin_ );
1888  std::swap( end_ , sm.end_ );
1889 }
1890 //*************************************************************************************************
1891 
1892 
1893 //*************************************************************************************************
1901 template< typename Type // Data type of the sparse matrix
1902  , bool SO > // Storage order
1904 {
1905  size_t nonzeros( 2UL*capacity()+1UL );
1906  nonzeros = blaze::max( nonzeros, 7UL );
1907 
1908  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
1909 
1910  return nonzeros;
1911 }
1912 //*************************************************************************************************
1913 
1914 
1915 //*************************************************************************************************
1921 template< typename Type // Data type of the sparse matrix
1922  , bool SO > // Storage order
1924 {
1925  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1926  Iterator* newEnd = newBegin+capacity_+1UL;
1927 
1928  newBegin[0UL] = allocate<Element>( nonzeros );
1929 
1930  for( size_t k=0UL; k<m_; ++k ) {
1931  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid row pointers" );
1932  newEnd [k] = std::copy( begin_[k], end_[k], newBegin[k] );
1933  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
1934  }
1935 
1936  newEnd[m_] = newBegin[0UL]+nonzeros;
1937 
1938  std::swap( newBegin, begin_ );
1939  deallocate( newBegin[0UL] );
1940  delete [] newBegin;
1941  end_ = newEnd;
1942 }
1943 //*************************************************************************************************
1944 
1945 
1946 
1947 
1948 //=================================================================================================
1949 //
1950 // LOOKUP FUNCTIONS
1951 //
1952 //=================================================================================================
1953 
1954 //*************************************************************************************************
1969 template< typename Type // Data type of the sparse matrix
1970  , bool SO > // Storage order
1972  CompressedMatrix<Type,SO>::find( size_t i, size_t j )
1973 {
1974  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
1975 }
1976 //*************************************************************************************************
1977 
1978 
1979 //*************************************************************************************************
1994 template< typename Type // Data type of the sparse matrix
1995  , bool SO > // Storage order
1997  CompressedMatrix<Type,SO>::find( size_t i, size_t j ) const
1998 {
1999  const ConstIterator pos( lowerBound( i, j ) );
2000  if( pos != end_[i] && pos->index_ == j )
2001  return pos;
2002  else return end_[i];
2003 }
2004 //*************************************************************************************************
2005 
2006 
2007 //*************************************************************************************************
2022 template< typename Type // Data type of the sparse matrix
2023  , bool SO > // Storage order
2026 {
2027  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
2028 }
2029 //*************************************************************************************************
2030 
2031 
2032 //*************************************************************************************************
2047 template< typename Type // Data type of the sparse matrix
2048  , bool SO > // Storage order
2050  CompressedMatrix<Type,SO>::lowerBound( size_t i, size_t j ) const
2051 {
2052  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2053  return std::lower_bound( begin_[i], end_[i], j, FindIndex() );
2054 }
2055 //*************************************************************************************************
2056 
2057 
2058 //*************************************************************************************************
2073 template< typename Type // Data type of the sparse matrix
2074  , bool SO > // Storage order
2077 {
2078  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
2079 }
2080 //*************************************************************************************************
2081 
2082 
2083 //*************************************************************************************************
2098 template< typename Type // Data type of the sparse matrix
2099  , bool SO > // Storage order
2101  CompressedMatrix<Type,SO>::upperBound( size_t i, size_t j ) const
2102 {
2103  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2104  return std::upper_bound( begin_[i], end_[i], j, FindIndex() );
2105 }
2106 //*************************************************************************************************
2107 
2108 
2109 
2110 
2111 //=================================================================================================
2112 //
2113 // LOW-LEVEL UTILITY FUNCTIONS
2114 //
2115 //=================================================================================================
2116 
2117 //*************************************************************************************************
2161 template< typename Type // Data type of the sparse matrix
2162  , bool SO > // Storage order
2163 inline void CompressedMatrix<Type,SO>::append( size_t i, size_t j, const Type& value, bool check )
2164 {
2165  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2166  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
2167  BLAZE_USER_ASSERT( end_[i] < end_[m_], "Not enough reserved capacity left" );
2168  BLAZE_USER_ASSERT( begin_[i] == end_[i] || j > ( end_[i]-1UL )->index_, "Index is not strictly increasing" );
2169 
2170  end_[i]->value_ = value;
2171 
2172  if( !check || !isDefault( end_[i]->value_ ) ) {
2173  end_[i]->index_ = j;
2174  ++end_[i];
2175  }
2176 }
2177 //*************************************************************************************************
2178 
2179 
2180 //*************************************************************************************************
2193 template< typename Type // Data type of the sparse matrix
2194  , bool SO > // Storage order
2196 {
2197  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2198 
2199  begin_[i+1UL] = end_[i];
2200  if( i != m_-1UL )
2201  end_[i+1UL] = end_[i];
2202 }
2203 //*************************************************************************************************
2204 
2205 
2206 
2207 
2208 //=================================================================================================
2209 //
2210 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2211 //
2212 //=================================================================================================
2213 
2214 //*************************************************************************************************
2224 template< typename Type // Data type of the sparse matrix
2225  , bool SO > // Storage order
2226 template< typename Other > // Data type of the foreign expression
2227 inline bool CompressedMatrix<Type,SO>::canAlias( const Other* alias ) const
2228 {
2229  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2230 }
2231 //*************************************************************************************************
2232 
2233 
2234 //*************************************************************************************************
2244 template< typename Type // Data type of the sparse matrix
2245  , bool SO > // Storage order
2246 template< typename Other > // Data type of the foreign expression
2247 inline bool CompressedMatrix<Type,SO>::isAliased( const Other* alias ) const
2248 {
2249  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2250 }
2251 //*************************************************************************************************
2252 
2253 
2254 //*************************************************************************************************
2264 template< typename Type // Data type of the sparse matrix
2265  , bool SO > // Storage order
2267 {
2268  return false;
2269 }
2270 //*************************************************************************************************
2271 
2272 
2273 //*************************************************************************************************
2284 template< typename Type // Data type of the sparse matrix
2285  , bool SO > // Storage order
2286 template< typename MT // Type of the right-hand side dense matrix
2287  , bool SO2 > // Storage order of the right-hand side dense matrix
2289 {
2290  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2291  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2292 
2293  size_t nonzeros( 0UL );
2294 
2295  for( size_t i=1UL; i<=m_; ++i )
2296  begin_[i] = end_[i] = end_[m_];
2297 
2298  for( size_t i=0UL; i<m_; ++i )
2299  {
2300  begin_[i] = end_[i] = begin_[0UL]+nonzeros;
2301 
2302  const size_t jbegin( ( IsUpper<MT>::value )
2303  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2304  :( 0UL ) );
2305  const size_t jend ( ( IsLower<MT>::value )
2306  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2307  :( n_ ) );
2308 
2309  for( size_t j=jbegin; j<jend; ++j )
2310  {
2311  if( nonzeros == capacity() ) {
2312  reserveElements( extendCapacity() );
2313  for( size_t k=i+1UL; k<=m_; ++k )
2314  begin_[k] = end_[k] = end_[m_];
2315  }
2316 
2317  end_[i]->value_ = (~rhs)(i,j);
2318 
2319  if( !isDefault( end_[i]->value_ ) ) {
2320  end_[i]->index_ = j;
2321  ++end_[i];
2322  ++nonzeros;
2323  }
2324  }
2325  }
2326 
2327  begin_[m_] = begin_[0UL]+nonzeros;
2328 }
2329 //*************************************************************************************************
2330 
2331 
2332 //*************************************************************************************************
2343 template< typename Type // Data type of the sparse matrix
2344  , bool SO > // Storage order
2345 template< typename MT > // Type of the right-hand side sparse matrix
2347 {
2348  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2349  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2350  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2351  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
2352 
2353  if( m_ == 0UL || begin_[0] == NULL )
2354  return;
2355 
2356  for( size_t i=0UL; i<m_; ++i ) {
2357  begin_[i+1UL] = end_[i] = std::copy( (~rhs).begin(i), (~rhs).end(i), begin_[i] );
2358  }
2359 }
2360 //*************************************************************************************************
2361 
2362 
2363 //*************************************************************************************************
2374 template< typename Type // Data type of the sparse matrix
2375  , bool SO > // Storage order
2376 template< typename MT > // Type of the right-hand side sparse matrix
2378 {
2380 
2381  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2382  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2383  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2384  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
2385 
2386  typedef typename MT::ConstIterator RhsIterator;
2387 
2388  // Counting the number of elements per row
2389  std::vector<size_t> rowLengths( m_, 0UL );
2390  for( size_t j=0UL; j<n_; ++j ) {
2391  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2392  ++rowLengths[element->index()];
2393  }
2394 
2395  // Resizing the sparse matrix
2396  for( size_t i=0UL; i<m_; ++i ) {
2397  begin_[i+1UL] = end_[i+1UL] = begin_[i] + rowLengths[i];
2398  }
2399 
2400  // Appending the elements to the rows of the sparse matrix
2401  for( size_t j=0UL; j<n_; ++j ) {
2402  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2403  append( element->index(), j, element->value() );
2404  }
2405 }
2406 //*************************************************************************************************
2407 
2408 
2409 //*************************************************************************************************
2420 template< typename Type // Data type of the sparse matrix
2421  , bool SO > // Storage order
2422 template< typename MT // Type of the right-hand side dense matrix
2423  , bool SO2 > // Storage order of the right-hand side dense matrix
2425 {
2426  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2427  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2428 
2429  CompressedMatrix tmp( serial( *this + (~rhs) ) );
2430  swap( tmp );
2431 }
2432 //*************************************************************************************************
2433 
2434 
2435 //*************************************************************************************************
2446 template< typename Type // Data type of the sparse matrix
2447  , bool SO > // Storage order
2448 template< typename MT // Type of the right-hand side sparse matrix
2449  , bool SO2 > // Storage order of the right-hand side sparse matrix
2451 {
2452  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2453  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2454 
2455  CompressedMatrix tmp( serial( *this + (~rhs) ) );
2456  swap( tmp );
2457 }
2458 //*************************************************************************************************
2459 
2460 
2461 //*************************************************************************************************
2472 template< typename Type // Data type of the sparse matrix
2473  , bool SO > // Storage order
2474 template< typename MT // Type of the right-hand side dense matrix
2475  , bool SO2 > // Storage order of the right-hand side dense matrix
2477 {
2478  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2479  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2480 
2481  CompressedMatrix tmp( serial( *this - (~rhs) ) );
2482  swap( tmp );
2483 }
2484 //*************************************************************************************************
2485 
2486 
2487 //*************************************************************************************************
2498 template< typename Type // Data type of the sparse matrix
2499  , bool SO > // Storage order
2500 template< typename MT // Type of the right-hand side sparse matrix
2501  , bool SO2 > // Storage order of the right-hand sparse matrix
2503 {
2504  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2505  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2506 
2507  CompressedMatrix tmp( serial( *this - (~rhs) ) );
2508  swap( tmp );
2509 }
2510 //*************************************************************************************************
2511 
2512 
2513 
2514 
2515 
2516 
2517 
2518 
2519 //=================================================================================================
2520 //
2521 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2522 //
2523 //=================================================================================================
2524 
2525 //*************************************************************************************************
2533 template< typename Type > // Data type of the sparse matrix
2534 class CompressedMatrix<Type,true> : public SparseMatrix< CompressedMatrix<Type,true>, true >
2535 {
2536  private:
2537  //**Type definitions****************************************************************************
2539  //**********************************************************************************************
2540 
2541  //**Private class Element***********************************************************************
2545  struct Element : public ElementBase
2546  {
2547  // This operator is required due to a bug in all versions of the the MSVC compiler.
2548  // A simple 'using ElementBase::operator=;' statement results in ambiguity problems.
2549  template< typename Other >
2550  inline Element& operator=( const Other& rhs )
2551  {
2552  ElementBase::operator=( rhs );
2553  return *this;
2554  }
2555 
2556  friend class CompressedMatrix;
2557  };
2559  //**********************************************************************************************
2560 
2561  //**Private class FindIndex*********************************************************************
2565  struct FindIndex : public std::binary_function<Element,size_t,bool>
2566  {
2567  inline bool operator()( const Element& element, size_t index ) const {
2568  return element.index() < index;
2569  }
2570  inline bool operator()( size_t index, const Element& element ) const {
2571  return index < element.index();
2572  }
2573  inline bool operator()( const Element& element1, const Element& element2 ) const {
2574  return element1.index() < element2.index();
2575  }
2576  };
2578  //**********************************************************************************************
2579 
2580  public:
2581  //**Type definitions****************************************************************************
2583  typedef This ResultType;
2586  typedef Type ElementType;
2587  typedef const Type& ReturnType;
2588  typedef const This& CompositeType;
2590  typedef const Type& ConstReference;
2591  typedef Element* Iterator;
2592  typedef const Element* ConstIterator;
2593  //**********************************************************************************************
2594 
2595  //**Rebind struct definition********************************************************************
2598  template< typename ET > // Data type of the other matrix
2599  struct Rebind {
2601  };
2602  //**********************************************************************************************
2603 
2604  //**Compilation flags***************************************************************************
2606 
2609  enum { smpAssignable = !IsSMPAssignable<Type>::value };
2610  //**********************************************************************************************
2611 
2612  //**Constructors********************************************************************************
2615  explicit inline CompressedMatrix();
2616  explicit inline CompressedMatrix( size_t m, size_t n );
2617  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
2618  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
2619  inline CompressedMatrix( const CompressedMatrix& sm );
2620  template< typename MT, bool SO > inline CompressedMatrix( const DenseMatrix<MT,SO>& dm );
2621  template< typename MT, bool SO > inline CompressedMatrix( const SparseMatrix<MT,SO>& sm );
2623  //**********************************************************************************************
2624 
2625  //**Destructor**********************************************************************************
2628  inline ~CompressedMatrix();
2630  //**********************************************************************************************
2631 
2632  //**Data access functions***********************************************************************
2635  inline Reference operator()( size_t i, size_t j );
2636  inline ConstReference operator()( size_t i, size_t j ) const;
2637  inline Reference at( size_t i, size_t j );
2638  inline ConstReference at( size_t i, size_t j ) const;
2639  inline Iterator begin ( size_t i );
2640  inline ConstIterator begin ( size_t i ) const;
2641  inline ConstIterator cbegin( size_t i ) const;
2642  inline Iterator end ( size_t i );
2643  inline ConstIterator end ( size_t i ) const;
2644  inline ConstIterator cend ( size_t i ) const;
2646  //**********************************************************************************************
2647 
2648  //**Assignment operators************************************************************************
2651  inline CompressedMatrix& operator= ( const CompressedMatrix& rhs );
2652  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO>& rhs );
2653  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO>& rhs );
2654  template< typename MT, bool SO > inline CompressedMatrix& operator+=( const Matrix<MT,SO>& rhs );
2655  template< typename MT, bool SO > inline CompressedMatrix& operator-=( const Matrix<MT,SO>& rhs );
2656  template< typename MT, bool SO > inline CompressedMatrix& operator*=( const Matrix<MT,SO>& rhs );
2657 
2658  template< typename Other >
2659  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
2660  operator*=( Other rhs );
2661 
2662  template< typename Other >
2663  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
2664  operator/=( Other rhs );
2666  //**********************************************************************************************
2667 
2668  //**Utility functions***************************************************************************
2671  inline size_t rows() const;
2672  inline size_t columns() const;
2673  inline size_t capacity() const;
2674  inline size_t capacity( size_t j ) const;
2675  inline size_t nonZeros() const;
2676  inline size_t nonZeros( size_t j ) const;
2677  inline void reset();
2678  inline void reset( size_t j );
2679  inline void clear();
2680  inline Iterator set ( size_t i, size_t j, const Type& value );
2681  inline Iterator insert ( size_t i, size_t j, const Type& value );
2682  inline void erase ( size_t i, size_t j );
2683  inline Iterator erase ( size_t j, Iterator pos );
2684  inline Iterator erase ( size_t j, Iterator first, Iterator last );
2685  void resize ( size_t m, size_t n, bool preserve=true );
2686  inline void reserve( size_t nonzeros );
2687  void reserve( size_t j, size_t nonzeros );
2688  inline void trim ();
2689  inline void trim ( size_t j );
2690  inline CompressedMatrix& transpose();
2691  inline CompressedMatrix& ctranspose();
2692  template< typename Other > inline CompressedMatrix& scale( const Other& scalar );
2693  template< typename Other > inline CompressedMatrix& scaleDiagonal( Other scalar );
2694  inline void swap( CompressedMatrix& sm ) /* throw() */;
2696  //**********************************************************************************************
2697 
2698  //**Lookup functions****************************************************************************
2701  inline Iterator find ( size_t i, size_t j );
2702  inline ConstIterator find ( size_t i, size_t j ) const;
2703  inline Iterator lowerBound( size_t i, size_t j );
2704  inline ConstIterator lowerBound( size_t i, size_t j ) const;
2705  inline Iterator upperBound( size_t i, size_t j );
2706  inline ConstIterator upperBound( size_t i, size_t j ) const;
2708  //**********************************************************************************************
2709 
2710  //**Low-level utility functions*****************************************************************
2713  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
2714  inline void finalize( size_t j );
2716  //**********************************************************************************************
2717 
2718  //**Expression template evaluation functions****************************************************
2721  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2722  template< typename Other > inline bool isAliased( const Other* alias ) const;
2723 
2724  inline bool canSMPAssign() const;
2725 
2726  template< typename MT, bool SO > inline void assign ( const DenseMatrix<MT,SO>& rhs );
2727  template< typename MT > inline void assign ( const SparseMatrix<MT,true>& rhs );
2728  template< typename MT > inline void assign ( const SparseMatrix<MT,false>& rhs );
2729  template< typename MT, bool SO > inline void addAssign( const DenseMatrix<MT,SO>& rhs );
2730  template< typename MT, bool SO > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
2731  template< typename MT, bool SO > inline void subAssign( const DenseMatrix<MT,SO>& rhs );
2732  template< typename MT, bool SO > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
2734  //**********************************************************************************************
2735 
2736  private:
2737  //**Utility functions***************************************************************************
2740  Iterator insert( Iterator pos, size_t i, size_t j, const Type& value );
2741  inline size_t extendCapacity() const;
2742  void reserveElements( size_t nonzeros );
2744  //**********************************************************************************************
2745 
2746  //**Member variables****************************************************************************
2749  size_t m_;
2750  size_t n_;
2751  size_t capacity_;
2752  Iterator* begin_;
2753  Iterator* end_;
2754 
2755  static const Type zero_;
2756 
2757  //**********************************************************************************************
2758 
2759  //**Compile time checks*************************************************************************
2765  BLAZE_CONSTRAINT_MUST_HAVE_SAME_SIZE ( ElementBase, Element );
2767  //**********************************************************************************************
2768 };
2770 //*************************************************************************************************
2771 
2772 
2773 
2774 
2775 //=================================================================================================
2776 //
2777 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
2778 //
2779 //=================================================================================================
2780 
2781 template< typename Type >
2782 const Type CompressedMatrix<Type,true>::zero_ = Type();
2783 
2784 
2785 
2786 
2787 //=================================================================================================
2788 //
2789 // CONSTRUCTORS
2790 //
2791 //=================================================================================================
2792 
2793 //*************************************************************************************************
2797 template< typename Type > // Data type of the sparse matrix
2799  : m_ ( 0UL ) // The current number of rows of the sparse matrix
2800  , n_ ( 0UL ) // The current number of columns of the sparse matrix
2801  , capacity_( 0UL ) // The current capacity of the pointer array
2802  , begin_( new Iterator[2UL] ) // Pointers to the first non-zero element of each column
2803  , end_ ( begin_+1UL ) // Pointers one past the last non-zero element of each column
2804 {
2805  begin_[0UL] = end_[0UL] = NULL;
2806 }
2808 //*************************************************************************************************
2809 
2810 
2811 //*************************************************************************************************
2820 template< typename Type > // Data type of the sparse matrix
2821 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n )
2822  : m_ ( m ) // The current number of rows of the sparse matrix
2823  , n_ ( n ) // The current number of columns of the sparse matrix
2824  , capacity_( n ) // The current capacity of the pointer array
2825  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
2826  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
2827 {
2828  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
2829  begin_[j] = NULL;
2830 }
2832 //*************************************************************************************************
2833 
2834 
2835 //*************************************************************************************************
2845 template< typename Type > // Data type of the sparse matrix
2846 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
2847  : m_ ( m ) // The current number of rows of the sparse matrix
2848  , n_ ( n ) // The current number of columns of the sparse matrix
2849  , capacity_( n ) // The current capacity of the pointer array
2850  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
2851  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
2852 {
2853  begin_[0UL] = allocate<Element>( nonzeros );
2854  for( size_t j=1UL; j<(2UL*n_+1UL); ++j )
2855  begin_[j] = begin_[0UL];
2856  end_[n_] = begin_[0UL]+nonzeros;
2857 }
2859 //*************************************************************************************************
2860 
2861 
2862 //*************************************************************************************************
2873 template< typename Type > // Data type of the sparse matrix
2874 CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
2875  : m_ ( m ) // The current number of rows of the sparse matrix
2876  , n_ ( n ) // The current number of columns of the sparse matrix
2877  , capacity_( n ) // The current capacity of the pointer array
2878  , begin_( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2879  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2880 {
2881  BLAZE_USER_ASSERT( nonzeros.size() == n, "Size of capacity vector and number of columns don't match" );
2882 
2883  size_t newCapacity( 0UL );
2884  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
2885  newCapacity += *it;
2886 
2887  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
2888  for( size_t j=0UL; j<n_; ++j ) {
2889  begin_[j+1UL] = end_[j+1UL] = begin_[j] + nonzeros[j];
2890  }
2891 }
2893 //*************************************************************************************************
2894 
2895 
2896 //*************************************************************************************************
2902 template< typename Type > // Data type of the sparse matrix
2903 inline CompressedMatrix<Type,true>::CompressedMatrix( const CompressedMatrix& sm )
2904  : m_ ( sm.m_ ) // The current number of rows of the sparse matrix
2905  , n_ ( sm.n_ ) // The current number of columns of the sparse matrix
2906  , capacity_( sm.n_ ) // The current capacity of the pointer array
2907  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2908  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2909 {
2910  const size_t nonzeros( sm.nonZeros() );
2911 
2912  begin_[0UL] = allocate<Element>( nonzeros );
2913  for( size_t j=0UL; j<n_; ++j )
2914  begin_[j+1UL] = end_[j] = std::copy( sm.begin(j), sm.end(j), begin_[j] );
2915  end_[n_] = begin_[0UL]+nonzeros;
2916 }
2918 //*************************************************************************************************
2919 
2920 
2921 //*************************************************************************************************
2927 template< typename Type > // Data type of the sparse matrix
2928 template< typename MT // Type of the foreign dense matrix
2929  , bool SO > // Storage order of the foreign dense matrix
2930 inline CompressedMatrix<Type,true>::CompressedMatrix( const DenseMatrix<MT,SO>& dm )
2931  : m_ ( (~dm).rows() ) // The current number of rows of the sparse matrix
2932  , n_ ( (~dm).columns() ) // The current number of columns of the sparse matrix
2933  , capacity_( n_ ) // The current capacity of the pointer array
2934  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2935  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2936 {
2937  using blaze::assign;
2938 
2939  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
2940  begin_[j] = NULL;
2941 
2942  assign( *this, ~dm );
2943 }
2945 //*************************************************************************************************
2946 
2947 
2948 //*************************************************************************************************
2954 template< typename Type > // Data type of the sparse matrix
2955 template< typename MT // Type of the foreign sparse matrix
2956  , bool SO > // Storage order of the foreign sparse matrix
2957 inline CompressedMatrix<Type,true>::CompressedMatrix( const SparseMatrix<MT,SO>& sm )
2958  : m_ ( (~sm).rows() ) // The current number of rows of the sparse matrix
2959  , n_ ( (~sm).columns() ) // The current number of columns of the sparse matrix
2960  , capacity_( n_ ) // The current capacity of the pointer array
2961  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2962  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2963 {
2964  using blaze::assign;
2965 
2966  const size_t nonzeros( (~sm).nonZeros() );
2967 
2968  begin_[0UL] = allocate<Element>( nonzeros );
2969  for( size_t j=0UL; j<n_; ++j )
2970  begin_[j+1UL] = end_[j] = begin_[0UL];
2971  end_[n_] = begin_[0UL]+nonzeros;
2972 
2973  assign( *this, ~sm );
2974 }
2976 //*************************************************************************************************
2977 
2978 
2979 
2980 
2981 //=================================================================================================
2982 //
2983 // DESTRUCTOR
2984 //
2985 //=================================================================================================
2986 
2987 //*************************************************************************************************
2991 template< typename Type > // Data type of the sparse matrix
2992 inline CompressedMatrix<Type,true>::~CompressedMatrix()
2993 {
2994  deallocate( begin_[0UL] );
2995  delete [] begin_;
2996 }
2998 //*************************************************************************************************
2999 
3000 
3001 
3002 
3003 //=================================================================================================
3004 //
3005 // DATA ACCESS FUNCTIONS
3006 //
3007 //=================================================================================================
3008 
3009 //*************************************************************************************************
3017 template< typename Type > // Data type of the sparse matrix
3019  CompressedMatrix<Type,true>::operator()( size_t i, size_t j )
3020 {
3021  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3022  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3023 
3024  return Reference( *this, i, j );
3025 }
3027 //*************************************************************************************************
3028 
3029 
3030 //*************************************************************************************************
3038 template< typename Type > // Data type of the sparse matrix
3040  CompressedMatrix<Type,true>::operator()( size_t i, size_t j ) const
3041 {
3042  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3043  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3044 
3045  const ConstIterator pos( lowerBound( i, j ) );
3046 
3047  if( pos == end_[j] || pos->index_ != i )
3048  return zero_;
3049  else
3050  return pos->value_;
3051 }
3053 //*************************************************************************************************
3054 
3055 
3056 //*************************************************************************************************
3068 template< typename Type > // Data type of the sparse matrix
3070  CompressedMatrix<Type,true>::at( size_t i, size_t j )
3071 {
3072  if( i >= m_ ) {
3073  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3074  }
3075  if( j >= n_ ) {
3076  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3077  }
3078  return (*this)(i,j);
3079 }
3081 //*************************************************************************************************
3082 
3083 
3084 //*************************************************************************************************
3096 template< typename Type > // Data type of the sparse matrix
3098  CompressedMatrix<Type,true>::at( size_t i, size_t j ) const
3099 {
3100  if( i >= m_ ) {
3101  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3102  }
3103  if( j >= n_ ) {
3104  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3105  }
3106  return (*this)(i,j);
3107 }
3109 //*************************************************************************************************
3110 
3111 
3112 //*************************************************************************************************
3119 template< typename Type > // Data type of the sparse matrix
3121  CompressedMatrix<Type,true>::begin( size_t j )
3122 {
3123  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
3124  return begin_[j];
3125 }
3127 //*************************************************************************************************
3128 
3129 
3130 //*************************************************************************************************
3137 template< typename Type > // Data type of the sparse matrix
3139  CompressedMatrix<Type,true>::begin( size_t j ) const
3140 {
3141  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
3142  return begin_[j];
3143 }
3145 //*************************************************************************************************
3146 
3147 
3148 //*************************************************************************************************
3155 template< typename Type > // Data type of the sparse matrix
3157  CompressedMatrix<Type,true>::cbegin( size_t j ) const
3158 {
3159  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
3160  return begin_[j];
3161 }
3163 //*************************************************************************************************
3164 
3165 
3166 //*************************************************************************************************
3173 template< typename Type > // Data type of the sparse matrix
3175  CompressedMatrix<Type,true>::end( size_t j )
3176 {
3177  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
3178  return end_[j];
3179 }
3181 //*************************************************************************************************
3182 
3183 
3184 //*************************************************************************************************
3191 template< typename Type > // Data type of the sparse matrix
3193  CompressedMatrix<Type,true>::end( size_t j ) const
3194 {
3195  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
3196  return end_[j];
3197 }
3199 //*************************************************************************************************
3200 
3201 
3202 //*************************************************************************************************
3209 template< typename Type > // Data type of the sparse matrix
3211  CompressedMatrix<Type,true>::cend( size_t j ) const
3212 {
3213  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
3214  return end_[j];
3215 }
3217 //*************************************************************************************************
3218 
3219 
3220 
3221 
3222 //=================================================================================================
3223 //
3224 // ASSIGNMENT OPERATORS
3225 //
3226 //=================================================================================================
3227 
3228 //*************************************************************************************************
3238 template< typename Type > // Data type of the sparse matrix
3239 inline CompressedMatrix<Type,true>&
3240  CompressedMatrix<Type,true>::operator=( const CompressedMatrix& rhs )
3241 {
3242  if( &rhs == this ) return *this;
3243 
3244  const size_t nonzeros( rhs.nonZeros() );
3245 
3246  if( rhs.n_ > capacity_ || nonzeros > capacity() )
3247  {
3248  Iterator* newBegin( new Iterator[2UL*rhs.n_+2UL] );
3249  Iterator* newEnd ( newBegin+(rhs.n_+1UL) );
3250 
3251  newBegin[0UL] = allocate<Element>( nonzeros );
3252  for( size_t j=0UL; j<rhs.n_; ++j ) {
3253  newBegin[j+1UL] = newEnd[j] = std::copy( rhs.begin_[j], rhs.end_[j], newBegin[j] );
3254  }
3255  newEnd[rhs.n_] = newBegin[0UL]+nonzeros;
3256 
3257  std::swap( begin_, newBegin );
3258  end_ = newEnd;
3259  deallocate( newBegin[0UL] );
3260  delete [] newBegin;
3261  capacity_ = rhs.n_;
3262  }
3263  else {
3264  for( size_t j=0UL; j<rhs.n_; ++j ) {
3265  begin_[j+1UL] = end_[j] = std::copy( rhs.begin_[j], rhs.end_[j], begin_[j] );
3266  }
3267  }
3268 
3269  m_ = rhs.m_;
3270  n_ = rhs.n_;
3271 
3272  return *this;
3273 }
3275 //*************************************************************************************************
3276 
3277 
3278 //*************************************************************************************************
3288 template< typename Type > // Data type of the sparse matrix
3289 template< typename MT // Type of the right-hand side dense matrix
3290  , bool SO > // Storage order of the right-hand side dense matrix
3291 inline CompressedMatrix<Type,true>&
3292  CompressedMatrix<Type,true>::operator=( const DenseMatrix<MT,SO>& rhs )
3293 {
3294  using blaze::assign;
3295 
3296  if( (~rhs).canAlias( this ) ) {
3297  CompressedMatrix tmp( ~rhs );
3298  swap( tmp );
3299  }
3300  else {
3301  resize( (~rhs).rows(), (~rhs).columns(), false );
3302  assign( *this, ~rhs );
3303  }
3304 
3305  return *this;
3306 }
3308 //*************************************************************************************************
3309 
3310 
3311 //*************************************************************************************************
3321 template< typename Type > // Data type of the sparse matrix
3322 template< typename MT // Type of the right-hand side sparse matrix
3323  , bool SO > // Storage order of the right-hand side sparse matrix
3324 inline CompressedMatrix<Type,true>&
3325  CompressedMatrix<Type,true>::operator=( const SparseMatrix<MT,SO>& rhs )
3326 {
3327  using blaze::assign;
3328 
3329  if( (~rhs).canAlias( this ) ||
3330  (~rhs).columns() > capacity_ ||
3331  (~rhs).nonZeros() > capacity() ) {
3332  CompressedMatrix tmp( ~rhs );
3333  swap( tmp );
3334  }
3335  else {
3336  resize( (~rhs).rows(), (~rhs).columns(), false );
3337  reset();
3338  assign( *this, ~rhs );
3339  }
3340 
3341  return *this;
3342 }
3344 //*************************************************************************************************
3345 
3346 
3347 //*************************************************************************************************
3358 template< typename Type > // Data type of the sparse matrix
3359 template< typename MT // Type of the right-hand side matrix
3360  , bool SO > // Storage order of the right-hand side matrix
3361 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator+=( const Matrix<MT,SO>& rhs )
3362 {
3363  using blaze::addAssign;
3364 
3365  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
3366  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3367  }
3368 
3369  addAssign( *this, ~rhs );
3370  return *this;
3371 }
3373 //*************************************************************************************************
3374 
3375 
3376 //*************************************************************************************************
3387 template< typename Type > // Data type of the sparse matrix
3388 template< typename MT // Type of the right-hand side matrix
3389  , bool SO > // Storage order of the right-hand side matrix
3390 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator-=( const Matrix<MT,SO>& rhs )
3391 {
3392  using blaze::subAssign;
3393 
3394  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
3395  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3396  }
3397 
3398  subAssign( *this, ~rhs );
3399  return *this;
3400 }
3402 //*************************************************************************************************
3403 
3404 
3405 //*************************************************************************************************
3416 template< typename Type > // Data type of the sparse matrix
3417 template< typename MT // Type of the right-hand side matrix
3418  , bool SO > // Storage order of the right-hand side matrix
3419 inline CompressedMatrix<Type,true>&
3420  CompressedMatrix<Type,true>::operator*=( const Matrix<MT,SO>& rhs )
3421 {
3422  if( (~rhs).rows() != n_ ) {
3423  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3424  }
3425 
3426  CompressedMatrix tmp( *this * (~rhs) );
3427  swap( tmp );
3428 
3429  return *this;
3430 }
3432 //*************************************************************************************************
3433 
3434 
3435 //*************************************************************************************************
3443 template< typename Type > // Data type of the sparse matrix
3444 template< typename Other > // Data type of the right-hand side scalar
3445 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,true> >::Type&
3446  CompressedMatrix<Type,true>::operator*=( Other rhs )
3447 {
3448  for( size_t j=0UL; j<n_; ++j ) {
3449  const Iterator last( end(j) );
3450  for( Iterator element=begin(j); element!=last; ++element )
3451  element->value_ *= rhs;
3452  }
3453  return *this;
3454 }
3456 //*************************************************************************************************
3457 
3458 
3459 //*************************************************************************************************
3467 template< typename Type > // Data type of the sparse matrix
3468 template< typename Other > // Data type of the right-hand side scalar
3469 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,true> >::Type&
3470  CompressedMatrix<Type,true>::operator/=( Other rhs )
3471 {
3472  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3473 
3474  typedef typename DivTrait<Type,Other>::Type DT;
3475  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
3476 
3477  // Depending on the two involved data types, an integer division is applied or a
3478  // floating point division is selected.
3479  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
3480  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
3481  for( size_t j=0UL; j<n_; ++j ) {
3482  const Iterator last( end(j) );
3483  for( Iterator element=begin(j); element!=last; ++element )
3484  element->value_ *= tmp;
3485  }
3486  }
3487  else {
3488  for( size_t j=0UL; j<n_; ++j ) {
3489  const Iterator last( end(j) );
3490  for( Iterator element=begin(j); element!=last; ++element )
3491  element->value_ /= rhs;
3492  }
3493  }
3494 
3495  return *this;
3496 }
3498 //*************************************************************************************************
3499 
3500 
3501 
3502 
3503 //=================================================================================================
3504 //
3505 // UTILITY FUNCTIONS
3506 //
3507 //=================================================================================================
3508 
3509 //*************************************************************************************************
3515 template< typename Type > // Data type of the sparse matrix
3516 inline size_t CompressedMatrix<Type,true>::rows() const
3517 {
3518  return m_;
3519 }
3521 //*************************************************************************************************
3522 
3523 
3524 //*************************************************************************************************
3530 template< typename Type > // Data type of the sparse matrix
3531 inline size_t CompressedMatrix<Type,true>::columns() const
3532 {
3533  return n_;
3534 }
3536 //*************************************************************************************************
3537 
3538 
3539 //*************************************************************************************************
3545 template< typename Type > // Data type of the sparse matrix
3546 inline size_t CompressedMatrix<Type,true>::capacity() const
3547 {
3548  return end_[n_] - begin_[0UL];
3549 }
3551 //*************************************************************************************************
3552 
3553 
3554 //*************************************************************************************************
3561 template< typename Type > // Data type of the sparse matrix
3562 inline size_t CompressedMatrix<Type,true>::capacity( size_t j ) const
3563 {
3564  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3565  return begin_[j+1UL] - begin_[j];
3566 }
3568 //*************************************************************************************************
3569 
3570 
3571 //*************************************************************************************************
3577 template< typename Type > // Data type of the sparse matrix
3578 inline size_t CompressedMatrix<Type,true>::nonZeros() const
3579 {
3580  size_t nonzeros( 0UL );
3581 
3582  for( size_t j=0UL; j<n_; ++j )
3583  nonzeros += nonZeros( j );
3584 
3585  return nonzeros;
3586 }
3588 //*************************************************************************************************
3589 
3590 
3591 //*************************************************************************************************
3598 template< typename Type > // Data type of the sparse matrix
3599 inline size_t CompressedMatrix<Type,true>::nonZeros( size_t j ) const
3600 {
3601  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3602  return end_[j] - begin_[j];
3603 }
3605 //*************************************************************************************************
3606 
3607 
3608 //*************************************************************************************************
3614 template< typename Type > // Data type of the sparse matrix
3616 {
3617  for( size_t j=0UL; j<n_; ++j )
3618  end_[j] = begin_[j];
3619 }
3621 //*************************************************************************************************
3622 
3623 
3624 //*************************************************************************************************
3634 template< typename Type > // Data type of the sparse matrix
3635 inline void CompressedMatrix<Type,true>::reset( size_t j )
3636 {
3637  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3638  end_[j] = begin_[j];
3639 }
3641 //*************************************************************************************************
3642 
3643 
3644 //*************************************************************************************************
3652 template< typename Type > // Data type of the sparse matrix
3654 {
3655  end_[0UL] = end_[n_];
3656  m_ = 0UL;
3657  n_ = 0UL;
3658 }
3660 //*************************************************************************************************
3661 
3662 
3663 //*************************************************************************************************
3676 template< typename Type > // Data type of the sparse matrix
3678  CompressedMatrix<Type,true>::set( size_t i, size_t j, const Type& value )
3679 {
3680  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3681  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3682 
3683  const Iterator pos( lowerBound( i, j ) );
3684 
3685  if( pos != end_[j] && pos->index_ == i ) {
3686  pos->value() = value;
3687  return pos;
3688  }
3689  else return insert( pos, i, j, value );
3690 }
3692 //*************************************************************************************************
3693 
3694 
3695 //*************************************************************************************************
3709 template< typename Type > // Data type of the sparse matrix
3711  CompressedMatrix<Type,true>::insert( size_t i, size_t j, const Type& value )
3712 {
3713  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3714  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3715 
3716  const Iterator pos( lowerBound( i, j ) );
3717 
3718  if( pos != end_[j] && pos->index_ == i ) {
3719  BLAZE_THROW_INVALID_ARGUMENT( "Bad access index" );
3720  }
3721 
3722  return insert( pos, i, j, value );
3723 }
3725 //*************************************************************************************************
3726 
3727 
3728 //*************************************************************************************************
3739 template< typename Type > // Data type of the sparse matrix
3741  CompressedMatrix<Type,true>::insert( Iterator pos, size_t i, size_t j, const Type& value )
3742 {
3743  if( begin_[j+1UL] - end_[j] != 0 ) {
3744  std::copy_backward( pos, end_[j], end_[j]+1 );
3745  pos->value_ = value;
3746  pos->index_ = i;
3747  ++end_[j];
3748 
3749  return pos;
3750  }
3751  else if( end_[n_] - begin_[n_] != 0 ) {
3752  std::copy_backward( pos, end_[n_-1UL], end_[n_-1]+1 );
3753 
3754  pos->value_ = value;
3755  pos->index_ = i;
3756 
3757  for( size_t k=j+1UL; k<n_+1UL; ++k ) {
3758  ++begin_[k];
3759  ++end_[k-1UL];
3760  }
3761 
3762  return pos;
3763  }
3764  else {
3765  size_t newCapacity( extendCapacity() );
3766 
3767  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
3768  Iterator* newEnd = newBegin+capacity_+1UL;
3769 
3770  newBegin[0UL] = allocate<Element>( newCapacity );
3771 
3772  for( size_t k=0UL; k<j; ++k ) {
3773  const size_t nonzeros( end_[k] - begin_[k] );
3774  const size_t total( begin_[k+1UL] - begin_[k] );
3775  newEnd [k] = newBegin[k] + nonzeros;
3776  newBegin[k+1UL] = newBegin[k] + total;
3777  }
3778  newEnd [j] = newBegin[j] + ( end_[j] - begin_[j] ) + 1;
3779  newBegin[j+1UL] = newBegin[j] + ( begin_[j+1UL] - begin_[j] ) + 1;
3780  for( size_t k=j+1UL; k<n_; ++k ) {
3781  const size_t nonzeros( end_[k] - begin_[k] );
3782  const size_t total( begin_[k+1UL] - begin_[k] );
3783  newEnd [k] = newBegin[k] + nonzeros;
3784  newBegin[k+1UL] = newBegin[k] + total;
3785  }
3786 
3787  newEnd[n_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
3788 
3789  Iterator tmp = std::copy( begin_[0UL], pos, newBegin[0UL] );
3790  tmp->value_ = value;
3791  tmp->index_ = i;
3792  std::copy( pos, end_[n_-1UL], tmp+1UL );
3793 
3794  std::swap( newBegin, begin_ );
3795  end_ = newEnd;
3796  deallocate( newBegin[0UL] );
3797  delete [] newBegin;
3798 
3799  return tmp;
3800  }
3801 }
3803 //*************************************************************************************************
3804 
3805 
3806 //*************************************************************************************************
3816 template< typename Type > // Data type of the sparse matrix
3817 inline void CompressedMatrix<Type,true>::erase( size_t i, size_t j )
3818 {
3819  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3820  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3821 
3822  const Iterator pos( find( i, j ) );
3823  if( pos != end_[j] )
3824  end_[j] = std::copy( pos+1, end_[j], pos );
3825 }
3827 //*************************************************************************************************
3828 
3829 
3830 //*************************************************************************************************
3840 template< typename Type > // Data type of the sparse matrix
3842  CompressedMatrix<Type,true>::erase( size_t j, Iterator pos )
3843 {
3844  BLAZE_USER_ASSERT( j < columns() , "Invalid row access index" );
3845  BLAZE_USER_ASSERT( pos >= begin_[j] && pos <= end_[j], "Invalid compressed matrix iterator" );
3846 
3847  if( pos != end_[j] )
3848  end_[j] = std::copy( pos+1, end_[j], pos );
3849 
3850  return pos;
3851 }
3853 //*************************************************************************************************
3854 
3855 
3856 //*************************************************************************************************
3867 template< typename Type > // Data type of the sparse matrix
3869  CompressedMatrix<Type,true>::erase( size_t j, Iterator first, Iterator last )
3870 {
3871  BLAZE_USER_ASSERT( j < columns(), "Invalid row access index" );
3872  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
3873  BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j], "Invalid compressed matrix iterator" );
3874  BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j], "Invalid compressed matrix iterator" );
3875 
3876  if( first != last )
3877  end_[j] = std::copy( last, end_[j], first );
3878 
3879  return first;
3880 }
3882 //*************************************************************************************************
3883 
3884 
3885 //*************************************************************************************************
3901 template< typename Type > // Data type of the sparse matrix
3902 void CompressedMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
3903 {
3904  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
3905  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
3906 
3907  if( m == m_ && n == n_ ) return;
3908 
3909  if( n > capacity_ )
3910  {
3911  Iterator* newBegin( new Iterator[2UL*n+2UL] );
3912  Iterator* newEnd ( newBegin+n+1UL );
3913 
3914  newBegin[0UL] = begin_[0UL];
3915 
3916  if( preserve ) {
3917  for( size_t j=0UL; j<n_; ++j ) {
3918  newEnd [j] = end_ [j];
3919  newBegin[j+1UL] = begin_[j+1UL];
3920  }
3921  for( size_t j=n_; j<n; ++j ) {
3922  newBegin[j+1UL] = newEnd[j] = begin_[n_];
3923  }
3924  }
3925  else {
3926  for( size_t j=0UL; j<n; ++j ) {
3927  newBegin[j+1UL] = newEnd[j] = begin_[0UL];
3928  }
3929  }
3930 
3931  newEnd[n] = end_[n_];
3932 
3933  std::swap( newBegin, begin_ );
3934  delete [] newBegin;
3935 
3936  end_ = newEnd;
3937  capacity_ = n;
3938  }
3939  else if( n > n_ )
3940  {
3941  end_[n] = end_[n_];
3942 
3943  if( !preserve ) {
3944  for( size_t j=0UL; j<n_; ++j )
3945  end_[j] = begin_[j];
3946  }
3947 
3948  for( size_t j=n_; j<n; ++j )
3949  begin_[j+1UL] = end_[j] = begin_[n_];
3950  }
3951  else
3952  {
3953  if( preserve ) {
3954  for( size_t j=0UL; j<n; ++j )
3955  end_[j] = lowerBound( m, j );
3956  }
3957  else {
3958  for( size_t j=0UL; j<n; ++j )
3959  end_[j] = begin_[j];
3960  }
3961 
3962  end_[n] = end_[n_];
3963  }
3964 
3965  m_ = m;
3966  n_ = n;
3967 
3968  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
3969  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
3970 }
3972 //*************************************************************************************************
3973 
3974 
3975 //*************************************************************************************************
3986 template< typename Type > // Data type of the sparse matrix
3987 inline void CompressedMatrix<Type,true>::reserve( size_t nonzeros )
3988 {
3989  if( nonzeros > capacity() )
3990  reserveElements( nonzeros );
3991 }
3993 //*************************************************************************************************
3994 
3995 
3996 //*************************************************************************************************
4008 template< typename Type > // Data type of the sparse matrix
4009 void CompressedMatrix<Type,true>::reserve( size_t j, size_t nonzeros )
4010 {
4011  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4012 
4013  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4014  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4015 
4016  const size_t current( capacity(j) );
4017 
4018  if( current >= nonzeros ) return;
4019 
4020  const ptrdiff_t additional( nonzeros - current );
4021 
4022  if( end_[n_] - begin_[n_] < additional )
4023  {
4024  const size_t newCapacity( begin_[n_] - begin_[0UL] + additional );
4025  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
4026 
4027  Iterator* newBegin( new Iterator[2UL*n_+2UL] );
4028  Iterator* newEnd ( newBegin+n_+1UL );
4029 
4030  newBegin[0UL] = allocate<Element>( newCapacity );
4031  newEnd [n_ ] = newBegin[0UL]+newCapacity;
4032 
4033  for( size_t k=0UL; k<j; ++k ) {
4034  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
4035  newBegin[k+1UL] = newBegin[k] + capacity(k);
4036  }
4037  newEnd [j ] = std::copy( begin_[j], end_[j], newBegin[j] );
4038  newBegin[j+1UL] = newBegin[j] + nonzeros;
4039  for( size_t k=j+1UL; k<n_; ++k ) {
4040  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
4041  newBegin[k+1UL] = newBegin[k] + capacity(k);
4042  }
4043 
4044  BLAZE_INTERNAL_ASSERT( newBegin[n_] == newEnd[n_], "Invalid pointer calculations" );
4045 
4046  std::swap( newBegin, begin_ );
4047  deallocate( newBegin[0UL] );
4048  delete [] newBegin;
4049  end_ = newEnd;
4050  capacity_ = n_;
4051  }
4052  else
4053  {
4054  begin_[n_] += additional;
4055  for( size_t k=n_-1UL; k>j; --k ) {
4056  begin_[k] = std::copy_backward( begin_[k], end_[k], end_[k]+additional );
4057  end_ [k] += additional;
4058  }
4059  }
4060 
4061  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4062  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4063 }
4065 //*************************************************************************************************
4066 
4067 
4068 //*************************************************************************************************
4078 template< typename Type > // Data type of the sparse matrix
4079 void CompressedMatrix<Type,true>::trim()
4080 {
4081  for( size_t j=0UL; j<n_; ++j )
4082  trim( j );
4083 }
4085 //*************************************************************************************************
4086 
4087 
4088 //*************************************************************************************************
4099 template< typename Type > // Data type of the sparse matrix
4100 void CompressedMatrix<Type,true>::trim( size_t j )
4101 {
4102  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4103 
4104  if( j < ( n_ - 1UL ) )
4105  end_[j+1] = std::copy( begin_[j+1], end_[j+1], end_[j] );
4106  begin_[j+1] = end_[j];
4107 }
4109 //*************************************************************************************************
4110 
4111 
4112 //*************************************************************************************************
4118 template< typename Type > // Data type of the sparse matrix
4119 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::transpose()
4120 {
4121  CompressedMatrix tmp( trans( *this ) );
4122  swap( tmp );
4123  return *this;
4124 }
4126 //*************************************************************************************************
4127 
4128 
4129 //*************************************************************************************************
4135 template< typename Type > // Data type of the sparse matrix
4136 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::ctranspose()
4137 {
4138  CompressedMatrix tmp( ctrans( *this ) );
4139  swap( tmp );
4140  return *this;
4141 }
4143 //*************************************************************************************************
4144 
4145 
4146 //*************************************************************************************************
4153 template< typename Type > // Data type of the sparse matrix
4154 template< typename Other > // Data type of the scalar value
4155 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scale( const Other& scalar )
4156 {
4157  for( size_t j=0UL; j<n_; ++j )
4158  for( Iterator element=begin_[j]; element!=end_[j]; ++element )
4159  element->value_ *= scalar;
4160 
4161  return *this;
4162 }
4164 //*************************************************************************************************
4165 
4166 
4167 //*************************************************************************************************
4174 template< typename Type > // Data type of the sparse matrix
4175 template< typename Other > // Data type of the scalar value
4176 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scaleDiagonal( Other scalar )
4177 {
4178  const size_t size( blaze::min( m_, n_ ) );
4179 
4180  for( size_t j=0UL; j<size; ++j ) {
4181  Iterator pos = lowerBound( j, j );
4182  if( pos != end_[j] && pos->index_ == j )
4183  pos->value_ *= scalar;
4184  }
4185 
4186  return *this;
4187 }
4189 //*************************************************************************************************
4190 
4191 
4192 //*************************************************************************************************
4200 template< typename Type > // Data type of the sparse matrix
4201 inline void CompressedMatrix<Type,true>::swap( CompressedMatrix& sm ) /* throw() */
4202 {
4203  std::swap( m_, sm.m_ );
4204  std::swap( n_, sm.n_ );
4205  std::swap( capacity_, sm.capacity_ );
4206  std::swap( begin_, sm.begin_ );
4207  std::swap( end_ , sm.end_ );
4208 }
4210 //*************************************************************************************************
4211 
4212 
4213 //*************************************************************************************************
4222 template< typename Type > // Data type of the sparse matrix
4223 inline size_t CompressedMatrix<Type,true>::extendCapacity() const
4224 {
4225  size_t nonzeros( 2UL*capacity()+1UL );
4226  nonzeros = blaze::max( nonzeros, 7UL );
4227 
4228  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
4229 
4230  return nonzeros;
4231 }
4233 //*************************************************************************************************
4234 
4235 
4236 //*************************************************************************************************
4243 template< typename Type > // Data type of the sparse matrix
4244 void CompressedMatrix<Type,true>::reserveElements( size_t nonzeros )
4245 {
4246  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
4247  Iterator* newEnd = newBegin+capacity_+1UL;
4248 
4249  newBegin[0UL] = allocate<Element>( nonzeros );
4250 
4251  for( size_t k=0UL; k<n_; ++k ) {
4252  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid column pointers" );
4253  newEnd [k] = std::copy( begin_[k], end_[k], newBegin[k] );
4254  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
4255  }
4256 
4257  newEnd[n_] = newBegin[0UL]+nonzeros;
4258 
4259  std::swap( newBegin, begin_ );
4260  deallocate( newBegin[0UL] );
4261  delete [] newBegin;
4262  end_ = newEnd;
4263 }
4265 //*************************************************************************************************
4266 
4267 
4268 
4269 
4270 //=================================================================================================
4271 //
4272 // LOOKUP FUNCTIONS
4273 //
4274 //=================================================================================================
4275 
4276 //*************************************************************************************************
4291 template< typename Type > // Data type of the sparse matrix
4293  CompressedMatrix<Type,true>::find( size_t i, size_t j )
4294 {
4295  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
4296 }
4298 //*************************************************************************************************
4299 
4300 
4301 //*************************************************************************************************
4316 template< typename Type > // Data type of the sparse matrix
4318  CompressedMatrix<Type,true>::find( size_t i, size_t j ) const
4319 {
4320  const ConstIterator pos( lowerBound( i, j ) );
4321  if( pos != end_[j] && pos->index_ == i )
4322  return pos;
4323  else return end_[j];
4324 }
4326 //*************************************************************************************************
4327 
4328 
4329 //*************************************************************************************************
4343 template< typename Type > // Data type of the sparse matrix
4345  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j )
4346 {
4347  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
4348 }
4350 //*************************************************************************************************
4351 
4352 
4353 //*************************************************************************************************
4367 template< typename Type > // Data type of the sparse matrix
4369  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j ) const
4370 {
4371  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4372  return std::lower_bound( begin_[j], end_[j], i, FindIndex() );
4373 }
4375 //*************************************************************************************************
4376 
4377 
4378 //*************************************************************************************************
4392 template< typename Type > // Data type of the sparse matrix
4394  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j )
4395 {
4396  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
4397 }
4399 //*************************************************************************************************
4400 
4401 
4402 //*************************************************************************************************
4416 template< typename Type > // Data type of the sparse matrix
4418  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j ) const
4419 {
4420  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4421  return std::upper_bound( begin_[j], end_[j], i, FindIndex() );
4422 }
4424 //*************************************************************************************************
4425 
4426 
4427 
4428 
4429 //=================================================================================================
4430 //
4431 // LOW-LEVEL UTILITY FUNCTIONS
4432 //
4433 //=================================================================================================
4434 
4435 //*************************************************************************************************
4477 template< typename Type > // Data type of the sparse matrix
4478 inline void CompressedMatrix<Type,true>::append( size_t i, size_t j, const Type& value, bool check )
4479 {
4480  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
4481  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
4482  BLAZE_USER_ASSERT( end_[j] < end_[n_], "Not enough reserved capacity left" );
4483  BLAZE_USER_ASSERT( begin_[j] == end_[j] || i > ( end_[j]-1UL )->index_, "Index is not strictly increasing" );
4484 
4485  end_[j]->value_ = value;
4486 
4487  if( !check || !isDefault( end_[j]->value_ ) ) {
4488  end_[j]->index_ = i;
4489  ++end_[j];
4490  }
4491 }
4493 //*************************************************************************************************
4494 
4495 
4496 //*************************************************************************************************
4510 template< typename Type > // Data type of the sparse matrix
4511 inline void CompressedMatrix<Type,true>::finalize( size_t j )
4512 {
4513  BLAZE_USER_ASSERT( j < n_, "Invalid row access index" );
4514 
4515  begin_[j+1UL] = end_[j];
4516  if( j != n_-1UL )
4517  end_[j+1UL] = end_[j];
4518 }
4520 //*************************************************************************************************
4521 
4522 
4523 
4524 
4525 //=================================================================================================
4526 //
4527 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4528 //
4529 //=================================================================================================
4530 
4531 //*************************************************************************************************
4542 template< typename Type > // Data type of the sparse matrix
4543 template< typename Other > // Data type of the foreign expression
4544 inline bool CompressedMatrix<Type,true>::canAlias( const Other* alias ) const
4545 {
4546  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4547 }
4549 //*************************************************************************************************
4550 
4551 
4552 //*************************************************************************************************
4563 template< typename Type > // Data type of the sparse matrix
4564 template< typename Other > // Data type of the foreign expression
4565 inline bool CompressedMatrix<Type,true>::isAliased( const Other* alias ) const
4566 {
4567  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4568 }
4570 //*************************************************************************************************
4571 
4572 
4573 //*************************************************************************************************
4584 template< typename Type > // Data type of the sparse matrix
4585 inline bool CompressedMatrix<Type,true>::canSMPAssign() const
4586 {
4587  return false;
4588 }
4590 //*************************************************************************************************
4591 
4592 
4593 //*************************************************************************************************
4605 template< typename Type > // Data type of the sparse matrix
4606 template< typename MT // Type of the right-hand side dense matrix
4607  , bool SO > // Storage order of the right-hand side dense matrix
4608 inline void CompressedMatrix<Type,true>::assign( const DenseMatrix<MT,SO>& rhs )
4609 {
4610  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4611  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4612 
4613  size_t nonzeros( 0UL );
4614 
4615  for( size_t j=1UL; j<=n_; ++j )
4616  begin_[j] = end_[j] = end_[n_];
4617 
4618  for( size_t j=0UL; j<n_; ++j )
4619  {
4620  begin_[j] = end_[j] = begin_[0UL]+nonzeros;
4621 
4622  const size_t ibegin( ( IsLower<MT>::value )
4623  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
4624  :( 0UL ) );
4625  const size_t iend ( ( IsUpper<MT>::value )
4626  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
4627  :( m_ ) );
4628 
4629  for( size_t i=ibegin; i<iend; ++i )
4630  {
4631  if( nonzeros == capacity() ) {
4632  reserveElements( extendCapacity() );
4633  for( size_t k=j+1UL; k<=n_; ++k )
4634  begin_[k] = end_[k] = end_[n_];
4635  }
4636 
4637  end_[j]->value_ = (~rhs)(i,j);
4638 
4639  if( !isDefault( end_[j]->value_ ) ) {
4640  end_[j]->index_ = i;
4641  ++end_[j];
4642  ++nonzeros;
4643  }
4644  }
4645  }
4646 
4647  begin_[n_] = begin_[0UL]+nonzeros;
4648 }
4650 //*************************************************************************************************
4651 
4652 
4653 //*************************************************************************************************
4665 template< typename Type > // Data type of the sparse matrix
4666 template< typename MT > // Type of the right-hand side sparse matrix
4667 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,true>& rhs )
4668 {
4669  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4670  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4671  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4672  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
4673 
4674  if( n_ == 0UL || begin_[0] == NULL )
4675  return;
4676 
4677  for( size_t j=0UL; j<n_; ++j ) {
4678  begin_[j+1UL] = end_[j] = std::copy( (~rhs).begin(j), (~rhs).end(j), begin_[j] );
4679  }
4680 }
4682 //*************************************************************************************************
4683 
4684 
4685 //*************************************************************************************************
4697 template< typename Type > // Data type of the sparse matrix
4698 template< typename MT > // Type of the right-hand side sparse matrix
4699 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,false>& rhs )
4700 {
4702 
4703  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4704  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4705  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4706  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
4707 
4708  typedef typename MT::ConstIterator RhsIterator;
4709 
4710  // Counting the number of elements per column
4711  std::vector<size_t> columnLengths( n_, 0UL );
4712  for( size_t i=0UL; i<m_; ++i ) {
4713  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4714  ++columnLengths[element->index()];
4715  }
4716 
4717  // Resizing the sparse matrix
4718  for( size_t j=0UL; j<n_; ++j ) {
4719  begin_[j+1UL] = end_[j+1UL] = begin_[j] + columnLengths[j];
4720  }
4721 
4722  // Appending the elements to the columns of the sparse matrix
4723  for( size_t i=0UL; i<m_; ++i ) {
4724  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4725  append( i, element->index(), element->value() );
4726  }
4727 }
4729 //*************************************************************************************************
4730 
4731 
4732 //*************************************************************************************************
4744 template< typename Type > // Data type of the sparse matrix
4745 template< typename MT // Type of the right-hand side dense matrix
4746  , bool SO > // Storage order of the right-hand side dense matrix
4747 inline void CompressedMatrix<Type,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
4748 {
4749  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4750  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4751 
4752  CompressedMatrix tmp( serial( *this + (~rhs) ) );
4753  swap( tmp );
4754 }
4756 //*************************************************************************************************
4757 
4758 
4759 //*************************************************************************************************
4771 template< typename Type > // Data type of the sparse matrix
4772 template< typename MT // Type of the right-hand side sparse matrix
4773  , bool SO > // Storage order of the right-hand side sparse matrix
4774 inline void CompressedMatrix<Type,true>::addAssign( const SparseMatrix<MT,SO>& rhs )
4775 {
4776  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4777  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4778 
4779  CompressedMatrix tmp( serial( *this + (~rhs) ) );
4780  swap( tmp );
4781 }
4783 //*************************************************************************************************
4784 
4785 
4786 //*************************************************************************************************
4798 template< typename Type > // Data type of the sparse matrix
4799 template< typename MT // Type of the right-hand side dense matrix
4800  , bool SO > // Storage order of the right-hand side dense matrix
4801 inline void CompressedMatrix<Type,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
4802 {
4803  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4804  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4805 
4806  CompressedMatrix tmp( serial( *this - (~rhs) ) );
4807  swap( tmp );
4808 }
4810 //*************************************************************************************************
4811 
4812 
4813 //*************************************************************************************************
4825 template< typename Type > // Data type of the sparse matrix
4826 template< typename MT // Type of the right-hand side sparse matrix
4827  , bool SO > // Storage order of the right-hand side sparse matrix
4828 inline void CompressedMatrix<Type,true>::subAssign( const SparseMatrix<MT,SO>& rhs )
4829 {
4830  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4831  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4832 
4833  CompressedMatrix tmp( serial( *this - (~rhs) ) );
4834  swap( tmp );
4835 }
4837 //*************************************************************************************************
4838 
4839 
4840 
4841 
4842 
4843 
4844 
4845 
4846 //=================================================================================================
4847 //
4848 // COMPRESSEDMATRIX OPERATORS
4849 //
4850 //=================================================================================================
4851 
4852 //*************************************************************************************************
4855 template< typename Type, bool SO >
4856 inline void reset( CompressedMatrix<Type,SO>& m );
4857 
4858 template< typename Type, bool SO >
4859 inline void reset( CompressedMatrix<Type,SO>& m, size_t i );
4860 
4861 template< typename Type, bool SO >
4862 inline void clear( CompressedMatrix<Type,SO>& m );
4863 
4864 template< typename Type, bool SO >
4865 inline bool isDefault( const CompressedMatrix<Type,SO>& m );
4866 
4867 template< typename Type, bool SO >
4868 inline bool isIntact( const CompressedMatrix<Type,SO>& m );
4869 
4870 template< typename Type, bool SO >
4871 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) /* throw() */;
4872 
4873 template< typename Type, bool SO >
4874 inline void move( CompressedMatrix<Type,SO>& dst, CompressedMatrix<Type,SO>& src ) /* throw() */;
4876 //*************************************************************************************************
4877 
4878 
4879 //*************************************************************************************************
4886 template< typename Type // Data type of the sparse matrix
4887  , bool SO > // Storage order
4888 inline void reset( CompressedMatrix<Type,SO>& m )
4889 {
4890  m.reset();
4891 }
4892 //*************************************************************************************************
4893 
4894 
4895 //*************************************************************************************************
4908 template< typename Type // Data type of the sparse matrix
4909  , bool SO > // Storage order
4910 inline void reset( CompressedMatrix<Type,SO>& m, size_t i )
4911 {
4912  m.reset( i );
4913 }
4914 //*************************************************************************************************
4915 
4916 
4917 //*************************************************************************************************
4924 template< typename Type // Data type of the sparse matrix
4925  , bool SO > // Storage order
4926 inline void clear( CompressedMatrix<Type,SO>& m )
4927 {
4928  m.clear();
4929 }
4930 //*************************************************************************************************
4931 
4932 
4933 //*************************************************************************************************
4951 template< typename Type // Data type of the sparse matrix
4952  , bool SO > // Storage order
4953 inline bool isDefault( const CompressedMatrix<Type,SO>& m )
4954 {
4955  return ( m.rows() == 0UL && m.columns() == 0UL );
4956 }
4957 //*************************************************************************************************
4958 
4959 
4960 //*************************************************************************************************
4978 template< typename Type // Data type of the sparse matrix
4979  , bool SO > // Storage order
4980 inline bool isIntact( const CompressedMatrix<Type,SO>& m )
4981 {
4982  return ( m.nonZeros() <= m.capacity() );
4983 }
4984 //*************************************************************************************************
4985 
4986 
4987 //*************************************************************************************************
4996 template< typename Type // Data type of the sparse matrix
4997  , bool SO > // Storage order
4998 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) /* throw() */
4999 {
5000  a.swap( b );
5001 }
5002 //*************************************************************************************************
5003 
5004 
5005 //*************************************************************************************************
5014 template< typename Type // Data type of the sparse matrix
5015  , bool SO > // Storage order
5016 inline void move( CompressedMatrix<Type,SO>& dst, CompressedMatrix<Type,SO>& src ) /* throw() */
5017 {
5018  dst.swap( src );
5019 }
5020 //*************************************************************************************************
5021 
5022 
5023 
5024 
5025 //=================================================================================================
5026 //
5027 // ISRESIZABLE SPECIALIZATIONS
5028 //
5029 //=================================================================================================
5030 
5031 //*************************************************************************************************
5033 template< typename T, bool SO >
5034 struct IsResizable< CompressedMatrix<T,SO> > : public TrueType
5035 {
5036  enum { value = 1 };
5037  typedef TrueType Type;
5038 };
5040 //*************************************************************************************************
5041 
5042 
5043 
5044 
5045 //=================================================================================================
5046 //
5047 // ADDTRAIT SPECIALIZATIONS
5048 //
5049 //=================================================================================================
5050 
5051 //*************************************************************************************************
5053 template< typename T1, bool SO, typename T2, size_t M, size_t N >
5054 struct AddTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
5055 {
5056  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
5057 };
5058 
5059 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5060 struct AddTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
5061 {
5062  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO2 > Type;
5063 };
5064 
5065 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5066 struct AddTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
5067 {
5068  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
5069 };
5070 
5071 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5072 struct AddTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
5073 {
5074  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO1 > Type;
5075 };
5076 
5077 template< typename T1, bool SO, typename T2, size_t M, size_t N >
5078 struct AddTrait< CompressedMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
5079 {
5080  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
5081 };
5082 
5083 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5084 struct AddTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
5085 {
5086  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, SO2 > Type;
5087 };
5088 
5089 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5090 struct AddTrait< HybridMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
5091 {
5092  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
5093 };
5094 
5095 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5096 struct AddTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
5097 {
5098  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, SO1 > Type;
5099 };
5100 
5101 template< typename T1, bool SO, typename T2 >
5102 struct AddTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
5103 {
5104  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type, SO > Type;
5105 };
5106 
5107 template< typename T1, bool SO1, typename T2, bool SO2 >
5108 struct AddTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
5109 {
5110  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type, SO2 > Type;
5111 };
5112 
5113 template< typename T1, bool SO, typename T2 >
5114 struct AddTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
5115 {
5116  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type, SO > Type;
5117 };
5118 
5119 template< typename T1, bool SO1, typename T2, bool SO2 >
5120 struct AddTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
5121 {
5122  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type, SO1 > Type;
5123 };
5124 
5125 template< typename T1, bool SO, typename T2, bool AF, bool PF >
5126 struct AddTrait< CompressedMatrix<T1,SO>, CustomMatrix<T2,AF,PF,SO> >
5127 {
5128  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type, SO > Type;
5129 };
5130 
5131 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
5132 struct AddTrait< CompressedMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
5133 {
5134  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type, SO2 > Type;
5135 };
5136 
5137 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
5138 struct AddTrait< CustomMatrix<T1,AF,PF,SO>, CompressedMatrix<T2,SO> >
5139 {
5140  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type, SO > Type;
5141 };
5142 
5143 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
5144 struct AddTrait< CustomMatrix<T1,AF,PF,SO1>, CompressedMatrix<T2,SO2> >
5145 {
5146  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type, SO1 > Type;
5147 };
5148 
5149 template< typename T1, bool SO, typename T2 >
5150 struct AddTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
5151 {
5152  typedef CompressedMatrix< typename AddTrait<T1,T2>::Type, SO > Type;
5153 };
5154 
5155 template< typename T1, bool SO1, typename T2, bool SO2 >
5156 struct AddTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
5157 {
5158  typedef CompressedMatrix< typename AddTrait<T1,T2>::Type, false > Type;
5159 };
5161 //*************************************************************************************************
5162 
5163 
5164 
5165 
5166 //=================================================================================================
5167 //
5168 // SUBTRAIT SPECIALIZATIONS
5169 //
5170 //=================================================================================================
5171 
5172 //*************************************************************************************************
5174 template< typename T1, bool SO, typename T2, size_t M, size_t N >
5175 struct SubTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
5176 {
5177  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
5178 };
5179 
5180 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5181 struct SubTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
5182 {
5183  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO2 > Type;
5184 };
5185 
5186 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5187 struct SubTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
5188 {
5189  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
5190 };
5191 
5192 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5193 struct SubTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
5194 {
5195  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO1 > Type;
5196 };
5197 
5198 template< typename T1, bool SO, typename T2, size_t M, size_t N >
5199 struct SubTrait< CompressedMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
5200 {
5201  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
5202 };
5203 
5204 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5205 struct SubTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
5206 {
5207  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, SO2 > Type;
5208 };
5209 
5210 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5211 struct SubTrait< HybridMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
5212 {
5213  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
5214 };
5215 
5216 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5217 struct SubTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
5218 {
5219  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, SO1 > Type;
5220 };
5221 
5222 template< typename T1, bool SO, typename T2 >
5223 struct SubTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
5224 {
5225  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type, SO > Type;
5226 };
5227 
5228 template< typename T1, bool SO1, typename T2, bool SO2 >
5229 struct SubTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
5230 {
5231  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type, SO2 > Type;
5232 };
5233 
5234 template< typename T1, bool SO, typename T2 >
5235 struct SubTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
5236 {
5237  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type, SO > Type;
5238 };
5239 
5240 template< typename T1, bool SO1, typename T2, bool SO2 >
5241 struct SubTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
5242 {
5243  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type, SO1 > Type;
5244 };
5245 
5246 template< typename T1, bool SO, typename T2, bool AF, bool PF >
5247 struct SubTrait< CompressedMatrix<T1,SO>, CustomMatrix<T2,AF,PF,SO> >
5248 {
5249  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type, SO > Type;
5250 };
5251 
5252 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
5253 struct SubTrait< CompressedMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
5254 {
5255  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type, SO2 > Type;
5256 };
5257 
5258 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
5259 struct SubTrait< CustomMatrix<T1,AF,PF,SO>, CompressedMatrix<T2,SO> >
5260 {
5261  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type, SO > Type;
5262 };
5263 
5264 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
5265 struct SubTrait< CustomMatrix<T1,AF,PF,SO1>, CompressedMatrix<T2,SO2> >
5266 {
5267  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type, SO1 > Type;
5268 };
5269 
5270 template< typename T1, bool SO, typename T2 >
5271 struct SubTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
5272 {
5273  typedef CompressedMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
5274 };
5275 
5276 template< typename T1, bool SO1, typename T2, bool SO2 >
5277 struct SubTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
5278 {
5279  typedef CompressedMatrix< typename SubTrait<T1,T2>::Type , false > Type;
5280 };
5282 //*************************************************************************************************
5283 
5284 
5285 
5286 
5287 //=================================================================================================
5288 //
5289 // MULTTRAIT SPECIALIZATIONS
5290 //
5291 //=================================================================================================
5292 
5293 //*************************************************************************************************
5295 template< typename T1, bool SO, typename T2 >
5296 struct MultTrait< CompressedMatrix<T1,SO>, T2, typename EnableIf< IsNumeric<T2> >::Type >
5297 {
5298  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
5299 };
5300 
5301 template< typename T1, typename T2, bool SO >
5302 struct MultTrait< T1, CompressedMatrix<T2,SO>, typename EnableIf< IsNumeric<T1> >::Type >
5303 {
5304  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
5305 };
5306 
5307 template< typename T1, bool SO, typename T2, size_t N >
5308 struct MultTrait< CompressedMatrix<T1,SO>, StaticVector<T2,N,false> >
5309 {
5310  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
5311 };
5312 
5313 template< typename T1, size_t N, typename T2, bool SO >
5314 struct MultTrait< StaticVector<T1,N,true>, CompressedMatrix<T2,SO> >
5315 {
5316  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
5317 };
5318 
5319 template< typename T1, bool SO, typename T2, size_t N >
5320 struct MultTrait< CompressedMatrix<T1,SO>, HybridVector<T2,N,false> >
5321 {
5322  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
5323 };
5324 
5325 template< typename T1, size_t N, typename T2, bool SO >
5326 struct MultTrait< HybridVector<T1,N,true>, CompressedMatrix<T2,SO> >
5327 {
5328  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
5329 };
5330 
5331 template< typename T1, bool SO, typename T2 >
5332 struct MultTrait< CompressedMatrix<T1,SO>, DynamicVector<T2,false> >
5333 {
5334  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
5335 };
5336 
5337 template< typename T1, typename T2, bool SO >
5338 struct MultTrait< DynamicVector<T1,true>, CompressedMatrix<T2,SO> >
5339 {
5340  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
5341 };
5342 
5343 template< typename T1, bool SO, typename T2, bool AF, bool PF >
5344 struct MultTrait< CompressedMatrix<T1,SO>, CustomVector<T2,AF,PF,false> >
5345 {
5346  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
5347 };
5348 
5349 template< typename T1, bool AF, bool PF, typename T2, bool SO >
5350 struct MultTrait< CustomVector<T1,AF,PF,true>, CompressedMatrix<T2,SO> >
5351 {
5352  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
5353 };
5354 
5355 template< typename T1, bool SO, typename T2 >
5356 struct MultTrait< CompressedMatrix<T1,SO>, CompressedVector<T2,false> >
5357 {
5358  typedef CompressedVector< typename MultTrait<T1,T2>::Type, false > Type;
5359 };
5360 
5361 template< typename T1, typename T2, bool SO >
5362 struct MultTrait< CompressedVector<T1,true>, CompressedMatrix<T2,SO> >
5363 {
5364  typedef CompressedVector< typename MultTrait<T1,T2>::Type, true > Type;
5365 };
5366 
5367 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5368 struct MultTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
5369 {
5370  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5371 };
5372 
5373 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5374 struct MultTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
5375 {
5376  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5377 };
5378 
5379 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5380 struct MultTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
5381 {
5382  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5383 };
5384 
5385 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5386 struct MultTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
5387 {
5388  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5389 };
5390 
5391 template< typename T1, bool SO1, typename T2, bool SO2 >
5392 struct MultTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
5393 {
5394  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5395 };
5396 
5397 template< typename T1, bool SO1, typename T2, bool SO2 >
5398 struct MultTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
5399 {
5400  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5401 };
5402 
5403 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
5404 struct MultTrait< CompressedMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
5405 {
5406  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5407 };
5408 
5409 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
5410 struct MultTrait< CustomMatrix<T1,AF,PF,SO1>, CompressedMatrix<T2,SO2> >
5411 {
5412  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5413 };
5414 
5415 template< typename T1, bool SO1, typename T2, bool SO2 >
5416 struct MultTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
5417 {
5418  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5419 };
5421 //*************************************************************************************************
5422 
5423 
5424 
5425 
5426 //=================================================================================================
5427 //
5428 // DIVTRAIT SPECIALIZATIONS
5429 //
5430 //=================================================================================================
5431 
5432 //*************************************************************************************************
5434 template< typename T1, bool SO, typename T2 >
5435 struct DivTrait< CompressedMatrix<T1,SO>, T2, typename EnableIf< IsNumeric<T2> >::Type >
5436 {
5437  typedef CompressedMatrix< typename DivTrait<T1,T2>::Type, SO > Type;
5438 };
5440 //*************************************************************************************************
5441 
5442 
5443 
5444 
5445 //=================================================================================================
5446 //
5447 // MATHTRAIT SPECIALIZATIONS
5448 //
5449 //=================================================================================================
5450 
5451 //*************************************************************************************************
5453 template< typename T1, bool SO, typename T2 >
5454 struct MathTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
5455 {
5456  typedef CompressedMatrix< typename MathTrait<T1,T2>::HighType, SO > HighType;
5457  typedef CompressedMatrix< typename MathTrait<T1,T2>::LowType , SO > LowType;
5458 };
5460 //*************************************************************************************************
5461 
5462 
5463 
5464 
5465 //=================================================================================================
5466 //
5467 // SUBMATRIXTRAIT SPECIALIZATIONS
5468 //
5469 //=================================================================================================
5470 
5471 //*************************************************************************************************
5473 template< typename T1, bool SO >
5474 struct SubmatrixTrait< CompressedMatrix<T1,SO> >
5475 {
5476  typedef CompressedMatrix<T1,SO> Type;
5477 };
5479 //*************************************************************************************************
5480 
5481 
5482 
5483 
5484 //=================================================================================================
5485 //
5486 // ROWTRAIT SPECIALIZATIONS
5487 //
5488 //=================================================================================================
5489 
5490 //*************************************************************************************************
5492 template< typename T1, bool SO >
5493 struct RowTrait< CompressedMatrix<T1,SO> >
5494 {
5495  typedef CompressedVector<T1,true> Type;
5496 };
5498 //*************************************************************************************************
5499 
5500 
5501 
5502 
5503 //=================================================================================================
5504 //
5505 // COLUMNTRAIT SPECIALIZATIONS
5506 //
5507 //=================================================================================================
5508 
5509 //*************************************************************************************************
5511 template< typename T1, bool SO >
5512 struct ColumnTrait< CompressedMatrix<T1,SO> >
5513 {
5514  typedef CompressedVector<T1,false> Type;
5515 };
5517 //*************************************************************************************************
5518 
5519 } // namespace blaze
5520 
5521 #endif
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
Definition: Const.h:116
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exceptionThis macro encapsulates the default way of...
Definition: Exception.h:187
Pointer difference type of the Blaze library.
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1729
size_t rows() const
Returns the current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:1200
void reserveElements(size_t nonzeros)
Reserving the specified number of sparse matrix elements.
Definition: CompressedMatrix.h:1923
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:98
Iterator * end_
Pointers one past the last non-zero element of each row.
Definition: CompressedMatrix.h:426
Header file for mathematical functions.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
MatrixAccessProxy< This > Reference
Reference to a sparse matrix value.
Definition: CompressedMatrix.h:262
Compile time type selection.The If class template selects one of the two given types T2 and T3 depend...
Definition: If.h:112
Header file for the subtraction trait.
Header file for basic type definitions.
const Type & ConstReference
Reference to a constant sparse matrix value.
Definition: CompressedMatrix.h:263
const bool defaultStorageOrder
The default storage order for all matrices of the Blaze library.This value specifies the default stor...
Definition: StorageOrder.h:56
void move(CompressedMatrix< Type, SO > &dst, CompressedMatrix< Type, SO > &src)
Moving the contents of one compressed matrix to another.
Definition: CompressedMatrix.h:5016
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:252
Header file for the row trait.
CompressedMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: CompressedMatrix.h:1820
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:250
Header file for the IsSparseMatrix type trait.
CompressedMatrix()
The default constructor for CompressedMatrix.
Definition: CompressedMatrix.h:470
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:207
size_t extendCapacity() const
Calculating a new matrix capacity.
Definition: CompressedMatrix.h:1903
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:507
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2749
void clear()
Clearing the sparse matrix.
Definition: CompressedMatrix.h:1341
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix)
Returns the maximum capacity of the matrix.
Definition: Matrix.h:340
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:259
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:308
void clear(CompressedMatrix< Type, SO > &m)
Clearing the given compressed matrix.
Definition: CompressedMatrix.h:4926
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:90
CompressedMatrix< ET, SO > Other
The type of the other CompressedMatrix.
Definition: CompressedMatrix.h:273
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2582
CompressedMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:257
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.In case the given data type is a volatile-qualified type, a compilation error is created.
Definition: Volatile.h:116
~CompressedMatrix()
The destructor for CompressedMatrix.
Definition: CompressedMatrix.h:658
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:721
void reset(CompressedMatrix< Type, SO > &m)
Resetting the given compressed matrix.
Definition: CompressedMatrix.h:4888
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:378
Access proxy for sparse, matrices.The MatrixAccessProxy provides safe access to the elements of a no...
Definition: MatrixAccessProxy.h:100
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:90
Header file for memory allocation and deallocation functionality.
bool isAliased(const Other *alias) const
Returns whether the matrix is aliased with the given address alias.
Definition: CompressedMatrix.h:2247
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:428
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:260
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:117
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:547
Constraint on the data type.
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: CompressedMatrix.h:1263
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:2751
Header file for the SparseMatrix base class.
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:424
void reserve(size_t nonzeros)
Setting the minimum capacity of the sparse matrix.
Definition: CompressedMatrix.h:1671
void reset()
Reset to the default initial values.
Definition: CompressedMatrix.h:1303
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:261
Header file for the ValueIndexPair class.
bool isDefault(const CompressedMatrix< Type, SO > &m)
Returns whether the given compressed matrix is in default state.
Definition: CompressedMatrix.h:4953
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
Header file for the If class template.
Header file for the IsFloatingPoint type trait.
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b)
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:4998
Iterator set(size_t i, size_t j, const Type &value)
Setting an element of the compressed matrix.
Definition: CompressedMatrix.h:1365
bool isIntact(const CompressedMatrix< Type, SO > &m)
Returns whether the invariants of the given compressed matrix are intact.
Definition: CompressedMatrix.h:4980
Header file for the MatrixAccessProxy class.
Header file for all forward declarations of the math module.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2592
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:116
Header file for the IsSMPAssignable type trait.
void erase(size_t i, size_t j)
Erasing an element from the sparse matrix.
Definition: CompressedMatrix.h:1501
Iterator * end_
Pointers one past the last non-zero element of each column.
Definition: CompressedMatrix.h:2753
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exceptionThis macro encapsulates the default way of Bla...
Definition: Exception.h:331
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1682
EnableIf< IsBuiltin< T > >::Type deallocate(T *address)
Deallocation of memory for built-in data types.
Definition: Memory.h:227
#define BLAZE_CONSTRAINT_MUST_HAVE_SAME_SIZE(T1, T2)
Constraint on the size of two data types.In case the types T1 and T2 don't have the same size...
Definition: SameSize.h:78
const CTransExprTrait< MT >::Type ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatConjExpr.h:974
ValueIndexPair< Type > ElementBase
Base class for the sparse matrix element.
Definition: CompressedMatrix.h:211
Constraint on the data type.
Header file for the IsLower type trait.
Header file for the default storage order for all vectors of the Blaze library.
Iterator insert(size_t i, size_t j, const Type &value)
Inserting an element into the compressed matrix.
Definition: CompressedMatrix.h:1397
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:187
CompressedMatrix< ET, true > Other
The type of the other CompressedMatrix.
Definition: CompressedMatrix.h:2600
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
Compile time check for floating point data types.This type trait tests whether or not the given templ...
Definition: IsFloatingPoint.h:94
Compile time check for data types.This type trait tests whether or not the given template parameter i...
Definition: IsSMPAssignable.h:120
BLAZE_ALWAYS_INLINE void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:532
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2590
void subAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the subtraction assignment of a dense matrix.
Definition: CompressedMatrix.h:2476
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
Header file for the serial shim.
void swap(CompressedMatrix &sm)
Swapping the contents of two sparse matrices.
Definition: CompressedMatrix.h:1882
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:265
bool canSMPAssign() const
Returns whether the matrix can be used in SMP assignments.
Definition: CompressedMatrix.h:2266
size_t capacity() const
Returns the maximum capacity of the sparse matrix.
Definition: CompressedMatrix.h:1228
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the sparse matrix.
Definition: CompressedMatrix.h:1587
Header file for the IsNumeric type trait.
CompressedMatrix & operator=(const CompressedMatrix &rhs)
Copy assignment operator for CompressedMatrix.
Definition: CompressedMatrix.h:931
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:116
Reference operator()(size_t i, size_t j)
2D-access to the sparse matrix elements.
Definition: CompressedMatrix.h:687
Header file for run time assertion macros.
Header file for the addition trait.
Iterator end(size_t i)
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:859
CompressedMatrix & transpose()
In-place transpose of the matrix.
Definition: CompressedMatrix.h:1804
Header file for the division trait.
void trim()
Removing all excessive capacity from all rows/columns.
Definition: CompressedMatrix.h:1765
Header file for the submatrix trait.
Constraint on the data type.
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:116
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2591
Header file for the column trait.
Header file for the isDefault shim.
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:94
Constraint on the data type.
size_t columns() const
Returns the current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:1214
Constraint on the data type.
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:256
Iterator * begin_
Pointers to the first non-zero element of each column.
Definition: CompressedMatrix.h:2752
void assign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the assignment of a row-major dense matrix.
Definition: CompressedMatrix.h:2288
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:264
void append(size_t i, size_t j, const Type &value, bool check=false)
Appending an element to the specified row/column of the sparse matrix.
Definition: CompressedMatrix.h:2163
void finalize(size_t i)
Finalizing the element insertion of a row/column.
Definition: CompressedMatrix.h:2195
bool canAlias(const Other *alias) const
Returns whether the matrix can alias with the given address alias.
Definition: CompressedMatrix.h:2227
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b)
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:256
Base template for the DivTrait class.
Definition: DivTrait.h:138
CompressedMatrix< Type, SO > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:255
Iterator find(size_t i, size_t j)
Searches for a specific matrix element.
Definition: CompressedMatrix.h:1972
Header file for the mathematical trait.
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
Iterator * begin_
Pointers to the first non-zero element of each row.
Definition: CompressedMatrix.h:425
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2750
Index-value-pair for sparse vectors and matrices.The ValueIndexPair class represents a single index-v...
Definition: ValueIndexPair.h:70
Constraint on the size of two data types.
void addAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the addition assignment of a dense matrix.
Definition: CompressedMatrix.h:2424
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:944
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:258
Iterator lowerBound(size_t i, size_t j)
Returns an iterator to the first index not less then the given index.
Definition: CompressedMatrix.h:2025
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:2755
Iterator upperBound(size_t i, size_t j)
Returns an iterator to the first index greater then the given index.
Definition: CompressedMatrix.h:2076
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix)
Returns the current number of columns of the matrix.
Definition: Matrix.h:324
ConstIterator cbegin(size_t i) const
Returns an iterator to the first non-zero element of row/column i.
Definition: CompressedMatrix.h:837
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2589
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:272
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:2599
Header file for the IsUpper type trait.
Header file for exception macros.
boost::true_type TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:423
ConstIterator cend(size_t i) const
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:903
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: CompressedMatrix.h:739
Header file for the IsResizable type trait.
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:422
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Iterator begin(size_t i)
Returns an iterator to the first non-zero element of row/column i.
Definition: CompressedMatrix.h:793
Header file for a safe C++ NULL pointer implementation.