All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 <stdexcept>
46 #include <vector>
48 #include <blaze/math/Forward.h>
49 #include <blaze/math/Functions.h>
50 #include <blaze/math/shims/Equal.h>
64 #include <blaze/system/Precision.h>
66 #include <blaze/util/Assert.h>
73 #include <blaze/util/EnableIf.h>
74 #include <blaze/util/Memory.h>
75 #include <blaze/util/mpl/If.h>
76 #include <blaze/util/Null.h>
77 #include <blaze/util/Types.h>
80 
81 
82 namespace blaze {
83 
84 //=================================================================================================
85 //
86 // CLASS DEFINITION
87 //
88 //=================================================================================================
89 
90 //*************************************************************************************************
195 template< typename Type // Data type of the sparse matrix
196  , bool SO = defaultStorageOrder > // Storage order
197 class CompressedMatrix : public SparseMatrix< CompressedMatrix<Type,SO>, SO >
198 {
199  private:
200  //**Type definitions****************************************************************************
202  //**********************************************************************************************
203 
204  //**Private class Element***********************************************************************
208  struct Element : public ElementBase
209  {
210  // This operator is required due to a bug in all versions of the the MSVC compiler.
211  // A simple 'using ElementBase::operator=;' statement results in ambiguity problems.
212  template< typename Other >
213  inline Element& operator=( const Other& rhs )
214  {
215  ElementBase::operator=( rhs );
216  return *this;
217  }
218 
219  friend class CompressedMatrix;
220  };
222  //**********************************************************************************************
223 
224  //**Private class FindIndex*********************************************************************
228  struct FindIndex : public std::binary_function<Element,size_t,bool>
229  {
230  inline bool operator()( const Element& element, size_t index ) const {
231  return element.index() < index;
232  }
233  inline bool operator()( size_t index, const Element& element ) const {
234  return index < element.index();
235  }
236  inline bool operator()( const Element& element1, const Element& element2 ) const {
237  return element1.index() < element2.index();
238  }
239  };
241  //**********************************************************************************************
242 
243  public:
244  //**Type definitions****************************************************************************
246  typedef This ResultType;
249  typedef Type ElementType;
250  typedef const Type& ReturnType;
251  typedef const This& CompositeType;
253  typedef const Type& ConstReference;
254  typedef Element* Iterator;
255  typedef const Element* ConstIterator;
256  //**********************************************************************************************
257 
258  //**Compilation flags***************************************************************************
260 
263  enum { smpAssignable = 0 };
264  //**********************************************************************************************
265 
266  //**Constructors********************************************************************************
269  explicit inline CompressedMatrix();
270  explicit inline CompressedMatrix( size_t m, size_t n );
271  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
272  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
273  inline CompressedMatrix( const CompressedMatrix& sm );
274  template< typename MT, bool SO2 > inline CompressedMatrix( const DenseMatrix<MT,SO2>& dm );
275  template< typename MT, bool SO2 > inline CompressedMatrix( const SparseMatrix<MT,SO2>& sm );
277  //**********************************************************************************************
278 
279  //**Destructor**********************************************************************************
282  inline ~CompressedMatrix();
284  //**********************************************************************************************
285 
286  //**Data access functions***********************************************************************
289  inline Reference operator()( size_t i, size_t j );
290  inline ConstReference operator()( size_t i, size_t j ) const;
291  inline Iterator begin ( size_t i );
292  inline ConstIterator begin ( size_t i ) const;
293  inline ConstIterator cbegin( size_t i ) const;
294  inline Iterator end ( size_t i );
295  inline ConstIterator end ( size_t i ) const;
296  inline ConstIterator cend ( size_t i ) const;
298  //**********************************************************************************************
299 
300  //**Assignment operators************************************************************************
303  inline CompressedMatrix& operator= ( const CompressedMatrix& rhs );
304  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO2>& rhs );
305  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO2>& rhs );
306  template< typename MT, bool SO2 > inline CompressedMatrix& operator+=( const Matrix<MT,SO2>& rhs );
307  template< typename MT, bool SO2 > inline CompressedMatrix& operator-=( const Matrix<MT,SO2>& rhs );
308  template< typename MT, bool SO2 > inline CompressedMatrix& operator*=( const Matrix<MT,SO2>& rhs );
309 
310  template< typename Other >
311  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
312  operator*=( Other rhs );
313 
314  template< typename Other >
315  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
316  operator/=( Other rhs );
318  //**********************************************************************************************
319 
320  //**Utility functions***************************************************************************
323  inline size_t rows() const;
324  inline size_t columns() const;
325  inline size_t capacity() const;
326  inline size_t capacity( size_t i ) const;
327  inline size_t nonZeros() const;
328  inline size_t nonZeros( size_t i ) const;
329  inline void reset();
330  inline void reset( size_t i );
331  inline void clear();
332  Iterator insert ( size_t i, size_t j, const Type& value );
333  inline void erase ( size_t i, size_t j );
334  inline Iterator erase ( size_t i, Iterator pos );
335  inline Iterator erase ( size_t i, Iterator first, Iterator last );
336  void resize ( size_t m, size_t n, bool preserve=true );
337  inline void reserve( size_t nonzeros );
338  void reserve( size_t i, size_t nonzeros );
339  inline void trim ();
340  inline void trim ( size_t i );
341  inline CompressedMatrix& transpose();
342  template< typename Other > inline CompressedMatrix& scale( Other scalar );
343  template< typename Other > inline CompressedMatrix& scaleDiagonal( Other scalar );
344  inline void swap( CompressedMatrix& sm ) /* throw() */;
346  //**********************************************************************************************
347 
348  //**Lookup functions****************************************************************************
351  inline Iterator find ( size_t i, size_t j );
352  inline ConstIterator find ( size_t i, size_t j ) const;
353  inline Iterator lowerBound( size_t i, size_t j );
354  inline ConstIterator lowerBound( size_t i, size_t j ) const;
355  inline Iterator upperBound( size_t i, size_t j );
356  inline ConstIterator upperBound( size_t i, size_t j ) const;
358  //**********************************************************************************************
359 
360  //**Low-level utility functions*****************************************************************
363  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
364  inline void finalize( size_t i );
366  //**********************************************************************************************
367 
368  //**Expression template evaluation functions****************************************************
371  template< typename Other > inline bool canAlias ( const Other* alias ) const;
372  template< typename Other > inline bool isAliased( const Other* alias ) const;
373  template< typename MT, bool SO2 > inline void assign ( const DenseMatrix<MT,SO2>& rhs );
374  template< typename MT > inline void assign ( const SparseMatrix<MT,SO>& rhs );
375  template< typename MT > inline void assign ( const SparseMatrix<MT,!SO>& rhs );
376  template< typename MT, bool SO2 > inline void addAssign( const DenseMatrix<MT,SO2>& rhs );
377  template< typename MT, bool SO2 > inline void addAssign( const SparseMatrix<MT,SO2>& rhs );
378  template< typename MT, bool SO2 > inline void subAssign( const DenseMatrix<MT,SO2>& rhs );
379  template< typename MT, bool SO2 > inline void subAssign( const SparseMatrix<MT,SO2>& rhs );
381  //**********************************************************************************************
382 
383  private:
384  //**Utility functions***************************************************************************
387  inline size_t extendCapacity() const;
388  void reserveElements( size_t nonzeros );
390  //**********************************************************************************************
391 
392  //**Member variables****************************************************************************
395  size_t m_;
396  size_t n_;
397  size_t capacity_;
400 
401  static const Type zero_;
402 
403  //**********************************************************************************************
404 
405  //**Compile time checks*************************************************************************
413  //**********************************************************************************************
414 };
415 //*************************************************************************************************
416 
417 
418 
419 
420 //=================================================================================================
421 //
422 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
423 //
424 //=================================================================================================
425 
426 template< typename Type, bool SO >
427 const Type CompressedMatrix<Type,SO>::zero_ = Type();
428 
429 
430 
431 
432 //=================================================================================================
433 //
434 // CONSTRUCTORS
435 //
436 //=================================================================================================
437 
438 //*************************************************************************************************
441 template< typename Type // Data type of the sparse matrix
442  , bool SO > // Storage order
444  : m_ ( 0UL ) // The current number of rows of the sparse matrix
445  , n_ ( 0UL ) // The current number of columns of the sparse matrix
446  , capacity_( 0UL ) // The current capacity of the pointer array
447  , begin_( new Iterator[2] ) // Pointers to the first non-zero element of each row
448  , end_ ( begin_+1 ) // Pointers one past the last non-zero element of each row
449 {
450  begin_[0] = end_[0] = NULL;
451 }
452 //*************************************************************************************************
453 
454 
455 //*************************************************************************************************
463 template< typename Type // Data type of the sparse matrix
464  , bool SO > // Storage order
466  : m_ ( m ) // The current number of rows of the sparse matrix
467  , n_ ( n ) // The current number of columns of the sparse matrix
468  , capacity_( m ) // The current capacity of the pointer array
469  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
470  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
471 {
472  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
473  begin_[i] = NULL;
474 }
475 //*************************************************************************************************
476 
477 
478 //*************************************************************************************************
487 template< typename Type // Data type of the sparse matrix
488  , bool SO > // Storage order
489 inline CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
490  : m_ ( m ) // The current number of rows of the sparse matrix
491  , n_ ( n ) // The current number of columns of the sparse matrix
492  , capacity_( m ) // The current capacity of the pointer array
493  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
494  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
495 {
496  begin_[0UL] = allocate<Element>( nonzeros );
497  for( size_t i=1UL; i<(2UL*m_+1UL); ++i )
498  begin_[i] = begin_[0UL];
499  end_[m_] = begin_[0UL]+nonzeros;
500 }
501 //*************************************************************************************************
502 
503 
504 //*************************************************************************************************
513 template< typename Type // Data type of the sparse matrix
514  , bool SO > // Storage order
515 CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
516  : m_ ( m ) // The current number of rows of the sparse matrix
517  , n_ ( n ) // The current number of columns of the sparse matrix
518  , capacity_( m ) // The current capacity of the pointer array
519  , begin_( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
520  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
521 {
522  BLAZE_USER_ASSERT( nonzeros.size() == m, "Size of capacity vector and number of rows don't match" );
523 
524  size_t newCapacity( 0UL );
525  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
526  newCapacity += *it;
527 
528  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
529  for( size_t i=0UL; i<m_; ++i ) {
530  begin_[i+1UL] = end_[i+1UL] = begin_[i] + nonzeros[i];
531  }
532 }
533 //*************************************************************************************************
534 
535 
536 //*************************************************************************************************
541 template< typename Type // Data type of the sparse matrix
542  , bool SO > // Storage order
544  : m_ ( sm.m_ ) // The current number of rows of the sparse matrix
545  , n_ ( sm.n_ ) // The current number of columns of the sparse matrix
546  , capacity_( sm.m_ ) // The current capacity of the pointer array
547  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
548  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
549 {
550  const size_t nonzeros( sm.nonZeros() );
551 
552  begin_[0UL] = allocate<Element>( nonzeros );
553  for( size_t i=0UL; i<m_; ++i )
554  begin_[i+1UL] = end_[i] = std::copy( sm.begin(i), sm.end(i), begin_[i] );
555  end_[m_] = begin_[0UL]+nonzeros;
556 }
557 //*************************************************************************************************
558 
559 
560 //*************************************************************************************************
565 template< typename Type // Data type of the sparse matrix
566  , bool SO > // Storage order
567 template< typename MT // Type of the foreign dense matrix
568  , bool SO2 > // Storage order of the foreign dense matrix
570  : m_ ( (~dm).rows() ) // The current number of rows of the sparse matrix
571  , n_ ( (~dm).columns() ) // The current number of columns of the sparse matrix
572  , capacity_( m_ ) // The current capacity of the pointer array
573  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
574  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
575 {
576  using blaze::assign;
577 
578  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
579  begin_[i] = NULL;
580 
581  assign( *this, ~dm );
582 }
583 //*************************************************************************************************
584 
585 
586 //*************************************************************************************************
591 template< typename Type // Data type of the sparse matrix
592  , bool SO > // Storage order
593 template< typename MT // Type of the foreign sparse matrix
594  , bool SO2 > // Storage order of the foreign sparse matrix
596  : m_ ( (~sm).rows() ) // The current number of rows of the sparse matrix
597  , n_ ( (~sm).columns() ) // The current number of columns of the sparse matrix
598  , capacity_( m_ ) // The current capacity of the pointer array
599  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
600  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
601 {
602  using blaze::assign;
603 
604  const size_t nonzeros( (~sm).nonZeros() );
605 
606  begin_[0UL] = allocate<Element>( nonzeros );
607  for( size_t i=0UL; i<m_; ++i )
608  begin_[i+1UL] = end_[i] = begin_[0UL];
609  end_[m_] = begin_[0UL]+nonzeros;
610 
611  assign( *this, ~sm );
612 }
613 //*************************************************************************************************
614 
615 
616 
617 
618 //=================================================================================================
619 //
620 // DESTRUCTOR
621 //
622 //=================================================================================================
623 
624 //*************************************************************************************************
627 template< typename Type // Data type of the sparse matrix
628  , bool SO > // Storage order
630 {
631  deallocate( begin_[0UL] );
632  delete [] begin_;
633 }
634 //*************************************************************************************************
635 
636 
637 
638 
639 //=================================================================================================
640 //
641 // DATA ACCESS FUNCTIONS
642 //
643 //=================================================================================================
644 
645 //*************************************************************************************************
652 template< typename Type // Data type of the sparse matrix
653  , bool SO > // Storage order
656 {
657  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
658  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
659 
660  return Reference( *this, i, j );
661 }
662 //*************************************************************************************************
663 
664 
665 //*************************************************************************************************
672 template< typename Type // Data type of the sparse matrix
673  , bool SO > // Storage order
675  CompressedMatrix<Type,SO>::operator()( size_t i, size_t j ) const
676 {
677  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
678  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
679 
680  const ConstIterator pos( lowerBound( i, j ) );
681 
682  if( pos == end_[i] || pos->index_ != j )
683  return zero_;
684  else
685  return pos->value_;
686 }
687 //*************************************************************************************************
688 
689 
690 //*************************************************************************************************
701 template< typename Type // Data type of the sparse matrix
702  , bool SO > // Storage order
705 {
706  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
707  return begin_[i];
708 }
709 //*************************************************************************************************
710 
711 
712 //*************************************************************************************************
723 template< typename Type // Data type of the sparse matrix
724  , bool SO > // Storage order
727 {
728  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
729  return begin_[i];
730 }
731 //*************************************************************************************************
732 
733 
734 //*************************************************************************************************
745 template< typename Type // Data type of the sparse matrix
746  , bool SO > // Storage order
749 {
750  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
751  return begin_[i];
752 }
753 //*************************************************************************************************
754 
755 
756 //*************************************************************************************************
767 template< typename Type // Data type of the sparse matrix
768  , bool SO > // Storage order
771 {
772  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
773  return end_[i];
774 }
775 //*************************************************************************************************
776 
777 
778 //*************************************************************************************************
789 template< typename Type // Data type of the sparse matrix
790  , bool SO > // Storage order
793 {
794  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
795  return end_[i];
796 }
797 //*************************************************************************************************
798 
799 
800 //*************************************************************************************************
811 template< typename Type // Data type of the sparse matrix
812  , bool SO > // Storage order
815 {
816  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
817  return end_[i];
818 }
819 //*************************************************************************************************
820 
821 
822 
823 
824 //=================================================================================================
825 //
826 // ASSIGNMENT OPERATORS
827 //
828 //=================================================================================================
829 
830 //*************************************************************************************************
839 template< typename Type // Data type of the sparse matrix
840  , bool SO > // Storage order
843 {
844  if( &rhs == this ) return *this;
845 
846  const size_t nonzeros( rhs.nonZeros() );
847 
848  if( rhs.m_ > capacity_ || nonzeros > capacity() )
849  {
850  Iterator* newBegin( new Iterator[2UL*rhs.m_+2UL] );
851  Iterator* newEnd ( newBegin+(rhs.m_+1UL) );
852 
853  newBegin[0UL] = allocate<Element>( nonzeros );
854  for( size_t i=0UL; i<rhs.m_; ++i ) {
855  newBegin[i+1UL] = newEnd[i] = std::copy( rhs.begin_[i], rhs.end_[i], newBegin[i] );
856  }
857  newEnd[rhs.m_] = newBegin[0UL]+nonzeros;
858 
859  std::swap( begin_, newBegin );
860  end_ = newEnd;
861  deallocate( newBegin[0UL] );
862  delete [] newBegin;
863  capacity_ = rhs.m_;
864  }
865  else {
866  for( size_t i=0UL; i<rhs.m_; ++i ) {
867  begin_[i+1UL] = end_[i] = std::copy( rhs.begin_[i], rhs.end_[i], begin_[i] );
868  }
869  }
870 
871  m_ = rhs.m_;
872  n_ = rhs.n_;
873 
874  return *this;
875 }
876 //*************************************************************************************************
877 
878 
879 //*************************************************************************************************
888 template< typename Type // Data type of the sparse matrix
889  , bool SO > // Storage order
890 template< typename MT // Type of the right-hand side dense matrix
891  , bool SO2 > // Storage order of the right-hand side dense matrix
894 {
895  using blaze::assign;
896 
897  if( (~rhs).canAlias( this ) ) {
898  CompressedMatrix tmp( rhs );
899  swap( tmp );
900  }
901  else {
902  resize( (~rhs).rows(), (~rhs).columns(), false );
903  assign( *this, ~rhs );
904  }
905 
906  return *this;
907 }
908 //*************************************************************************************************
909 
910 
911 //*************************************************************************************************
920 template< typename Type // Data type of the sparse matrix
921  , bool SO > // Storage order
922 template< typename MT // Type of the right-hand side sparse matrix
923  , bool SO2 > // Storage order of the right-hand side sparse matrix
926 {
927  using blaze::assign;
928 
929  if( (~rhs).canAlias( this ) ||
930  (~rhs).rows() > capacity_ ||
931  (~rhs).nonZeros() > capacity() ) {
932  CompressedMatrix tmp( rhs );
933  swap( tmp );
934  }
935  else {
936  resize( (~rhs).rows(), (~rhs).columns(), false );
937  reset();
938  assign( *this, ~rhs );
939  }
940 
941  return *this;
942 }
943 //*************************************************************************************************
944 
945 
946 //*************************************************************************************************
956 template< typename Type // Data type of the sparse matrix
957  , bool SO > // Storage order
958 template< typename MT // Type of the right-hand side matrix
959  , bool SO2 > // Storage order of the right-hand side matrix
962 {
963  using blaze::addAssign;
964 
965  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
966  throw std::invalid_argument( "Matrix sizes do not match" );
967 
968  addAssign( *this, ~rhs );
969  return *this;
970 }
971 //*************************************************************************************************
972 
973 
974 //*************************************************************************************************
984 template< typename Type // Data type of the sparse matrix
985  , bool SO > // Storage order
986 template< typename MT // Type of the right-hand side matrix
987  , bool SO2 > // Storage order of the right-hand side matrix
989 {
990  using blaze::subAssign;
991 
992  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
993  throw std::invalid_argument( "Matrix sizes do not match" );
994 
995  subAssign( *this, ~rhs );
996  return *this;
997 }
998 //*************************************************************************************************
999 
1000 
1001 //*************************************************************************************************
1011 template< typename Type // Data type of the sparse matrix
1012  , bool SO > // Storage order
1013 template< typename MT // Type of the right-hand side matrix
1014  , bool SO2 > // Storage order of the right-hand side matrix
1017 {
1018  if( (~rhs).rows() != n_ )
1019  throw std::invalid_argument( "Matrix sizes do not match" );
1020 
1021  CompressedMatrix tmp( *this * (~rhs) );
1022  swap( tmp );
1023 
1024  return *this;
1025 }
1026 //*************************************************************************************************
1027 
1028 
1029 //*************************************************************************************************
1036 template< typename Type // Data type of the sparse matrix
1037  , bool SO > // Storage order
1038 template< typename Other > // Data type of the right-hand side scalar
1039 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,SO> >::Type&
1041 {
1042  for( size_t i=0UL; i<m_; ++i ) {
1043  const Iterator last( end(i) );
1044  for( Iterator element=begin(i); element!=last; ++element )
1045  element->value_ *= rhs;
1046  }
1047 
1048  return *this;
1049 }
1050 //*************************************************************************************************
1051 
1052 
1053 //*************************************************************************************************
1060 template< typename Type // Data type of the sparse matrix
1061  , bool SO > // Storage order
1062 template< typename Other > // Data type of the right-hand side scalar
1063 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,SO> >::Type&
1065 {
1066  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1067 
1068  typedef typename DivTrait<Type,Other>::Type DT;
1069  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
1070 
1071  // Depending on the two involved data types, an integer division is applied or a
1072  // floating point division is selected.
1074  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1075  for( size_t i=0UL; i<m_; ++i ) {
1076  const Iterator last( end(i) );
1077  for( Iterator element=begin(i); element!=last; ++element )
1078  element->value_ *= tmp;
1079  }
1080  }
1081  else {
1082  for( size_t i=0UL; i<m_; ++i ) {
1083  const Iterator last( end(i) );
1084  for( Iterator element=begin(i); element!=last; ++element )
1085  element->value_ /= rhs;
1086  }
1087  }
1088 
1089  return *this;
1090 }
1091 //*************************************************************************************************
1092 
1093 
1094 
1095 
1096 //=================================================================================================
1097 //
1098 // UTILITY FUNCTIONS
1099 //
1100 //=================================================================================================
1101 
1102 //*************************************************************************************************
1107 template< typename Type // Data type of the sparse matrix
1108  , bool SO > // Storage order
1109 inline size_t CompressedMatrix<Type,SO>::rows() const
1110 {
1111  return m_;
1112 }
1113 //*************************************************************************************************
1114 
1115 
1116 //*************************************************************************************************
1121 template< typename Type // Data type of the sparse matrix
1122  , bool SO > // Storage order
1124 {
1125  return n_;
1126 }
1127 //*************************************************************************************************
1128 
1129 
1130 //*************************************************************************************************
1135 template< typename Type // Data type of the sparse matrix
1136  , bool SO > // Storage order
1138 {
1139  return end_[m_] - begin_[0UL];
1140 }
1141 //*************************************************************************************************
1142 
1143 
1144 //*************************************************************************************************
1155 template< typename Type // Data type of the sparse matrix
1156  , bool SO > // Storage order
1157 inline size_t CompressedMatrix<Type,SO>::capacity( size_t i ) const
1158 {
1159  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1160  return begin_[i+1UL] - begin_[i];
1161 }
1162 //*************************************************************************************************
1163 
1164 
1165 //*************************************************************************************************
1170 template< typename Type // Data type of the sparse matrix
1171  , bool SO > // Storage order
1173 {
1174  size_t nonzeros( 0UL );
1175 
1176  for( size_t i=0UL; i<m_; ++i )
1177  nonzeros += nonZeros( i );
1178 
1179  return nonzeros;
1180 }
1181 //*************************************************************************************************
1182 
1183 
1184 //*************************************************************************************************
1195 template< typename Type // Data type of the sparse matrix
1196  , bool SO > // Storage order
1197 inline size_t CompressedMatrix<Type,SO>::nonZeros( size_t i ) const
1198 {
1199  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1200  return end_[i] - begin_[i];
1201 }
1202 //*************************************************************************************************
1203 
1204 
1205 //*************************************************************************************************
1210 template< typename Type // Data type of the sparse matrix
1211  , bool SO > // Storage order
1213 {
1214  for( size_t i=0UL; i<m_; ++i )
1215  end_[i] = begin_[i];
1216 }
1217 //*************************************************************************************************
1218 
1219 
1220 //*************************************************************************************************
1231 template< typename Type // Data type of the sparse matrix
1232  , bool SO > // Storage order
1233 inline void CompressedMatrix<Type,SO>::reset( size_t i )
1234 {
1235  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1236  end_[i] = begin_[i];
1237 }
1238 //*************************************************************************************************
1239 
1240 
1241 //*************************************************************************************************
1248 template< typename Type // Data type of the sparse matrix
1249  , bool SO > // Storage order
1251 {
1252  end_[0UL] = end_[m_];
1253  m_ = 0UL;
1254  n_ = 0UL;
1255 }
1256 //*************************************************************************************************
1257 
1258 
1259 //*************************************************************************************************
1272 template< typename Type // Data type of the sparse matrix
1273  , bool SO > // Storage order
1275  CompressedMatrix<Type,SO>::insert( size_t i, size_t j, const Type& value )
1276 {
1277  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1278  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1279 
1280  const Iterator pos( lowerBound( i, j ) );
1281 
1282  if( pos != end_[i] && pos->index_ == j )
1283  throw std::invalid_argument( "Bad access index" );
1284 
1285  if( begin_[i+1UL] - end_[i] != 0 ) {
1286  std::copy_backward( pos, end_[i], end_[i]+1 );
1287  pos->value_ = value;
1288  pos->index_ = j;
1289  ++end_[i];
1290 
1291  return pos;
1292  }
1293  else if( end_[m_] - begin_[m_] != 0 ) {
1294  std::copy_backward( pos, end_[m_-1UL], end_[m_-1UL]+1 );
1295 
1296  pos->value_ = value;
1297  pos->index_ = j;
1298 
1299  for( size_t k=i+1UL; k<m_+1UL; ++k ) {
1300  ++begin_[k];
1301  ++end_[k-1UL];
1302  }
1303 
1304  return pos;
1305  }
1306  else {
1307  size_t newCapacity( extendCapacity() );
1308 
1309  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1310  Iterator* newEnd = newBegin+capacity_+1UL;
1311 
1312  newBegin[0UL] = allocate<Element>( newCapacity );
1313 
1314  for( size_t k=0UL; k<i; ++k ) {
1315  const size_t nonzeros( end_[k] - begin_[k] );
1316  const size_t total( begin_[k+1UL] - begin_[k] );
1317  newEnd [k] = newBegin[k] + nonzeros;
1318  newBegin[k+1UL] = newBegin[k] + total;
1319  }
1320  newEnd [i] = newBegin[i] + ( end_[i] - begin_[i] ) + 1;
1321  newBegin[i+1UL] = newBegin[i] + ( begin_[i+1] - begin_[i] ) + 1;
1322  for( size_t k=i+1UL; k<m_; ++k ) {
1323  const size_t nonzeros( end_[k] - begin_[k] );
1324  const size_t total( begin_[k+1UL] - begin_[k] );
1325  newEnd [k] = newBegin[k] + nonzeros;
1326  newBegin[k+1UL] = newBegin[k] + total;
1327  }
1328 
1329  newEnd[m_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
1330 
1331  Iterator tmp = std::copy( begin_[0UL], pos, newBegin[0UL] );
1332  tmp->value_ = value;
1333  tmp->index_ = j;
1334  std::copy( pos, end_[m_-1UL], tmp+1UL );
1335 
1336  std::swap( newBegin, begin_ );
1337  end_ = newEnd;
1338  deallocate( newBegin[0UL] );
1339  delete [] newBegin;
1340 
1341  return tmp;
1342  }
1343 }
1344 //*************************************************************************************************
1345 
1346 
1347 //*************************************************************************************************
1356 template< typename Type // Data type of the sparse matrix
1357  , bool SO > // Storage order
1358 inline void CompressedMatrix<Type,SO>::erase( size_t i, size_t j )
1359 {
1360  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1361  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1362 
1363  const Iterator pos( find( i, j ) );
1364  if( pos != end_[i] )
1365  end_[i] = std::copy( pos+1, end_[i], pos );
1366 }
1367 //*************************************************************************************************
1368 
1369 
1370 //*************************************************************************************************
1381 template< typename Type // Data type of the sparse matrix
1382  , bool SO > // Storage order
1385 {
1386  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1387  BLAZE_USER_ASSERT( pos >= begin_[i] && pos <= end_[i], "Invalid compressed matrix iterator" );
1388 
1389  if( pos != end_[i] )
1390  end_[i] = std::copy( pos+1, end_[i], pos );
1391 
1392  return pos;
1393 }
1394 //*************************************************************************************************
1395 
1396 
1397 //*************************************************************************************************
1409 template< typename Type // Data type of the sparse matrix
1410  , bool SO > // Storage order
1413 {
1414  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1415  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
1416  BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i], "Invalid compressed matrix iterator" );
1417  BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i], "Invalid compressed matrix iterator" );
1418 
1419  if( first != last )
1420  end_[i] = std::copy( last, end_[i], first );
1421 
1422  return first;
1423 }
1424 //*************************************************************************************************
1425 
1426 
1427 //*************************************************************************************************
1441 template< typename Type // Data type of the sparse matrix
1442  , bool SO > // Storage order
1443 void CompressedMatrix<Type,SO>::resize( size_t m, size_t n, bool preserve )
1444 {
1445  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1446  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1447 
1448  if( m == m_ && n == n_ ) return;
1449 
1450  if( m > capacity_ )
1451  {
1452  Iterator* newBegin( new Iterator[2UL*m+2UL] );
1453  Iterator* newEnd ( newBegin+m+1UL );
1454 
1455  newBegin[0UL] = begin_[0UL];
1456 
1457  if( preserve ) {
1458  for( size_t i=0UL; i<m_; ++i ) {
1459  newEnd [i] = end_ [i];
1460  newBegin[i+1UL] = begin_[i+1UL];
1461  }
1462  for( size_t i=m_; i<m; ++i ) {
1463  newBegin[i+1UL] = newEnd[i] = begin_[m_];
1464  }
1465  }
1466  else {
1467  for( size_t i=0UL; i<m; ++i ) {
1468  newBegin[i+1UL] = newEnd[i] = begin_[0UL];
1469  }
1470  }
1471 
1472  newEnd[m] = end_[m_];
1473 
1474  std::swap( newBegin, begin_ );
1475  delete [] newBegin;
1476 
1477  end_ = newEnd;
1478  capacity_ = m;
1479  }
1480  else if( m > m_ )
1481  {
1482  end_[m] = end_[m_];
1483 
1484  if( !preserve ) {
1485  for( size_t i=0UL; i<m_; ++i )
1486  end_[i] = begin_[i];
1487  }
1488 
1489  for( size_t i=m_; i<m; ++i )
1490  begin_[i+1UL] = end_[i] = begin_[m_];
1491  }
1492  else
1493  {
1494  if( preserve ) {
1495  for( size_t i=0UL; i<m; ++i )
1496  end_[i] = lowerBound( i, n );
1497  }
1498  else {
1499  for( size_t i=0UL; i<m; ++i )
1500  end_[i] = begin_[i];
1501  }
1502 
1503  end_[m] = end_[m_];
1504  }
1505 
1506  m_ = m;
1507  n_ = n;
1508 }
1509 //*************************************************************************************************
1510 
1511 
1512 //*************************************************************************************************
1522 template< typename Type // Data type of the sparse matrix
1523  , bool SO > // Storage order
1524 inline void CompressedMatrix<Type,SO>::reserve( size_t nonzeros )
1525 {
1526  if( nonzeros > capacity() )
1527  reserveElements( nonzeros );
1528 }
1529 //*************************************************************************************************
1530 
1531 
1532 //*************************************************************************************************
1546 template< typename Type // Data type of the sparse matrix
1547  , bool SO > // Storage order
1548 void CompressedMatrix<Type,SO>::reserve( size_t i, size_t nonzeros )
1549 {
1550  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1551 
1552  const size_t current( capacity(i) );
1553 
1554  if( current >= nonzeros ) return;
1555 
1556  const ptrdiff_t additional( nonzeros - current );
1557 
1558  if( end_[m_] - begin_[m_] < additional )
1559  {
1560  const size_t newCapacity( begin_[m_] - begin_[0UL] + additional );
1561  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
1562 
1563  Iterator* newBegin( new Iterator[2UL*m_+2UL] );
1564  Iterator* newEnd ( newBegin+m_+1UL );
1565 
1566  newBegin[0UL] = allocate<Element>( newCapacity );
1567  newEnd [m_ ] = newBegin[0UL]+newCapacity;
1568 
1569  for( size_t k=0UL; k<i; ++k ) {
1570  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
1571  newBegin[k+1UL] = newBegin[k] + capacity(k);
1572  }
1573  newEnd [i ] = std::copy( begin_[i], end_[i], newBegin[i] );
1574  newBegin[i+1UL] = newBegin[i] + nonzeros;
1575  for( size_t k=i+1UL; k<m_; ++k ) {
1576  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
1577  newBegin[k+1UL] = newBegin[k] + capacity(k);
1578  }
1579 
1580  BLAZE_INTERNAL_ASSERT( newBegin[m_] == newEnd[m_], "Invalid pointer calculations" );
1581 
1582  std::swap( newBegin, begin_ );
1583  deallocate( newBegin[0UL] );
1584  delete [] newBegin;
1585  end_ = newEnd;
1586  }
1587  else
1588  {
1589  begin_[m_] += additional;
1590  for( size_t j=m_-1UL; j>i; --j ) {
1591  begin_[j] = std::copy_backward( begin_[j], end_[j], end_[j]+additional );
1592  end_ [j] += additional;
1593  }
1594  }
1595 }
1596 //*************************************************************************************************
1597 
1598 
1599 //*************************************************************************************************
1609 template< typename Type // Data type of the sparse matrix
1610  , bool SO > // Storage order
1612 {
1613  for( size_t i=0UL; i<m_; ++i )
1614  trim( i );
1615 }
1616 //*************************************************************************************************
1617 
1618 
1619 //*************************************************************************************************
1630 template< typename Type // Data type of the sparse matrix
1631  , bool SO > // Storage order
1633 {
1634  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1635 
1636  if( i < ( m_ - 1UL ) )
1637  end_[i+1] = std::copy( begin_[i+1], end_[i+1], end_[i] );
1638  begin_[i+1] = end_[i];
1639 }
1640 //*************************************************************************************************
1641 
1642 
1643 //*************************************************************************************************
1648 template< typename Type // Data type of the sparse matrix
1649  , bool SO > // Storage order
1651 {
1652  CompressedMatrix tmp( trans( *this ) );
1653  swap( tmp );
1654  return *this;
1655 }
1656 //*************************************************************************************************
1657 
1658 
1659 //*************************************************************************************************
1665 template< typename Type // Data type of the sparse matrix
1666  , bool SO > // Storage order
1667 template< typename Other > // Data type of the scalar value
1669 {
1670  for( size_t i=0UL; i<m_; ++i )
1671  for( Iterator element=begin_[i]; element!=end_[i]; ++element )
1672  element->value_ *= scalar;
1673 
1674  return *this;
1675 }
1676 //*************************************************************************************************
1677 
1678 
1679 //*************************************************************************************************
1685 template< typename Type // Data type of the sparse matrix
1686  , bool SO > // Storage order
1687 template< typename Other > // Data type of the scalar value
1689 {
1690  const size_t size( blaze::min( m_, n_ ) );
1691 
1692  for( size_t i=0UL; i<size; ++i ) {
1693  Iterator pos = lowerBound( i, i );
1694  if( pos != end_[i] && pos->index_ == i )
1695  pos->value_ *= scalar;
1696  }
1697 
1698  return *this;
1699 }
1700 //*************************************************************************************************
1701 
1702 
1703 //*************************************************************************************************
1710 template< typename Type // Data type of the sparse matrix
1711  , bool SO > // Storage order
1712 inline void CompressedMatrix<Type,SO>::swap( CompressedMatrix& sm ) /* throw() */
1713 {
1714  std::swap( m_, sm.m_ );
1715  std::swap( n_, sm.n_ );
1716  std::swap( capacity_, sm.capacity_ );
1717  std::swap( begin_, sm.begin_ );
1718  std::swap( end_ , sm.end_ );
1719 }
1720 //*************************************************************************************************
1721 
1722 
1723 //*************************************************************************************************
1731 template< typename Type // Data type of the sparse matrix
1732  , bool SO > // Storage order
1734 {
1735  size_t nonzeros( 2UL*capacity()+1UL );
1736  nonzeros = blaze::max( nonzeros, 7UL );
1737 
1738  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
1739 
1740  return nonzeros;
1741 }
1742 //*************************************************************************************************
1743 
1744 
1745 //*************************************************************************************************
1751 template< typename Type // Data type of the sparse matrix
1752  , bool SO > // Storage order
1754 {
1755  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1756  Iterator* newEnd = newBegin+capacity_+1UL;
1757 
1758  newBegin[0UL] = allocate<Element>( nonzeros );
1759 
1760  for( size_t k=0UL; k<m_; ++k ) {
1761  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid row pointers" );
1762  newEnd [k] = std::copy( begin_[k], end_[k], newBegin[k] );
1763  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
1764  }
1765 
1766  newEnd[m_] = newBegin[0UL]+nonzeros;
1767 
1768  std::swap( newBegin, begin_ );
1769  deallocate( newBegin[0UL] );
1770  delete [] newBegin;
1771  end_ = newEnd;
1772 }
1773 //*************************************************************************************************
1774 
1775 
1776 
1777 
1778 //=================================================================================================
1779 //
1780 // LOOKUP FUNCTIONS
1781 //
1782 //=================================================================================================
1783 
1784 //*************************************************************************************************
1799 template< typename Type // Data type of the sparse matrix
1800  , bool SO > // Storage order
1802  CompressedMatrix<Type,SO>::find( size_t i, size_t j )
1803 {
1804  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
1805 }
1806 //*************************************************************************************************
1807 
1808 
1809 //*************************************************************************************************
1824 template< typename Type // Data type of the sparse matrix
1825  , bool SO > // Storage order
1827  CompressedMatrix<Type,SO>::find( size_t i, size_t j ) const
1828 {
1829  const ConstIterator pos( lowerBound( i, j ) );
1830  if( pos != end_[i] && pos->index_ == j )
1831  return pos;
1832  else return end_[i];
1833 }
1834 //*************************************************************************************************
1835 
1836 
1837 //*************************************************************************************************
1852 template< typename Type // Data type of the sparse matrix
1853  , bool SO > // Storage order
1856 {
1857  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
1858 }
1859 //*************************************************************************************************
1860 
1861 
1862 //*************************************************************************************************
1877 template< typename Type // Data type of the sparse matrix
1878  , bool SO > // Storage order
1880  CompressedMatrix<Type,SO>::lowerBound( size_t i, size_t j ) const
1881 {
1882  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1883  return std::lower_bound( begin_[i], end_[i], j, FindIndex() );
1884 }
1885 //*************************************************************************************************
1886 
1887 
1888 //*************************************************************************************************
1903 template< typename Type // Data type of the sparse matrix
1904  , bool SO > // Storage order
1907 {
1908  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
1909 }
1910 //*************************************************************************************************
1911 
1912 
1913 //*************************************************************************************************
1928 template< typename Type // Data type of the sparse matrix
1929  , bool SO > // Storage order
1931  CompressedMatrix<Type,SO>::upperBound( size_t i, size_t j ) const
1932 {
1933  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1934  return std::upper_bound( begin_[i], end_[i], j, FindIndex() );
1935 }
1936 //*************************************************************************************************
1937 
1938 
1939 
1940 
1941 //=================================================================================================
1942 //
1943 // LOW-LEVEL UTILITY FUNCTIONS
1944 //
1945 //=================================================================================================
1946 
1947 //*************************************************************************************************
1990 template< typename Type // Data type of the sparse matrix
1991  , bool SO > // Storage order
1992 inline void CompressedMatrix<Type,SO>::append( size_t i, size_t j, const Type& value, bool check )
1993 {
1994  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
1995  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
1996  BLAZE_USER_ASSERT( end_[i] < end_[m_], "Not enough reserved space left" );
1997  BLAZE_USER_ASSERT( begin_[i] == end_[i] || j > ( end_[i]-1UL )->index_, "Index is not strictly increasing" );
1998 
1999  end_[i]->value_ = value;
2000 
2001  if( !check || !isDefault( end_[i]->value_ ) ) {
2002  end_[i]->index_ = j;
2003  ++end_[i];
2004  }
2005 }
2006 //*************************************************************************************************
2007 
2008 
2009 //*************************************************************************************************
2022 template< typename Type // Data type of the sparse matrix
2023  , bool SO > // Storage order
2025 {
2026  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2027 
2028  begin_[i+1UL] = end_[i];
2029  if( i != m_-1UL )
2030  end_[i+1UL] = end_[i];
2031 }
2032 //*************************************************************************************************
2033 
2034 
2035 
2036 
2037 //=================================================================================================
2038 //
2039 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2040 //
2041 //=================================================================================================
2042 
2043 //*************************************************************************************************
2053 template< typename Type // Data type of the sparse matrix
2054  , bool SO > // Storage order
2055 template< typename Other > // Data type of the foreign expression
2056 inline bool CompressedMatrix<Type,SO>::canAlias( const Other* alias ) const
2057 {
2058  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2059 }
2060 //*************************************************************************************************
2061 
2062 
2063 //*************************************************************************************************
2073 template< typename Type // Data type of the sparse matrix
2074  , bool SO > // Storage order
2075 template< typename Other > // Data type of the foreign expression
2076 inline bool CompressedMatrix<Type,SO>::isAliased( const Other* alias ) const
2077 {
2078  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2079 }
2080 //*************************************************************************************************
2081 
2082 
2083 //*************************************************************************************************
2094 template< typename Type // Data type of the sparse matrix
2095  , bool SO > // Storage order
2096 template< typename MT // Type of the right-hand side dense matrix
2097  , bool SO2 > // Storage order of the right-hand side dense matrix
2099 {
2100  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2101  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2102 
2103  size_t nonzeros( 0UL );
2104 
2105  for( size_t i=1UL; i<=m_; ++i )
2106  begin_[i] = end_[i] = end_[m_];
2107 
2108  for( size_t i=0UL; i<m_; ++i )
2109  {
2110  begin_[i] = end_[i] = begin_[0UL]+nonzeros;
2111 
2112  for( size_t j=0UL; j<n_; ++j )
2113  {
2114  if( nonzeros == capacity() ) {
2115  reserveElements( extendCapacity() );
2116  for( size_t k=i+1UL; k<=m_; ++k )
2117  begin_[k] = end_[k] = end_[m_];
2118  }
2119 
2120  end_[i]->value_ = (~rhs)(i,j);
2121 
2122  if( !isDefault( end_[i]->value_ ) ) {
2123  end_[i]->index_ = j;
2124  ++end_[i];
2125  ++nonzeros;
2126  }
2127  }
2128  }
2129 
2130  begin_[m_] = begin_[0UL]+nonzeros;
2131 }
2132 //*************************************************************************************************
2133 
2134 
2135 //*************************************************************************************************
2146 template< typename Type // Data type of the sparse matrix
2147  , bool SO > // Storage order
2148 template< typename MT > // Type of the right-hand side sparse matrix
2150 {
2151  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2152  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2153  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2154 
2155  for( size_t i=0UL; i<(~rhs).rows(); ++i ) {
2156  begin_[i+1UL] = end_[i] = std::copy( (~rhs).begin(i), (~rhs).end(i), begin_[i] );
2157  }
2158 }
2159 //*************************************************************************************************
2160 
2161 
2162 //*************************************************************************************************
2173 template< typename Type // Data type of the sparse matrix
2174  , bool SO > // Storage order
2175 template< typename MT > // Type of the right-hand side sparse matrix
2177 {
2178  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2179  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2180  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2181 
2182  typedef typename MT::ConstIterator RhsIterator;
2183 
2184  // Counting the number of elements per row
2185  std::vector<size_t> rowLengths( m_, 0UL );
2186  for( size_t j=0UL; j<n_; ++j ) {
2187  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2188  ++rowLengths[element->index()];
2189  }
2190 
2191  // Resizing the sparse matrix
2192  for( size_t i=0UL; i<m_; ++i ) {
2193  begin_[i+1UL] = end_[i+1UL] = begin_[i] + rowLengths[i];
2194  }
2195 
2196  // Appending the elements to the rows of the sparse matrix
2197  for( size_t j=0UL; j<n_; ++j ) {
2198  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2199  append( element->index(), j, element->value() );
2200  }
2201 }
2202 //*************************************************************************************************
2203 
2204 
2205 //*************************************************************************************************
2216 template< typename Type // Data type of the sparse matrix
2217  , bool SO > // Storage order
2218 template< typename MT // Type of the right-hand side dense matrix
2219  , bool SO2 > // Storage order of the right-hand side dense matrix
2221 {
2222  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2223  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2224 
2225  CompressedMatrix tmp( *this + (~rhs) );
2226  swap( tmp );
2227 }
2228 //*************************************************************************************************
2229 
2230 
2231 //*************************************************************************************************
2242 template< typename Type // Data type of the sparse matrix
2243  , bool SO > // Storage order
2244 template< typename MT // Type of the right-hand side sparse matrix
2245  , bool SO2 > // Storage order of the right-hand side sparse matrix
2247 {
2248  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2249  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2250 
2251  CompressedMatrix tmp( *this + (~rhs) );
2252  swap( tmp );
2253 }
2254 //*************************************************************************************************
2255 
2256 
2257 //*************************************************************************************************
2268 template< typename Type // Data type of the sparse matrix
2269  , bool SO > // Storage order
2270 template< typename MT // Type of the right-hand side dense matrix
2271  , bool SO2 > // Storage order of the right-hand side dense matrix
2273 {
2274  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2275  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2276 
2277  CompressedMatrix tmp( *this - (~rhs) );
2278  swap( tmp );
2279 }
2280 //*************************************************************************************************
2281 
2282 
2283 //*************************************************************************************************
2294 template< typename Type // Data type of the sparse matrix
2295  , bool SO > // Storage order
2296 template< typename MT // Type of the right-hand side sparse matrix
2297  , bool SO2 > // Storage order of the right-hand sparse matrix
2299 {
2300  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2301  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2302 
2303  CompressedMatrix tmp( *this - (~rhs) );
2304  swap( tmp );
2305 }
2306 //*************************************************************************************************
2307 
2308 
2309 
2310 
2311 
2312 
2313 
2314 
2315 //=================================================================================================
2316 //
2317 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2318 //
2319 //=================================================================================================
2320 
2321 //*************************************************************************************************
2329 template< typename Type > // Data type of the sparse matrix
2330 class CompressedMatrix<Type,true> : public SparseMatrix< CompressedMatrix<Type,true>, true >
2331 {
2332  private:
2333  //**Type definitions****************************************************************************
2335  //**********************************************************************************************
2336 
2337  //**Private class Element***********************************************************************
2341  struct Element : public ElementBase
2342  {
2343  // This operator is required due to a bug in all versions of the the MSVC compiler.
2344  // A simple 'using ElementBase::operator=;' statement results in ambiguity problems.
2345  template< typename Other >
2346  inline Element& operator=( const Other& rhs )
2347  {
2348  ElementBase::operator=( rhs );
2349  return *this;
2350  }
2351 
2352  friend class CompressedMatrix;
2353  };
2355  //**********************************************************************************************
2356 
2357  //**Private class FindIndex*********************************************************************
2361  struct FindIndex : public std::binary_function<Element,size_t,bool>
2362  {
2363  inline bool operator()( const Element& element, size_t index ) const {
2364  return element.index() < index;
2365  }
2366  inline bool operator()( size_t index, const Element& element ) const {
2367  return index < element.index();
2368  }
2369  inline bool operator()( const Element& element1, const Element& element2 ) const {
2370  return element1.index() < element2.index();
2371  }
2372  };
2374  //**********************************************************************************************
2375 
2376  public:
2377  //**Type definitions****************************************************************************
2379  typedef This ResultType;
2382  typedef Type ElementType;
2383  typedef const Type& ReturnType;
2384  typedef const This& CompositeType;
2386  typedef const Type& ConstReference;
2387  typedef Element* Iterator;
2388  typedef const Element* ConstIterator;
2389  //**********************************************************************************************
2390 
2391  //**Compilation flags***************************************************************************
2393 
2396  enum { smpAssignable = 0 };
2397  //**********************************************************************************************
2398 
2399  //**Constructors********************************************************************************
2402  explicit inline CompressedMatrix();
2403  explicit inline CompressedMatrix( size_t m, size_t n );
2404  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
2405  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
2406  inline CompressedMatrix( const CompressedMatrix& sm );
2407  template< typename MT, bool SO > inline CompressedMatrix( const DenseMatrix<MT,SO>& dm );
2408  template< typename MT, bool SO > inline CompressedMatrix( const SparseMatrix<MT,SO>& sm );
2410  //**********************************************************************************************
2411 
2412  //**Destructor**********************************************************************************
2415  inline ~CompressedMatrix();
2417  //**********************************************************************************************
2418 
2419  //**Data access functions***********************************************************************
2422  inline Reference operator()( size_t i, size_t j );
2423  inline ConstReference operator()( size_t i, size_t j ) const;
2424  inline Iterator begin ( size_t i );
2425  inline ConstIterator begin ( size_t i ) const;
2426  inline ConstIterator cbegin( size_t i ) const;
2427  inline Iterator end ( size_t i );
2428  inline ConstIterator end ( size_t i ) const;
2429  inline ConstIterator cend ( size_t i ) const;
2431  //**********************************************************************************************
2432 
2433  //**Assignment operators************************************************************************
2436  inline CompressedMatrix& operator= ( const CompressedMatrix& rhs );
2437  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO>& rhs );
2438  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO>& rhs );
2439  template< typename MT, bool SO > inline CompressedMatrix& operator+=( const Matrix<MT,SO>& rhs );
2440  template< typename MT, bool SO > inline CompressedMatrix& operator-=( const Matrix<MT,SO>& rhs );
2441  template< typename MT, bool SO > inline CompressedMatrix& operator*=( const Matrix<MT,SO>& rhs );
2442 
2443  template< typename Other >
2444  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
2445  operator*=( Other rhs );
2446 
2447  template< typename Other >
2448  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
2449  operator/=( Other rhs );
2451  //**********************************************************************************************
2452 
2453  //**Utility functions***************************************************************************
2456  inline size_t rows() const;
2457  inline size_t columns() const;
2458  inline size_t capacity() const;
2459  inline size_t capacity( size_t j ) const;
2460  inline size_t nonZeros() const;
2461  inline size_t nonZeros( size_t j ) const;
2462  inline void reset();
2463  inline void reset( size_t j );
2464  inline void clear();
2465  Iterator insert ( size_t i, size_t j, const Type& value );
2466  inline void erase ( size_t i, size_t j );
2467  inline Iterator erase ( size_t j, Iterator pos );
2468  inline Iterator erase ( size_t j, Iterator first, Iterator last );
2469  void resize ( size_t m, size_t n, bool preserve=true );
2470  inline void reserve( size_t nonzeros );
2471  void reserve( size_t j, size_t nonzeros );
2472  inline void trim ();
2473  inline void trim ( size_t j );
2474  inline CompressedMatrix& transpose();
2475  template< typename Other > inline CompressedMatrix& scale( Other scalar );
2476  template< typename Other > inline CompressedMatrix& scaleDiagonal( Other scalar );
2477  inline void swap( CompressedMatrix& sm ) /* throw() */;
2479  //**********************************************************************************************
2480 
2481  //**Lookup functions****************************************************************************
2484  inline Iterator find ( size_t i, size_t j );
2485  inline ConstIterator find ( size_t i, size_t j ) const;
2486  inline Iterator lowerBound( size_t i, size_t j );
2487  inline ConstIterator lowerBound( size_t i, size_t j ) const;
2488  inline Iterator upperBound( size_t i, size_t j );
2489  inline ConstIterator upperBound( size_t i, size_t j ) const;
2491  //**********************************************************************************************
2492 
2493  //**Low-level utility functions*****************************************************************
2496  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
2497  inline void finalize( size_t j );
2499  //**********************************************************************************************
2500 
2501  //**Expression template evaluation functions****************************************************
2504  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2505  template< typename Other > inline bool isAliased( const Other* alias ) const;
2506  template< typename MT, bool SO > inline void assign ( const DenseMatrix<MT,SO>& rhs );
2507  template< typename MT > inline void assign ( const SparseMatrix<MT,true>& rhs );
2508  template< typename MT > inline void assign ( const SparseMatrix<MT,false>& rhs );
2509  template< typename MT, bool SO > inline void addAssign( const DenseMatrix<MT,SO>& rhs );
2510  template< typename MT, bool SO > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
2511  template< typename MT, bool SO > inline void subAssign( const DenseMatrix<MT,SO>& rhs );
2512  template< typename MT, bool SO > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
2514  //**********************************************************************************************
2515 
2516  private:
2517  //**Utility functions***************************************************************************
2520  inline size_t extendCapacity() const;
2521  void reserveElements( size_t nonzeros );
2523  //**********************************************************************************************
2524 
2525  //**Member variables****************************************************************************
2528  size_t m_;
2529  size_t n_;
2530  size_t capacity_;
2533 
2534  static const Type zero_;
2535 
2536  //**********************************************************************************************
2537 
2538  //**Compile time checks*************************************************************************
2546  //**********************************************************************************************
2547 };
2549 //*************************************************************************************************
2550 
2551 
2552 
2553 
2554 //=================================================================================================
2555 //
2556 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
2557 //
2558 //=================================================================================================
2559 
2560 template< typename Type >
2561 const Type CompressedMatrix<Type,true>::zero_ = Type();
2562 
2563 
2564 
2565 
2566 //=================================================================================================
2567 //
2568 // CONSTRUCTORS
2569 //
2570 //=================================================================================================
2571 
2572 //*************************************************************************************************
2576 template< typename Type > // Data type of the sparse matrix
2578  : m_ ( 0UL ) // The current number of rows of the sparse matrix
2579  , n_ ( 0UL ) // The current number of columns of the sparse matrix
2580  , capacity_( 0UL ) // The current capacity of the pointer array
2581  , begin_( new Iterator[2UL] ) // Pointers to the first non-zero element of each column
2582  , end_ ( begin_+1UL ) // Pointers one past the last non-zero element of each column
2583 {
2584  begin_[0UL] = end_[0UL] = NULL;
2585 }
2587 //*************************************************************************************************
2588 
2589 
2590 //*************************************************************************************************
2599 template< typename Type > // Data type of the sparse matrix
2600 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n )
2601  : m_ ( m ) // The current number of rows of the sparse matrix
2602  , n_ ( n ) // The current number of columns of the sparse matrix
2603  , capacity_( n ) // The current capacity of the pointer array
2604  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
2605  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
2606 {
2607  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
2608  begin_[j] = NULL;
2609 }
2611 //*************************************************************************************************
2612 
2613 
2614 //*************************************************************************************************
2624 template< typename Type > // Data type of the sparse matrix
2625 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
2626  : m_ ( m ) // The current number of rows of the sparse matrix
2627  , n_ ( n ) // The current number of columns of the sparse matrix
2628  , capacity_( n ) // The current capacity of the pointer array
2629  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
2630  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
2631 {
2632  begin_[0UL] = allocate<Element>( nonzeros );
2633  for( size_t j=1UL; j<(2UL*n_+1UL); ++j )
2634  begin_[j] = begin_[0UL];
2635  end_[n_] = begin_[0UL]+nonzeros;
2636 }
2638 //*************************************************************************************************
2639 
2640 
2641 //*************************************************************************************************
2651 template< typename Type > // Data type of the sparse matrix
2652 CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
2653  : m_ ( m ) // The current number of rows of the sparse matrix
2654  , n_ ( n ) // The current number of columns of the sparse matrix
2655  , capacity_( n ) // The current capacity of the pointer array
2656  , begin_( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2657  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2658 {
2659  BLAZE_USER_ASSERT( nonzeros.size() == n, "Size of capacity vector and number of columns don't match" );
2660 
2661  size_t newCapacity( 0UL );
2662  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
2663  newCapacity += *it;
2664 
2665  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
2666  for( size_t j=0UL; j<n_; ++j ) {
2667  begin_[j+1UL] = end_[j+1UL] = begin_[j] + nonzeros[j];
2668  }
2669 }
2671 //*************************************************************************************************
2672 
2673 
2674 //*************************************************************************************************
2680 template< typename Type > // Data type of the sparse matrix
2681 inline CompressedMatrix<Type,true>::CompressedMatrix( const CompressedMatrix& sm )
2682  : m_ ( sm.m_ ) // The current number of rows of the sparse matrix
2683  , n_ ( sm.n_ ) // The current number of columns of the sparse matrix
2684  , capacity_( sm.n_ ) // The current capacity of the pointer array
2685  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2686  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2687 {
2688  const size_t nonzeros( sm.nonZeros() );
2689 
2690  begin_[0UL] = allocate<Element>( nonzeros );
2691  for( size_t j=0UL; j<n_; ++j )
2692  begin_[j+1UL] = end_[j] = std::copy( sm.begin(j), sm.end(j), begin_[j] );
2693  end_[n_] = begin_[0UL]+nonzeros;
2694 }
2696 //*************************************************************************************************
2697 
2698 
2699 //*************************************************************************************************
2705 template< typename Type > // Data type of the sparse matrix
2706 template< typename MT // Type of the foreign dense matrix
2707  , bool SO > // Storage order of the foreign dense matrix
2708 inline CompressedMatrix<Type,true>::CompressedMatrix( const DenseMatrix<MT,SO>& dm )
2709  : m_ ( (~dm).rows() ) // The current number of rows of the sparse matrix
2710  , n_ ( (~dm).columns() ) // The current number of columns of the sparse matrix
2711  , capacity_( n_ ) // The current capacity of the pointer array
2712  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2713  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2714 {
2715  using blaze::assign;
2716 
2717  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
2718  begin_[j] = NULL;
2719 
2720  assign( *this, ~dm );
2721 }
2723 //*************************************************************************************************
2724 
2725 
2726 //*************************************************************************************************
2732 template< typename Type > // Data type of the sparse matrix
2733 template< typename MT // Type of the foreign sparse matrix
2734  , bool SO > // Storage order of the foreign sparse matrix
2735 inline CompressedMatrix<Type,true>::CompressedMatrix( const SparseMatrix<MT,SO>& sm )
2736  : m_ ( (~sm).rows() ) // The current number of rows of the sparse matrix
2737  , n_ ( (~sm).columns() ) // The current number of columns of the sparse matrix
2738  , capacity_( n_ ) // The current capacity of the pointer array
2739  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2740  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2741 {
2742  using blaze::assign;
2743 
2744  const size_t nonzeros( (~sm).nonZeros() );
2745 
2746  begin_[0UL] = allocate<Element>( nonzeros );
2747  for( size_t j=0UL; j<n_; ++j )
2748  begin_[j+1UL] = end_[j] = begin_[0UL];
2749  end_[n_] = begin_[0UL]+nonzeros;
2750 
2751  assign( *this, ~sm );
2752 }
2754 //*************************************************************************************************
2755 
2756 
2757 
2758 
2759 //=================================================================================================
2760 //
2761 // DESTRUCTOR
2762 //
2763 //=================================================================================================
2764 
2765 //*************************************************************************************************
2769 template< typename Type > // Data type of the sparse matrix
2770 inline CompressedMatrix<Type,true>::~CompressedMatrix()
2771 {
2772  deallocate( begin_[0UL] );
2773  delete [] begin_;
2774 }
2776 //*************************************************************************************************
2777 
2778 
2779 
2780 
2781 //=================================================================================================
2782 //
2783 // DATA ACCESS FUNCTIONS
2784 //
2785 //=================================================================================================
2786 
2787 //*************************************************************************************************
2795 template< typename Type > // Data type of the sparse matrix
2797  CompressedMatrix<Type,true>::operator()( size_t i, size_t j )
2798 {
2799  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2800  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2801 
2802  return Reference( *this, i, j );
2803 }
2805 //*************************************************************************************************
2806 
2807 
2808 //*************************************************************************************************
2816 template< typename Type > // Data type of the sparse matrix
2818  CompressedMatrix<Type,true>::operator()( size_t i, size_t j ) const
2819 {
2820  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2821  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2822 
2823  const ConstIterator pos( lowerBound( i, j ) );
2824 
2825  if( pos == end_[j] || pos->index_ != i )
2826  return zero_;
2827  else
2828  return pos->value_;
2829 }
2831 //*************************************************************************************************
2832 
2833 
2834 //*************************************************************************************************
2841 template< typename Type > // Data type of the sparse matrix
2843  CompressedMatrix<Type,true>::begin( size_t j )
2844 {
2845  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2846  return begin_[j];
2847 }
2849 //*************************************************************************************************
2850 
2851 
2852 //*************************************************************************************************
2859 template< typename Type > // Data type of the sparse matrix
2861  CompressedMatrix<Type,true>::begin( size_t j ) const
2862 {
2863  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2864  return begin_[j];
2865 }
2867 //*************************************************************************************************
2868 
2869 
2870 //*************************************************************************************************
2877 template< typename Type > // Data type of the sparse matrix
2879  CompressedMatrix<Type,true>::cbegin( size_t j ) const
2880 {
2881  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2882  return begin_[j];
2883 }
2885 //*************************************************************************************************
2886 
2887 
2888 //*************************************************************************************************
2895 template< typename Type > // Data type of the sparse matrix
2897  CompressedMatrix<Type,true>::end( size_t j )
2898 {
2899  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2900  return end_[j];
2901 }
2903 //*************************************************************************************************
2904 
2905 
2906 //*************************************************************************************************
2913 template< typename Type > // Data type of the sparse matrix
2915  CompressedMatrix<Type,true>::end( size_t j ) const
2916 {
2917  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2918  return end_[j];
2919 }
2921 //*************************************************************************************************
2922 
2923 
2924 //*************************************************************************************************
2931 template< typename Type > // Data type of the sparse matrix
2933  CompressedMatrix<Type,true>::cend( size_t j ) const
2934 {
2935  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2936  return end_[j];
2937 }
2939 //*************************************************************************************************
2940 
2941 
2942 
2943 
2944 //=================================================================================================
2945 //
2946 // ASSIGNMENT OPERATORS
2947 //
2948 //=================================================================================================
2949 
2950 //*************************************************************************************************
2960 template< typename Type > // Data type of the sparse matrix
2961 inline CompressedMatrix<Type,true>&
2962  CompressedMatrix<Type,true>::operator=( const CompressedMatrix& rhs )
2963 {
2964  if( &rhs == this ) return *this;
2965 
2966  const size_t nonzeros( rhs.nonZeros() );
2967 
2968  if( rhs.n_ > capacity_ || nonzeros > capacity() )
2969  {
2970  Iterator* newBegin( new Iterator[2UL*rhs.n_+2UL] );
2971  Iterator* newEnd ( newBegin+(rhs.n_+1UL) );
2972 
2973  newBegin[0UL] = allocate<Element>( nonzeros );
2974  for( size_t j=0UL; j<rhs.n_; ++j ) {
2975  newBegin[j+1UL] = newEnd[j] = std::copy( rhs.begin_[j], rhs.end_[j], newBegin[j] );
2976  }
2977  newEnd[rhs.n_] = newBegin[0UL]+nonzeros;
2978 
2979  std::swap( begin_, newBegin );
2980  end_ = newEnd;
2981  deallocate( newBegin[0UL] );
2982  delete [] newBegin;
2983  capacity_ = rhs.n_;
2984  }
2985  else {
2986  for( size_t j=0UL; j<rhs.n_; ++j ) {
2987  begin_[j+1UL] = end_[j] = std::copy( rhs.begin_[j], rhs.end_[j], begin_[j] );
2988  }
2989  }
2990 
2991  m_ = rhs.m_;
2992  n_ = rhs.n_;
2993 
2994  return *this;
2995 }
2997 //*************************************************************************************************
2998 
2999 
3000 //*************************************************************************************************
3010 template< typename Type > // Data type of the sparse matrix
3011 template< typename MT // Type of the right-hand side dense matrix
3012  , bool SO > // Storage order of the right-hand side dense matrix
3013 inline CompressedMatrix<Type,true>&
3014  CompressedMatrix<Type,true>::operator=( const DenseMatrix<MT,SO>& rhs )
3015 {
3016  using blaze::assign;
3017 
3018  if( (~rhs).canAlias( this ) ) {
3019  CompressedMatrix tmp( rhs );
3020  swap( tmp );
3021  }
3022  else {
3023  resize( (~rhs).rows(), (~rhs).columns(), false );
3024  assign( *this, ~rhs );
3025  }
3026 
3027  return *this;
3028 }
3030 //*************************************************************************************************
3031 
3032 
3033 //*************************************************************************************************
3043 template< typename Type > // Data type of the sparse matrix
3044 template< typename MT // Type of the right-hand side sparse matrix
3045  , bool SO > // Storage order of the right-hand side sparse matrix
3046 inline CompressedMatrix<Type,true>&
3047  CompressedMatrix<Type,true>::operator=( const SparseMatrix<MT,SO>& rhs )
3048 {
3049  using blaze::assign;
3050 
3051  if( (~rhs).canAlias( this ) ||
3052  (~rhs).columns() > capacity_ ||
3053  (~rhs).nonZeros() > capacity() ) {
3054  CompressedMatrix tmp( rhs );
3055  swap( tmp );
3056  }
3057  else {
3058  resize( (~rhs).rows(), (~rhs).columns(), false );
3059  reset();
3060  assign( *this, ~rhs );
3061  }
3062 
3063  return *this;
3064 }
3066 //*************************************************************************************************
3067 
3068 
3069 //*************************************************************************************************
3080 template< typename Type > // Data type of the sparse matrix
3081 template< typename MT // Type of the right-hand side matrix
3082  , bool SO > // Storage order of the right-hand side matrix
3083 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator+=( const Matrix<MT,SO>& rhs )
3084 {
3085  using blaze::addAssign;
3086 
3087  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
3088  throw std::invalid_argument( "Matrix sizes do not match" );
3089 
3090  addAssign( *this, ~rhs );
3091  return *this;
3092 }
3094 //*************************************************************************************************
3095 
3096 
3097 //*************************************************************************************************
3108 template< typename Type > // Data type of the sparse matrix
3109 template< typename MT // Type of the right-hand side matrix
3110  , bool SO > // Storage order of the right-hand side matrix
3111 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator-=( const Matrix<MT,SO>& rhs )
3112 {
3113  using blaze::subAssign;
3114 
3115  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
3116  throw std::invalid_argument( "Matrix sizes do not match" );
3117 
3118  subAssign( *this, ~rhs );
3119  return *this;
3120 }
3122 //*************************************************************************************************
3123 
3124 
3125 //*************************************************************************************************
3136 template< typename Type > // Data type of the sparse matrix
3137 template< typename MT // Type of the right-hand side matrix
3138  , bool SO > // Storage order of the right-hand side matrix
3139 inline CompressedMatrix<Type,true>&
3140  CompressedMatrix<Type,true>::operator*=( const Matrix<MT,SO>& rhs )
3141 {
3142  if( (~rhs).rows() != n_ )
3143  throw std::invalid_argument( "Matrix sizes do not match" );
3144 
3145  CompressedMatrix tmp( *this * (~rhs) );
3146  swap( tmp );
3147 
3148  return *this;
3149 }
3151 //*************************************************************************************************
3152 
3153 
3154 //*************************************************************************************************
3162 template< typename Type > // Data type of the sparse matrix
3163 template< typename Other > // Data type of the right-hand side scalar
3164 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,true> >::Type&
3165  CompressedMatrix<Type,true>::operator*=( Other rhs )
3166 {
3167  for( size_t j=0UL; j<n_; ++j ) {
3168  const Iterator last( end(j) );
3169  for( Iterator element=begin(j); element!=last; ++element )
3170  element->value_ *= rhs;
3171  }
3172 
3173  return *this;
3174 }
3176 //*************************************************************************************************
3177 
3178 
3179 //*************************************************************************************************
3187 template< typename Type > // Data type of the sparse matrix
3188 template< typename Other > // Data type of the right-hand side scalar
3189 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,true> >::Type&
3190  CompressedMatrix<Type,true>::operator/=( Other rhs )
3191 {
3192  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3193 
3194  typedef typename DivTrait<Type,Other>::Type DT;
3195  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
3196 
3197  // Depending on the two involved data types, an integer division is applied or a
3198  // floating point division is selected.
3199  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
3200  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
3201  for( size_t j=0UL; j<n_; ++j ) {
3202  const Iterator last( end(j) );
3203  for( Iterator element=begin(j); element!=last; ++element )
3204  element->value_ *= tmp;
3205  }
3206  }
3207  else {
3208  for( size_t j=0UL; j<n_; ++j ) {
3209  const Iterator last( end(j) );
3210  for( Iterator element=begin(j); element!=last; ++element )
3211  element->value_ /= rhs;
3212  }
3213  }
3214 
3215  return *this;
3216 }
3218 //*************************************************************************************************
3219 
3220 
3221 
3222 
3223 //=================================================================================================
3224 //
3225 // UTILITY FUNCTIONS
3226 //
3227 //=================================================================================================
3228 
3229 //*************************************************************************************************
3235 template< typename Type > // Data type of the sparse matrix
3236 inline size_t CompressedMatrix<Type,true>::rows() const
3237 {
3238  return m_;
3239 }
3241 //*************************************************************************************************
3242 
3243 
3244 //*************************************************************************************************
3250 template< typename Type > // Data type of the sparse matrix
3251 inline size_t CompressedMatrix<Type,true>::columns() const
3252 {
3253  return n_;
3254 }
3256 //*************************************************************************************************
3257 
3258 
3259 //*************************************************************************************************
3265 template< typename Type > // Data type of the sparse matrix
3266 inline size_t CompressedMatrix<Type,true>::capacity() const
3267 {
3268  return end_[n_] - begin_[0UL];
3269 }
3271 //*************************************************************************************************
3272 
3273 
3274 //*************************************************************************************************
3281 template< typename Type > // Data type of the sparse matrix
3282 inline size_t CompressedMatrix<Type,true>::capacity( size_t j ) const
3283 {
3284  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3285  return begin_[j+1UL] - begin_[j];
3286 }
3288 //*************************************************************************************************
3289 
3290 
3291 //*************************************************************************************************
3297 template< typename Type > // Data type of the sparse matrix
3298 inline size_t CompressedMatrix<Type,true>::nonZeros() const
3299 {
3300  size_t nonzeros( 0UL );
3301 
3302  for( size_t j=0UL; j<n_; ++j )
3303  nonzeros += nonZeros( j );
3304 
3305  return nonzeros;
3306 }
3308 //*************************************************************************************************
3309 
3310 
3311 //*************************************************************************************************
3318 template< typename Type > // Data type of the sparse matrix
3319 inline size_t CompressedMatrix<Type,true>::nonZeros( size_t j ) const
3320 {
3321  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3322  return end_[j] - begin_[j];
3323 }
3325 //*************************************************************************************************
3326 
3327 
3328 //*************************************************************************************************
3334 template< typename Type > // Data type of the sparse matrix
3336 {
3337  for( size_t j=0UL; j<n_; ++j )
3338  end_[j] = begin_[j];
3339 }
3341 //*************************************************************************************************
3342 
3343 
3344 //*************************************************************************************************
3354 template< typename Type > // Data type of the sparse matrix
3355 inline void CompressedMatrix<Type,true>::reset( size_t j )
3356 {
3357  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3358  end_[j] = begin_[j];
3359 }
3361 //*************************************************************************************************
3362 
3363 
3364 //*************************************************************************************************
3372 template< typename Type > // Data type of the sparse matrix
3374 {
3375  end_[0UL] = end_[n_];
3376  m_ = 0UL;
3377  n_ = 0UL;
3378 }
3380 //*************************************************************************************************
3381 
3382 
3383 //*************************************************************************************************
3397 template< typename Type > // Data type of the sparse matrix
3399  CompressedMatrix<Type,true>::insert( size_t i, size_t j, const Type& value )
3400 {
3401  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3402  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3403 
3404  const Iterator pos( lowerBound( i, j ) );
3405 
3406  if( pos != end_[j] && pos->index_ == i )
3407  throw std::invalid_argument( "Bad access index" );
3408 
3409  if( begin_[j+1UL] - end_[j] != 0 ) {
3410  std::copy_backward( pos, end_[j], end_[j]+1 );
3411  pos->value_ = value;
3412  pos->index_ = i;
3413  ++end_[j];
3414 
3415  return pos;
3416  }
3417  else if( end_[n_] - begin_[n_] != 0 ) {
3418  std::copy_backward( pos, end_[n_-1UL], end_[n_-1]+1 );
3419 
3420  pos->value_ = value;
3421  pos->index_ = i;
3422 
3423  for( size_t k=j+1UL; k<n_+1UL; ++k ) {
3424  ++begin_[k];
3425  ++end_[k-1UL];
3426  }
3427 
3428  return pos;
3429  }
3430  else {
3431  size_t newCapacity( extendCapacity() );
3432 
3433  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
3434  Iterator* newEnd = newBegin+capacity_+1UL;
3435 
3436  newBegin[0UL] = allocate<Element>( newCapacity );
3437 
3438  for( size_t k=0UL; k<j; ++k ) {
3439  const size_t nonzeros( end_[k] - begin_[k] );
3440  const size_t total( begin_[k+1UL] - begin_[k] );
3441  newEnd [k] = newBegin[k] + nonzeros;
3442  newBegin[k+1UL] = newBegin[k] + total;
3443  }
3444  newEnd [j] = newBegin[j] + ( end_[j] - begin_[j] ) + 1;
3445  newBegin[j+1UL] = newBegin[j] + ( begin_[j+1UL] - begin_[j] ) + 1;
3446  for( size_t k=j+1UL; k<n_; ++k ) {
3447  const size_t nonzeros( end_[k] - begin_[k] );
3448  const size_t total( begin_[k+1UL] - begin_[k] );
3449  newEnd [k] = newBegin[k] + nonzeros;
3450  newBegin[k+1UL] = newBegin[k] + total;
3451  }
3452 
3453  newEnd[n_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
3454 
3455  Iterator tmp = std::copy( begin_[0UL], pos, newBegin[0UL] );
3456  tmp->value_ = value;
3457  tmp->index_ = i;
3458  std::copy( pos, end_[n_-1UL], tmp+1UL );
3459 
3460  std::swap( newBegin, begin_ );
3461  end_ = newEnd;
3462  deallocate( newBegin[0UL] );
3463  delete [] newBegin;
3464 
3465  return tmp;
3466  }
3467 }
3469 //*************************************************************************************************
3470 
3471 
3472 //*************************************************************************************************
3482 template< typename Type > // Data type of the sparse matrix
3483 inline void CompressedMatrix<Type,true>::erase( size_t i, size_t j )
3484 {
3485  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3486  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3487 
3488  const Iterator pos( find( i, j ) );
3489  if( pos != end_[j] )
3490  end_[j] = std::copy( pos+1, end_[j], pos );
3491 }
3493 //*************************************************************************************************
3494 
3495 
3496 //*************************************************************************************************
3506 template< typename Type > // Data type of the sparse matrix
3508  CompressedMatrix<Type,true>::erase( size_t j, Iterator pos )
3509 {
3510  BLAZE_USER_ASSERT( j < columns() , "Invalid row access index" );
3511  BLAZE_USER_ASSERT( pos >= begin_[j] && pos <= end_[j], "Invalid compressed matrix iterator" );
3512 
3513  if( pos != end_[j] )
3514  end_[j] = std::copy( pos+1, end_[j], pos );
3515 
3516  return pos;
3517 }
3519 //*************************************************************************************************
3520 
3521 
3522 //*************************************************************************************************
3533 template< typename Type > // Data type of the sparse matrix
3535  CompressedMatrix<Type,true>::erase( size_t j, Iterator first, Iterator last )
3536 {
3537  BLAZE_USER_ASSERT( j < columns(), "Invalid row access index" );
3538  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
3539  BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j], "Invalid compressed matrix iterator" );
3540  BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j], "Invalid compressed matrix iterator" );
3541 
3542  if( first != last )
3543  end_[j] = std::copy( last, end_[j], first );
3544 
3545  return first;
3546 }
3548 //*************************************************************************************************
3549 
3550 
3551 //*************************************************************************************************
3566 template< typename Type > // Data type of the sparse matrix
3567 void CompressedMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
3568 {
3569  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
3570  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
3571 
3572  if( m == m_ && n == n_ ) return;
3573 
3574  if( n > capacity_ )
3575  {
3576  Iterator* newBegin( new Iterator[2UL*n+2UL] );
3577  Iterator* newEnd ( newBegin+n+1UL );
3578 
3579  newBegin[0UL] = begin_[0UL];
3580 
3581  if( preserve ) {
3582  for( size_t j=0UL; j<n_; ++j ) {
3583  newEnd [j] = end_ [j];
3584  newBegin[j+1UL] = begin_[j+1UL];
3585  }
3586  for( size_t j=n_; j<n; ++j ) {
3587  newBegin[j+1UL] = newEnd[j] = begin_[n_];
3588  }
3589  }
3590  else {
3591  for( size_t j=0UL; j<n; ++j ) {
3592  newBegin[j+1UL] = newEnd[j] = begin_[0UL];
3593  }
3594  }
3595 
3596  newEnd[n] = end_[n_];
3597 
3598  std::swap( newBegin, begin_ );
3599  delete [] newBegin;
3600 
3601  end_ = newEnd;
3602  capacity_ = n;
3603  }
3604  else if( n > n_ )
3605  {
3606  end_[n] = end_[n_];
3607 
3608  if( !preserve ) {
3609  for( size_t j=0UL; j<n_; ++j )
3610  end_[j] = begin_[j];
3611  }
3612 
3613  for( size_t j=n_; j<n; ++j )
3614  begin_[j+1UL] = end_[j] = begin_[n_];
3615  }
3616  else
3617  {
3618  if( preserve ) {
3619  for( size_t j=0UL; j<n; ++j )
3620  end_[j] = lowerBound( m, j );
3621  }
3622  else {
3623  for( size_t j=0UL; j<n; ++j )
3624  end_[j] = begin_[j];
3625  }
3626 
3627  end_[n] = end_[n_];
3628  }
3629 
3630  m_ = m;
3631  n_ = n;
3632 }
3634 //*************************************************************************************************
3635 
3636 
3637 //*************************************************************************************************
3648 template< typename Type > // Data type of the sparse matrix
3649 inline void CompressedMatrix<Type,true>::reserve( size_t nonzeros )
3650 {
3651  if( nonzeros > capacity() )
3652  reserveElements( nonzeros );
3653 }
3655 //*************************************************************************************************
3656 
3657 
3658 //*************************************************************************************************
3670 template< typename Type > // Data type of the sparse matrix
3671 void CompressedMatrix<Type,true>::reserve( size_t j, size_t nonzeros )
3672 {
3673  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3674 
3675  const size_t current( capacity(j) );
3676 
3677  if( current >= nonzeros ) return;
3678 
3679  const ptrdiff_t additional( nonzeros - current );
3680 
3681  if( end_[n_] - begin_[n_] < additional )
3682  {
3683  const size_t newCapacity( begin_[n_] - begin_[0UL] + additional );
3684  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
3685 
3686  Iterator* newBegin( new Iterator[2UL*n_+2UL] );
3687  Iterator* newEnd ( newBegin+n_+1UL );
3688 
3689  newBegin[0UL] = allocate<Element>( newCapacity );
3690  newEnd [n_ ] = newBegin[0UL]+newCapacity;
3691 
3692  for( size_t k=0UL; k<j; ++k ) {
3693  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
3694  newBegin[k+1UL] = newBegin[k] + capacity(k);
3695  }
3696  newEnd [j ] = std::copy( begin_[j], end_[j], newBegin[j] );
3697  newBegin[j+1UL] = newBegin[j] + nonzeros;
3698  for( size_t k=j+1UL; k<n_; ++k ) {
3699  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
3700  newBegin[k+1UL] = newBegin[k] + capacity(k);
3701  }
3702 
3703  BLAZE_INTERNAL_ASSERT( newBegin[n_] == newEnd[n_], "Invalid pointer calculations" );
3704 
3705  std::swap( newBegin, begin_ );
3706  deallocate( newBegin[0UL] );
3707  delete [] newBegin;
3708  end_ = newEnd;
3709  }
3710  else
3711  {
3712  begin_[n_] += additional;
3713  for( size_t k=n_-1UL; k>j; --k ) {
3714  begin_[k] = std::copy_backward( begin_[k], end_[k], end_[k]+additional );
3715  end_ [k] += additional;
3716  }
3717  }
3718 }
3720 //*************************************************************************************************
3721 
3722 
3723 //*************************************************************************************************
3733 template< typename Type > // Data type of the sparse matrix
3734 void CompressedMatrix<Type,true>::trim()
3735 {
3736  for( size_t j=0UL; j<n_; ++j )
3737  trim( j );
3738 }
3740 //*************************************************************************************************
3741 
3742 
3743 //*************************************************************************************************
3754 template< typename Type > // Data type of the sparse matrix
3755 void CompressedMatrix<Type,true>::trim( size_t j )
3756 {
3757  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3758 
3759  if( j < ( n_ - 1UL ) )
3760  end_[j+1] = std::copy( begin_[j+1], end_[j+1], end_[j] );
3761  begin_[j+1] = end_[j];
3762 }
3764 //*************************************************************************************************
3765 
3766 
3767 //*************************************************************************************************
3773 template< typename Type > // Data type of the sparse matrix
3774 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::transpose()
3775 {
3776  CompressedMatrix tmp( trans( *this ) );
3777  swap( tmp );
3778  return *this;
3779 }
3781 //*************************************************************************************************
3782 
3783 
3784 //*************************************************************************************************
3791 template< typename Type > // Data type of the sparse matrix
3792 template< typename Other > // Data type of the scalar value
3793 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scale( Other scalar )
3794 {
3795  for( size_t j=0UL; j<n_; ++j )
3796  for( Iterator element=begin_[j]; element!=end_[j]; ++element )
3797  element->value_ *= scalar;
3798 
3799  return *this;
3800 }
3802 //*************************************************************************************************
3803 
3804 
3805 //*************************************************************************************************
3812 template< typename Type > // Data type of the sparse matrix
3813 template< typename Other > // Data type of the scalar value
3814 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scaleDiagonal( Other scalar )
3815 {
3816  const size_t size( blaze::min( m_, n_ ) );
3817 
3818  for( size_t j=0UL; j<size; ++j ) {
3819  Iterator pos = lowerBound( j, j );
3820  if( pos != end_[j] && pos->index_ == j )
3821  pos->value_ *= scalar;
3822  }
3823 
3824  return *this;
3825 }
3827 //*************************************************************************************************
3828 
3829 
3830 //*************************************************************************************************
3838 template< typename Type > // Data type of the sparse matrix
3839 inline void CompressedMatrix<Type,true>::swap( CompressedMatrix& sm ) /* throw() */
3840 {
3841  std::swap( m_, sm.m_ );
3842  std::swap( n_, sm.n_ );
3843  std::swap( capacity_, sm.capacity_ );
3844  std::swap( begin_, sm.begin_ );
3845  std::swap( end_ , sm.end_ );
3846 }
3848 //*************************************************************************************************
3849 
3850 
3851 //*************************************************************************************************
3860 template< typename Type > // Data type of the sparse matrix
3861 inline size_t CompressedMatrix<Type,true>::extendCapacity() const
3862 {
3863  size_t nonzeros( 2UL*capacity()+1UL );
3864  nonzeros = blaze::max( nonzeros, 7UL );
3865 
3866  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
3867 
3868  return nonzeros;
3869 }
3871 //*************************************************************************************************
3872 
3873 
3874 //*************************************************************************************************
3881 template< typename Type > // Data type of the sparse matrix
3882 void CompressedMatrix<Type,true>::reserveElements( size_t nonzeros )
3883 {
3884  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
3885  Iterator* newEnd = newBegin+capacity_+1UL;
3886 
3887  newBegin[0UL] = allocate<Element>( nonzeros );
3888 
3889  for( size_t k=0UL; k<n_; ++k ) {
3890  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid column pointers" );
3891  newEnd [k] = std::copy( begin_[k], end_[k], newBegin[k] );
3892  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
3893  }
3894 
3895  newEnd[n_] = newBegin[0UL]+nonzeros;
3896 
3897  std::swap( newBegin, begin_ );
3898  deallocate( newBegin[0UL] );
3899  delete [] newBegin;
3900  end_ = newEnd;
3901 }
3903 //*************************************************************************************************
3904 
3905 
3906 
3907 
3908 //=================================================================================================
3909 //
3910 // LOOKUP FUNCTIONS
3911 //
3912 //=================================================================================================
3913 
3914 //*************************************************************************************************
3929 template< typename Type > // Data type of the sparse matrix
3931  CompressedMatrix<Type,true>::find( size_t i, size_t j )
3932 {
3933  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
3934 }
3936 //*************************************************************************************************
3937 
3938 
3939 //*************************************************************************************************
3954 template< typename Type > // Data type of the sparse matrix
3956  CompressedMatrix<Type,true>::find( size_t i, size_t j ) const
3957 {
3958  const ConstIterator pos( lowerBound( i, j ) );
3959  if( pos != end_[j] && pos->index_ == i )
3960  return pos;
3961  else return end_[j];
3962 }
3964 //*************************************************************************************************
3965 
3966 
3967 //*************************************************************************************************
3981 template< typename Type > // Data type of the sparse matrix
3983  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j )
3984 {
3985  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
3986 }
3988 //*************************************************************************************************
3989 
3990 
3991 //*************************************************************************************************
4005 template< typename Type > // Data type of the sparse matrix
4007  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j ) const
4008 {
4009  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4010  return std::lower_bound( begin_[j], end_[j], i, FindIndex() );
4011 }
4013 //*************************************************************************************************
4014 
4015 
4016 //*************************************************************************************************
4030 template< typename Type > // Data type of the sparse matrix
4032  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j )
4033 {
4034  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
4035 }
4037 //*************************************************************************************************
4038 
4039 
4040 //*************************************************************************************************
4054 template< typename Type > // Data type of the sparse matrix
4056  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j ) const
4057 {
4058  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4059  return std::upper_bound( begin_[j], end_[j], i, FindIndex() );
4060 }
4062 //*************************************************************************************************
4063 
4064 
4065 
4066 
4067 //=================================================================================================
4068 //
4069 // LOW-LEVEL UTILITY FUNCTIONS
4070 //
4071 //=================================================================================================
4072 
4073 //*************************************************************************************************
4114 template< typename Type > // Data type of the sparse matrix
4115 inline void CompressedMatrix<Type,true>::append( size_t i, size_t j, const Type& value, bool check )
4116 {
4117  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
4118  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
4119  BLAZE_USER_ASSERT( end_[j] < end_[n_], "Not enough reserved space left" );
4120  BLAZE_USER_ASSERT( begin_[j] == end_[j] || i > ( end_[j]-1UL )->index_, "Index is not strictly increasing" );
4121 
4122  end_[j]->value_ = value;
4123 
4124  if( !check || !isDefault( end_[j]->value_ ) ) {
4125  end_[j]->index_ = i;
4126  ++end_[j];
4127  }
4128 }
4130 //*************************************************************************************************
4131 
4132 
4133 //*************************************************************************************************
4147 template< typename Type > // Data type of the sparse matrix
4148 inline void CompressedMatrix<Type,true>::finalize( size_t j )
4149 {
4150  BLAZE_USER_ASSERT( j < n_, "Invalid row access index" );
4151 
4152  begin_[j+1UL] = end_[j];
4153  if( j != n_-1UL )
4154  end_[j+1UL] = end_[j];
4155 }
4157 //*************************************************************************************************
4158 
4159 
4160 
4161 
4162 //=================================================================================================
4163 //
4164 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4165 //
4166 //=================================================================================================
4167 
4168 //*************************************************************************************************
4179 template< typename Type > // Data type of the sparse matrix
4180 template< typename Other > // Data type of the foreign expression
4181 inline bool CompressedMatrix<Type,true>::canAlias( const Other* alias ) const
4182 {
4183  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4184 }
4186 //*************************************************************************************************
4187 
4188 
4189 //*************************************************************************************************
4200 template< typename Type > // Data type of the sparse matrix
4201 template< typename Other > // Data type of the foreign expression
4202 inline bool CompressedMatrix<Type,true>::isAliased( const Other* alias ) const
4203 {
4204  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4205 }
4207 //*************************************************************************************************
4208 
4209 
4210 //*************************************************************************************************
4222 template< typename Type > // Data type of the sparse matrix
4223 template< typename MT // Type of the right-hand side dense matrix
4224  , bool SO > // Storage order of the right-hand side dense matrix
4225 inline void CompressedMatrix<Type,true>::assign( const DenseMatrix<MT,SO>& rhs )
4226 {
4227  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4228  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4229 
4230  size_t nonzeros( 0UL );
4231 
4232  for( size_t j=1UL; j<=n_; ++j )
4233  begin_[j] = end_[j] = end_[n_];
4234 
4235  for( size_t j=0UL; j<n_; ++j )
4236  {
4237  begin_[j] = end_[j] = begin_[0UL]+nonzeros;
4238 
4239  for( size_t i=0UL; i<m_; ++i )
4240  {
4241  if( nonzeros == capacity() ) {
4242  reserveElements( extendCapacity() );
4243  for( size_t k=j+1UL; k<=n_; ++k )
4244  begin_[k] = end_[k] = end_[n_];
4245  }
4246 
4247  end_[j]->value_ = (~rhs)(i,j);
4248 
4249  if( !isDefault( end_[j]->value_ ) ) {
4250  end_[j]->index_ = i;
4251  ++end_[j];
4252  ++nonzeros;
4253  }
4254  }
4255  }
4256 
4257  begin_[n_] = begin_[0UL]+nonzeros;
4258 }
4260 //*************************************************************************************************
4261 
4262 
4263 //*************************************************************************************************
4275 template< typename Type > // Data type of the sparse matrix
4276 template< typename MT > // Type of the right-hand side sparse matrix
4277 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,true>& rhs )
4278 {
4279  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4280  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4281  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4282 
4283  for( size_t j=0UL; j<(~rhs).columns(); ++j ) {
4284  begin_[j+1UL] = end_[j] = std::copy( (~rhs).begin(j), (~rhs).end(j), begin_[j] );
4285  }
4286 }
4288 //*************************************************************************************************
4289 
4290 
4291 //*************************************************************************************************
4303 template< typename Type > // Data type of the sparse matrix
4304 template< typename MT > // Type of the right-hand side sparse matrix
4305 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,false>& rhs )
4306 {
4307  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4308  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4309  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4310 
4311  typedef typename MT::ConstIterator RhsIterator;
4312 
4313  // Counting the number of elements per column
4314  std::vector<size_t> columnLengths( n_, 0UL );
4315  for( size_t i=0UL; i<m_; ++i ) {
4316  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4317  ++columnLengths[element->index()];
4318  }
4319 
4320  // Resizing the sparse matrix
4321  for( size_t j=0UL; j<n_; ++j ) {
4322  begin_[j+1UL] = end_[j+1UL] = begin_[j] + columnLengths[j];
4323  }
4324 
4325  // Appending the elements to the columns of the sparse matrix
4326  for( size_t i=0UL; i<m_; ++i ) {
4327  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4328  append( i, element->index(), element->value() );
4329  }
4330 }
4332 //*************************************************************************************************
4333 
4334 
4335 //*************************************************************************************************
4347 template< typename Type > // Data type of the sparse matrix
4348 template< typename MT // Type of the right-hand side dense matrix
4349  , bool SO > // Storage order of the right-hand side dense matrix
4350 inline void CompressedMatrix<Type,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
4351 {
4352  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4353  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4354 
4355  CompressedMatrix tmp( *this + (~rhs) );
4356  swap( tmp );
4357 }
4359 //*************************************************************************************************
4360 
4361 
4362 //*************************************************************************************************
4374 template< typename Type > // Data type of the sparse matrix
4375 template< typename MT // Type of the right-hand side sparse matrix
4376  , bool SO > // Storage order of the right-hand side sparse matrix
4377 inline void CompressedMatrix<Type,true>::addAssign( const SparseMatrix<MT,SO>& rhs )
4378 {
4379  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4380  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4381 
4382  CompressedMatrix tmp( *this + (~rhs) );
4383  swap( tmp );
4384 }
4386 //*************************************************************************************************
4387 
4388 
4389 //*************************************************************************************************
4401 template< typename Type > // Data type of the sparse matrix
4402 template< typename MT // Type of the right-hand side dense matrix
4403  , bool SO > // Storage order of the right-hand side dense matrix
4404 inline void CompressedMatrix<Type,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
4405 {
4406  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4407  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4408 
4409  CompressedMatrix tmp( *this - (~rhs) );
4410  swap( tmp );
4411 }
4413 //*************************************************************************************************
4414 
4415 
4416 //*************************************************************************************************
4428 template< typename Type > // Data type of the sparse matrix
4429 template< typename MT // Type of the right-hand side sparse matrix
4430  , bool SO > // Storage order of the right-hand side sparse matrix
4431 inline void CompressedMatrix<Type,true>::subAssign( const SparseMatrix<MT,SO>& rhs )
4432 {
4433  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4434  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4435 
4436  CompressedMatrix tmp( *this - (~rhs) );
4437  swap( tmp );
4438 }
4440 //*************************************************************************************************
4441 
4442 
4443 
4444 
4445 
4446 
4447 
4448 
4449 //=================================================================================================
4450 //
4451 // COMPRESSEDMATRIX OPERATORS
4452 //
4453 //=================================================================================================
4454 
4455 //*************************************************************************************************
4458 template< typename Type, bool SO >
4459 inline void reset( CompressedMatrix<Type,SO>& m );
4460 
4461 template< typename Type, bool SO >
4462 inline void clear( CompressedMatrix<Type,SO>& m );
4463 
4464 template< typename Type, bool SO >
4465 inline bool isDefault( const CompressedMatrix<Type,SO>& m );
4466 
4467 template< typename Type, bool SO >
4468 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) /* throw() */;
4470 //*************************************************************************************************
4471 
4472 
4473 //*************************************************************************************************
4480 template< typename Type // Data type of the sparse matrix
4481  , bool SO > // Storage order
4482 inline void reset( CompressedMatrix<Type,SO>& m )
4483 {
4484  m.reset();
4485 }
4486 //*************************************************************************************************
4487 
4488 
4489 //*************************************************************************************************
4496 template< typename Type // Data type of the sparse matrix
4497  , bool SO > // Storage order
4498 inline void clear( CompressedMatrix<Type,SO>& m )
4499 {
4500  m.clear();
4501 }
4502 //*************************************************************************************************
4503 
4504 
4505 //*************************************************************************************************
4523 template< typename Type // Data type of the sparse matrix
4524  , bool SO > // Storage order
4525 inline bool isDefault( const CompressedMatrix<Type,SO>& m )
4526 {
4528 
4529  if( SO == rowMajor ) {
4530  for( size_t i=0UL; i<m.rows(); ++i ) {
4531  for( ConstIterator element=m.begin(i); element!=m.end(i); ++element )
4532  if( !isDefault( element->value() ) ) return false;
4533  }
4534  }
4535  else {
4536  for( size_t j=0UL; j<m.columns(); ++j ) {
4537  for( ConstIterator element=m.begin(j); element!=m.end(j); ++element )
4538  if( !isDefault( element->value() ) ) return false;
4539  }
4540  }
4541 
4542  return true;
4543 }
4544 //*************************************************************************************************
4545 
4546 
4547 //*************************************************************************************************
4556 template< typename Type // Data type of the sparse matrix
4557  , bool SO > // Storage order
4558 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) /* throw() */
4559 {
4560  a.swap( b );
4561 }
4562 //*************************************************************************************************
4563 
4564 
4565 
4566 
4567 //=================================================================================================
4568 //
4569 // ISRESIZABLE SPECIALIZATIONS
4570 //
4571 //=================================================================================================
4572 
4573 //*************************************************************************************************
4575 template< typename T, bool SO >
4576 struct IsResizable< CompressedMatrix<T,SO> > : public TrueType
4577 {
4578  enum { value = 1 };
4579  typedef TrueType Type;
4580 };
4581 
4582 template< typename T, bool SO >
4583 struct IsResizable< const CompressedMatrix<T,SO> > : public TrueType
4584 {
4585  enum { value = 1 };
4586  typedef TrueType Type;
4587 };
4588 
4589 template< typename T, bool SO >
4590 struct IsResizable< volatile CompressedMatrix<T,SO> > : public TrueType
4591 {
4592  enum { value = 1 };
4593  typedef TrueType Type;
4594 };
4595 
4596 template< typename T, bool SO >
4597 struct IsResizable< const volatile CompressedMatrix<T,SO> > : public TrueType
4598 {
4599  enum { value = 1 };
4600  typedef TrueType Type;
4601 };
4603 //*************************************************************************************************
4604 
4605 
4606 
4607 
4608 //=================================================================================================
4609 //
4610 // ADDTRAIT SPECIALIZATIONS
4611 //
4612 //=================================================================================================
4613 
4614 //*************************************************************************************************
4616 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4617 struct AddTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4618 {
4619  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4620 };
4621 
4622 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4623 struct AddTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4624 {
4625  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
4626 };
4627 
4628 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4629 struct AddTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4630 {
4631  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4632 };
4633 
4634 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4635 struct AddTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4636 {
4637  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
4638 };
4639 
4640 template< typename T1, bool SO, typename T2 >
4641 struct AddTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4642 {
4643  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4644 };
4645 
4646 template< typename T1, bool SO1, typename T2, bool SO2 >
4647 struct AddTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4648 {
4649  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4650 };
4651 
4652 template< typename T1, bool SO, typename T2 >
4653 struct AddTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4654 {
4655  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4656 };
4657 
4658 template< typename T1, bool SO1, typename T2, bool SO2 >
4659 struct AddTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4660 {
4661  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4662 };
4663 
4664 template< typename T1, bool SO, typename T2 >
4665 struct AddTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4666 {
4667  typedef CompressedMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4668 };
4669 
4670 template< typename T1, bool SO1, typename T2, bool SO2 >
4671 struct AddTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4672 {
4673  typedef CompressedMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4674 };
4676 //*************************************************************************************************
4677 
4678 
4679 
4680 
4681 //=================================================================================================
4682 //
4683 // SUBTRAIT SPECIALIZATIONS
4684 //
4685 //=================================================================================================
4686 
4687 //*************************************************************************************************
4689 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4690 struct SubTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4691 {
4692  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4693 };
4694 
4695 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4696 struct SubTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4697 {
4698  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
4699 };
4700 
4701 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4702 struct SubTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4703 {
4704  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4705 };
4706 
4707 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4708 struct SubTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4709 {
4710  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
4711 };
4712 
4713 template< typename T1, bool SO, typename T2 >
4714 struct SubTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4715 {
4716  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4717 };
4718 
4719 template< typename T1, bool SO1, typename T2, bool SO2 >
4720 struct SubTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4721 {
4722  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , false > Type;
4723 };
4724 
4725 template< typename T1, bool SO, typename T2 >
4726 struct SubTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4727 {
4728  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4729 };
4730 
4731 template< typename T1, bool SO1, typename T2, bool SO2 >
4732 struct SubTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4733 {
4734  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , false > Type;
4735 };
4736 
4737 template< typename T1, bool SO, typename T2 >
4738 struct SubTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4739 {
4740  typedef CompressedMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4741 };
4742 
4743 template< typename T1, bool SO1, typename T2, bool SO2 >
4744 struct SubTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4745 {
4746  typedef CompressedMatrix< typename SubTrait<T1,T2>::Type , false > Type;
4747 };
4749 //*************************************************************************************************
4750 
4751 
4752 
4753 
4754 //=================================================================================================
4755 //
4756 // MULTTRAIT SPECIALIZATIONS
4757 //
4758 //=================================================================================================
4759 
4760 //*************************************************************************************************
4762 template< typename T1, bool SO, typename T2 >
4763 struct MultTrait< CompressedMatrix<T1,SO>, T2 >
4764 {
4765  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
4767 };
4768 
4769 template< typename T1, typename T2, bool SO >
4770 struct MultTrait< T1, CompressedMatrix<T2,SO> >
4771 {
4772  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
4774 };
4775 
4776 template< typename T1, bool SO, typename T2, size_t N >
4777 struct MultTrait< CompressedMatrix<T1,SO>, StaticVector<T2,N,false> >
4778 {
4779  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4780 };
4781 
4782 template< typename T1, size_t N, typename T2, bool SO >
4783 struct MultTrait< StaticVector<T1,N,true>, CompressedMatrix<T2,SO> >
4784 {
4785  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4786 };
4787 
4788 template< typename T1, bool SO, typename T2, size_t N >
4789 struct MultTrait< CompressedMatrix<T1,SO>, HybridVector<T2,N,false> >
4790 {
4791  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4792 };
4793 
4794 template< typename T1, size_t N, typename T2, bool SO >
4795 struct MultTrait< HybridVector<T1,N,true>, CompressedMatrix<T2,SO> >
4796 {
4797  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4798 };
4799 
4800 template< typename T1, bool SO, typename T2 >
4801 struct MultTrait< CompressedMatrix<T1,SO>, DynamicVector<T2,false> >
4802 {
4803  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4804 };
4805 
4806 template< typename T1, typename T2, bool SO >
4807 struct MultTrait< DynamicVector<T1,true>, CompressedMatrix<T2,SO> >
4808 {
4809  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4810 };
4811 
4812 template< typename T1, bool SO, typename T2 >
4813 struct MultTrait< CompressedMatrix<T1,SO>, CompressedVector<T2,false> >
4814 {
4815  typedef CompressedVector< typename MultTrait<T1,T2>::Type, false > Type;
4816 };
4817 
4818 template< typename T1, typename T2, bool SO >
4819 struct MultTrait< CompressedVector<T1,true>, CompressedMatrix<T2,SO> >
4820 {
4821  typedef CompressedVector< typename MultTrait<T1,T2>::Type, true > Type;
4822 };
4823 
4824 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4825 struct MultTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4826 {
4827  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4828 };
4829 
4830 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4831 struct MultTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4832 {
4833  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4834 };
4835 
4836 template< typename T1, bool SO1, typename T2, bool SO2 >
4837 struct MultTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4838 {
4839  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4840 };
4841 
4842 template< typename T1, bool SO1, typename T2, bool SO2 >
4843 struct MultTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4844 {
4845  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4846 };
4847 
4848 template< typename T1, bool SO1, typename T2, bool SO2 >
4849 struct MultTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4850 {
4851  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4852 };
4854 //*************************************************************************************************
4855 
4856 
4857 
4858 
4859 //=================================================================================================
4860 //
4861 // DIVTRAIT SPECIALIZATIONS
4862 //
4863 //=================================================================================================
4864 
4865 //*************************************************************************************************
4867 template< typename T1, bool SO, typename T2 >
4868 struct DivTrait< CompressedMatrix<T1,SO>, T2 >
4869 {
4870  typedef CompressedMatrix< typename DivTrait<T1,T2>::Type, SO > Type;
4872 };
4874 //*************************************************************************************************
4875 
4876 
4877 
4878 
4879 //=================================================================================================
4880 //
4881 // MATHTRAIT SPECIALIZATIONS
4882 //
4883 //=================================================================================================
4884 
4885 //*************************************************************************************************
4887 template< typename T1, bool SO, typename T2 >
4888 struct MathTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4889 {
4890  typedef CompressedMatrix< typename MathTrait<T1,T2>::HighType, SO > HighType;
4891  typedef CompressedMatrix< typename MathTrait<T1,T2>::LowType , SO > LowType;
4892 };
4894 //*************************************************************************************************
4895 
4896 
4897 
4898 
4899 //=================================================================================================
4900 //
4901 // SUBMATRIXTRAIT SPECIALIZATIONS
4902 //
4903 //=================================================================================================
4904 
4905 //*************************************************************************************************
4907 template< typename T1, bool SO >
4908 struct SubmatrixTrait< CompressedMatrix<T1,SO> >
4909 {
4910  typedef CompressedMatrix<T1,SO> Type;
4911 };
4913 //*************************************************************************************************
4914 
4915 
4916 
4917 
4918 //=================================================================================================
4919 //
4920 // ROWTRAIT SPECIALIZATIONS
4921 //
4922 //=================================================================================================
4923 
4924 //*************************************************************************************************
4926 template< typename T1, bool SO >
4927 struct RowTrait< CompressedMatrix<T1,SO> >
4928 {
4929  typedef CompressedVector<T1,true> Type;
4930 };
4932 //*************************************************************************************************
4933 
4934 
4935 
4936 
4937 //=================================================================================================
4938 //
4939 // COLUMNTRAIT SPECIALIZATIONS
4940 //
4941 //=================================================================================================
4942 
4943 //*************************************************************************************************
4945 template< typename T1, bool SO >
4946 struct ColumnTrait< CompressedMatrix<T1,SO> >
4947 {
4948  typedef CompressedVector<T1,false> Type;
4949 };
4951 //*************************************************************************************************
4952 
4953 } // namespace blaze
4954 
4955 #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
Pointer difference type of the Blaze library.
size_t rows() const
Returns the current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:1109
void reserveElements(size_t nonzeros)
Reserving the specified number of sparse matrix elements.
Definition: CompressedMatrix.h:1753
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:98
Constraint on the data type.
Iterator * end_
Pointers one past the last non-zero element of each row.
Definition: CompressedMatrix.h:399
Header file for mathematical functions.
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4579
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
MatrixAccessProxy< This > Reference
Reference to a sparse matrix value.
Definition: CompressedMatrix.h:252
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.
const Type & ConstReference
Reference to a constant sparse matrix value.
Definition: CompressedMatrix.h:253
const bool defaultStorageOrder
The default storage order for all matrices of the Blaze library.This value specifies the default stor...
Definition: StorageOrder.h:56
Header file for the row trait.
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:751
Header file for the IsSparseMatrix type trait.
CompressedMatrix()
The default constructor for CompressedMatrix.
Definition: CompressedMatrix.h:443
bool isDefault(const DynamicMatrix< Type, SO > &m)
Returns whether the given dense matrix is in default state.
Definition: DynamicMatrix.h:4622
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:197
size_t extendCapacity() const
Calculating a new matrix capacity.
Definition: CompressedMatrix.h:1733
const blaze::Null NULL
Global NULL pointer.This instance of the Null class replaces the NULL macro to ensure a type-safe NUL...
Definition: Null.h:300
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2528
void clear()
Clearing the sparse matrix.
Definition: CompressedMatrix.h:1250
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:249
Header file for a safe C++ NULL pointer implementation.
void clear(CompressedMatrix< Type, SO > &m)
Clearing the given sparse matrix.
Definition: CompressedMatrix.h:4498
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2378
CompressedMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:247
#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:629
void reset(CompressedMatrix< Type, SO > &m)
Resetting the given sparse matrix.
Definition: CompressedMatrix.h:4482
Access proxy for sparse, matrices.The MatrixAccessProxy provides safe access to the elements of a no...
Definition: MatrixAccessProxy.h:86
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:2076
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:401
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:250
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:104
Constraint on the data type.
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: CompressedMatrix.h:1172
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:2530
Header file for the SparseMatrix base class.
void deallocate(T *address)
Deallocation of memory.
Definition: Memory.h:114
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:397
Header file for the floating point precision of the Blaze library.
void reserve(size_t nonzeros)
Setting the minimum capacity of the sparse matrix.
Definition: CompressedMatrix.h:1524
void reset()
Reset to the default initial values.
Definition: CompressedMatrix.h:1212
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:251
Header file for the ValueIndexPair class.
bool isDefault(const CompressedMatrix< Type, SO > &m)
Returns whether the given sparse matrix is in default state.
Definition: CompressedMatrix.h:4525
Header file for the multiplication trait.
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 sparse matrices.
Definition: CompressedMatrix.h:4558
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:2388
#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
void erase(size_t i, size_t j)
Erasing an element from the sparse matrix.
Definition: CompressedMatrix.h:1358
Iterator * end_
Pointers one past the last non-zero element of each column.
Definition: CompressedMatrix.h:2532
#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&#39;t have the same size...
Definition: SameSize.h:78
ValueIndexPair< Type > ElementBase
Base class for the sparse matrix element.
Definition: CompressedMatrix.h:201
void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:179
Constraint on the data type.
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 sparse matrix.
Definition: CompressedMatrix.h:1275
Compile time check for floating point data types.This type trait tests whether or not the given templ...
Definition: IsFloatingPoint.h:94
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2386
void subAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the subtraction assignment of a dense matrix.
Definition: CompressedMatrix.h:2272
Header file for the EnableIf class template.
void swap(CompressedMatrix &sm)
Swapping the contents of two sparse matrices.
Definition: CompressedMatrix.h:1712
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:255
Header file for the equal shim.
size_t capacity() const
Returns the maximum capacity of the sparse matrix.
Definition: CompressedMatrix.h:1137
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the sparse matrix.
Definition: CompressedMatrix.h:1443
Header file for the IsNumeric type trait.
CompressedMatrix & operator=(const CompressedMatrix &rhs)
Copy assignment operator for CompressedMatrix.
Definition: CompressedMatrix.h:842
Reference operator()(size_t i, size_t j)
2D-access to the sparse matrix elements.
Definition: CompressedMatrix.h:655
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:770
CompressedMatrix & transpose()
Transposing the matrix.
Definition: CompressedMatrix.h:1650
Header file for the division trait.
void swap(DynamicMatrix< Type, SO > &a, DynamicMatrix< Type, SO > &b)
Swapping the contents of two matrices.
Definition: DynamicMatrix.h:4651
void addAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a matrix to a matrix.
Definition: Matrix.h:209
void trim()
Removing all excessive capacity from all rows/columns.
Definition: CompressedMatrix.h:1611
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_BE_NUMERIC_TYPE(T)
Constraint on the data type.In case the given data type T is not a numeric (integral or floating poin...
Definition: Numeric.h:79
void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:239
const VT::ElementType max(const SparseVector< VT, TF > &sv)
Returns the largest element of the sparse vector.
Definition: SparseVector.h:405
#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:2387
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:85
size_t columns() const
Returns the current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:1123
Constraint on the data type.
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:246
Iterator * begin_
Pointers to the first non-zero element of each column.
Definition: CompressedMatrix.h:2531
void assign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the assignment of a row-major dense matrix.
Definition: CompressedMatrix.h:2098
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:254
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:1992
void finalize(size_t i)
Finalizing the element insertion of a row/column.
Definition: CompressedMatrix.h:2024
bool canAlias(const Other *alias) const
Returns whether the matrix can alias with the given address alias.
Definition: CompressedMatrix.h:2056
Base template for the DivTrait class.
Definition: DivTrait.h:141
CompressedMatrix< Type, SO > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:245
Iterator find(size_t i, size_t j)
Searches for a specific matrix element.
Definition: CompressedMatrix.h:1802
Header file for the mathematical trait.
Iterator * begin_
Pointers to the first non-zero element of each row.
Definition: CompressedMatrix.h:398
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2529
Index-value-pair for sparse vectors and matrices.The ValueIndexPair class represents a single index-v...
Definition: ValueIndexPair.h:69
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:2220
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:248
Iterator lowerBound(size_t i, size_t j)
Returns an iterator to the first index not less then the given index.
Definition: CompressedMatrix.h:1855
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:2534
Iterator upperBound(size_t i, size_t j)
Returns an iterator to the first index greater then the given index.
Definition: CompressedMatrix.h:1906
size_t columns(const Matrix< MT, SO > &m)
Returns the current number of columns of the matrix.
Definition: Matrix.h:154
Header file for basic type definitions.
ConstIterator cbegin(size_t i) const
Returns an iterator to the first non-zero element of row/column i.
Definition: CompressedMatrix.h:748
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2385
const VT::ElementType min(const SparseVector< VT, TF > &sv)
Returns the smallest element of the sparse vector.
Definition: SparseVector.h:348
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:396
ConstIterator cend(size_t i) const
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:814
Header file for the IsResizable type trait.
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:395
size_t rows(const Matrix< MT, SO > &m)
Returns the current number of rows of the matrix.
Definition: Matrix.h:138
#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:704