All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CompressedMatrix.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_SPARSE_COMPRESSEDMATRIX_H_
23 #define _BLAZE_MATH_SPARSE_COMPRESSEDMATRIX_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <algorithm>
31 #include <functional>
32 #include <stdexcept>
33 #include <vector>
35 #include <blaze/math/Forward.h>
36 #include <blaze/math/Functions.h>
37 #include <blaze/math/shims/Equal.h>
39 #include <blaze/math/shims/IsNaN.h>
51 #include <blaze/system/Precision.h>
53 #include <blaze/util/Assert.h>
60 #include <blaze/util/EnableIf.h>
61 #include <blaze/util/mpl/If.h>
62 #include <blaze/util/Null.h>
63 #include <blaze/util/Types.h>
66 
67 
68 namespace blaze {
69 
70 //=================================================================================================
71 //
72 // CLASS DEFINITION
73 //
74 //=================================================================================================
75 
76 //*************************************************************************************************
181 template< typename Type // Data type of the sparse matrix
182  , bool SO = defaultStorageOrder > // Storage order
183 class CompressedMatrix : public SparseMatrix< CompressedMatrix<Type,SO>, SO >
184 {
185  private:
186  //**Type definitions****************************************************************************
188  //**********************************************************************************************
189 
190  //**Private class Element***********************************************************************
194  struct Element : public ElementBase
195  {
196  using ElementBase::operator=;
197  friend class CompressedMatrix;
198  };
200  //**********************************************************************************************
201 
202  //**Private class FindIndex*********************************************************************
206  struct FindIndex : public std::binary_function<Element,size_t,bool>
207  {
208  inline bool operator()( const Element& element, size_t index ) const {
209  return element.index() < index;
210  }
211  inline bool operator()( size_t index, const Element& element ) const {
212  return index < element.index();
213  }
214  inline bool operator()( const Element& element1, const Element& element2 ) const {
215  return element1.index() < element2.index();
216  }
217  };
219  //**********************************************************************************************
220 
221  public:
222  //**Type definitions****************************************************************************
224  typedef This ResultType;
227  typedef Type ElementType;
228  typedef const Type& ReturnType;
229  typedef const This& CompositeType;
231  typedef const Type& ConstReference;
232  typedef Element* Iterator;
233  typedef const Element* ConstIterator;
234  //**********************************************************************************************
235 
236  //**Constructors********************************************************************************
239  explicit inline CompressedMatrix();
240  explicit inline CompressedMatrix( size_t m, size_t n );
241  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
242  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
243  inline CompressedMatrix( const CompressedMatrix& sm );
244  template< typename MT, bool SO2 > inline CompressedMatrix( const DenseMatrix<MT,SO2>& dm );
245  template< typename MT, bool SO2 > inline CompressedMatrix( const SparseMatrix<MT,SO2>& sm );
247  //**********************************************************************************************
248 
249  //**Destructor**********************************************************************************
252  inline ~CompressedMatrix();
254  //**********************************************************************************************
255 
256  //**Data access functions***********************************************************************
259  inline Reference operator()( size_t i, size_t j );
260  inline ConstReference operator()( size_t i, size_t j ) const;
261  inline Iterator begin ( size_t i );
262  inline ConstIterator begin ( size_t i ) const;
263  inline ConstIterator cbegin( size_t i ) const;
264  inline Iterator end ( size_t i );
265  inline ConstIterator end ( size_t i ) const;
266  inline ConstIterator cend ( size_t i ) const;
268  //**********************************************************************************************
269 
270  //**Assignment operators************************************************************************
273  inline CompressedMatrix& operator= ( const CompressedMatrix& rhs );
274  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO2>& rhs );
275  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO2>& rhs );
276  template< typename MT, bool SO2 > inline CompressedMatrix& operator+=( const Matrix<MT,SO2>& rhs );
277  template< typename MT, bool SO2 > inline CompressedMatrix& operator-=( const Matrix<MT,SO2>& rhs );
278  template< typename MT, bool SO2 > inline CompressedMatrix& operator*=( const Matrix<MT,SO2>& rhs );
279 
280  template< typename Other >
281  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
282  operator*=( Other rhs );
283 
284  template< typename Other >
285  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
286  operator/=( Other rhs );
288  //**********************************************************************************************
289 
290  //**Utility functions***************************************************************************
293  inline size_t rows() const;
294  inline size_t columns() const;
295  inline size_t capacity() const;
296  inline size_t capacity( size_t i ) const;
297  inline size_t nonZeros() const;
298  inline size_t nonZeros( size_t i ) const;
299  inline void reset();
300  inline void reset( size_t i );
301  inline void clear();
302  Iterator insert ( size_t i, size_t j, const Type& value );
303  inline void erase ( size_t i, size_t j );
304  inline Iterator erase ( size_t i, Iterator pos );
305  inline Iterator find ( size_t i, size_t j );
306  inline ConstIterator find ( size_t i, size_t j ) const;
307  void resize ( size_t m, size_t n, bool preserve=true );
308  inline void reserve( size_t nonzeros );
309  void reserve( size_t i, size_t nonzeros );
310  inline CompressedMatrix& transpose();
311  bool isDiagonal() const;
312  bool isSymmetric() const;
313  template< typename Other > inline CompressedMatrix& scale( Other scalar );
314  template< typename Other > inline CompressedMatrix& scaleDiagonal( Other scalar );
315  inline void swap( CompressedMatrix& sm ) /* throw() */;
317  //**********************************************************************************************
318 
319  //**Low-level utility functions*****************************************************************
322  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
323  inline void finalize( size_t i );
325  //**********************************************************************************************
326 
327  //**Expression template evaluation functions****************************************************
330  template< typename Other > inline bool canAlias ( const Other* alias ) const;
331  template< typename Other > inline bool isAliased( const Other* alias ) const;
332  template< typename MT, bool SO2 > inline void assign ( const DenseMatrix<MT,SO2>& rhs );
333  template< typename MT > inline void assign ( const SparseMatrix<MT,SO>& rhs );
334  template< typename MT > inline void assign ( const SparseMatrix<MT,!SO>& rhs );
335  template< typename MT, bool SO2 > inline void addAssign( const DenseMatrix<MT,SO2>& rhs );
336  template< typename MT, bool SO2 > inline void addAssign( const SparseMatrix<MT,SO2>& rhs );
337  template< typename MT, bool SO2 > inline void subAssign( const DenseMatrix<MT,SO2>& rhs );
338  template< typename MT, bool SO2 > inline void subAssign( const SparseMatrix<MT,SO2>& rhs );
340  //**********************************************************************************************
341 
342  private:
343  //**Utility functions***************************************************************************
346  inline size_t extendCapacity() const;
347  void reserveElements( size_t nonzeros );
349  //**********************************************************************************************
350 
351  //**Member variables****************************************************************************
354  size_t m_;
355  size_t n_;
356  size_t capacity_;
359 
360  static const Type zero_;
361 
362  //**********************************************************************************************
363 
364  //**Compile time checks*************************************************************************
372  //**********************************************************************************************
373 };
374 //*************************************************************************************************
375 
376 
377 
378 
379 //=================================================================================================
380 //
381 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
382 //
383 //=================================================================================================
384 
385 template< typename Type, bool SO >
386 const Type CompressedMatrix<Type,SO>::zero_ = Type();
387 
388 
389 
390 
391 //=================================================================================================
392 //
393 // CONSTRUCTORS
394 //
395 //=================================================================================================
396 
397 //*************************************************************************************************
400 template< typename Type // Data type of the sparse matrix
401  , bool SO > // Storage order
403  : m_ ( 0UL ) // The current number of rows of the sparse matrix
404  , n_ ( 0UL ) // The current number of columns of the sparse matrix
405  , capacity_( 0UL ) // The current capacity of the pointer array
406  , begin_( new Iterator[2] ) // Pointers to the first non-zero element of each row
407  , end_ ( begin_+1 ) // Pointers one past the last non-zero element of each row
408 {
409  begin_[0] = end_[0] = NULL;
410 }
411 //*************************************************************************************************
412 
413 
414 //*************************************************************************************************
422 template< typename Type // Data type of the sparse matrix
423  , bool SO > // Storage order
425  : m_ ( m ) // The current number of rows of the sparse matrix
426  , n_ ( n ) // The current number of columns of the sparse matrix
427  , capacity_( m ) // The current capacity of the pointer array
428  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
429  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
430 {
431  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
432  begin_[i] = NULL;
433 }
434 //*************************************************************************************************
435 
436 
437 //*************************************************************************************************
446 template< typename Type // Data type of the sparse matrix
447  , bool SO > // Storage order
448 inline CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
449  : m_ ( m ) // The current number of rows of the sparse matrix
450  , n_ ( n ) // The current number of columns of the sparse matrix
451  , capacity_( m ) // The current capacity of the pointer array
452  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
453  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
454 {
455  begin_[0UL] = new Element[nonzeros];
456  for( size_t i=1UL; i<(2UL*m_+1UL); ++i )
457  begin_[i] = begin_[0UL];
458  end_[m_] = begin_[0UL]+nonzeros;
459 }
460 //*************************************************************************************************
461 
462 
463 //*************************************************************************************************
472 template< typename Type // Data type of the sparse matrix
473  , bool SO > // Storage order
474 CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
475  : m_ ( m ) // The current number of rows of the sparse matrix
476  , n_ ( n ) // The current number of columns of the sparse matrix
477  , capacity_( m ) // The current capacity of the pointer array
478  , begin_( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
479  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
480 {
481  BLAZE_USER_ASSERT( nonzeros.size() == m, "Size of capacity vector and number of rows don't match" );
482 
483  size_t newCapacity( 0UL );
484  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
485  newCapacity += *it;
486 
487  begin_[0UL] = end_[0UL] = new Element[newCapacity];
488  for( size_t i=0UL; i<m_; ++i ) {
489  begin_[i+1UL] = end_[i+1UL] = begin_[i] + nonzeros[i];
490  }
491 }
492 //*************************************************************************************************
493 
494 
495 //*************************************************************************************************
500 template< typename Type // Data type of the sparse matrix
501  , bool SO > // Storage order
503  : m_ ( sm.m_ ) // The current number of rows of the sparse matrix
504  , n_ ( sm.n_ ) // The current number of columns of the sparse matrix
505  , capacity_( sm.m_ ) // The current capacity of the pointer array
506  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
507  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
508 {
509  const size_t nonzeros( sm.nonZeros() );
510 
511  begin_[0UL] = new Element[nonzeros];
512  for( size_t i=0UL; i<m_; ++i )
513  begin_[i+1UL] = end_[i] = std::copy( sm.begin(i), sm.end(i), begin_[i] );
514  end_[m_] = begin_[0UL]+nonzeros;
515 }
516 //*************************************************************************************************
517 
518 
519 //*************************************************************************************************
524 template< typename Type // Data type of the sparse matrix
525  , bool SO > // Storage order
526 template< typename MT // Type of the foreign dense matrix
527  , bool SO2 > // Storage order of the foreign dense matrix
529  : m_ ( (~dm).rows() ) // The current number of rows of the sparse matrix
530  , n_ ( (~dm).columns() ) // The current number of columns of the sparse matrix
531  , capacity_( m_ ) // The current capacity of the pointer array
532  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
533  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
534 {
535  using blaze::assign;
536 
537  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
538  begin_[i] = NULL;
539 
540  assign( *this, ~dm );
541 }
542 //*************************************************************************************************
543 
544 
545 //*************************************************************************************************
550 template< typename Type // Data type of the sparse matrix
551  , bool SO > // Storage order
552 template< typename MT // Type of the foreign sparse matrix
553  , bool SO2 > // Storage order of the foreign sparse matrix
555  : m_ ( (~sm).rows() ) // The current number of rows of the sparse matrix
556  , n_ ( (~sm).columns() ) // The current number of columns of the sparse matrix
557  , capacity_( m_ ) // The current capacity of the pointer array
558  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
559  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
560 {
561  using blaze::assign;
562 
563  const size_t nonzeros( (~sm).nonZeros() );
564 
565  begin_[0UL] = new Element[nonzeros];
566  for( size_t i=0UL; i<m_; ++i )
567  begin_[i+1UL] = end_[i] = begin_[0UL];
568  end_[m_] = begin_[0UL]+nonzeros;
569 
570  assign( *this, ~sm );
571 }
572 //*************************************************************************************************
573 
574 
575 
576 
577 //=================================================================================================
578 //
579 // DESTRUCTOR
580 //
581 //=================================================================================================
582 
583 //*************************************************************************************************
586 template< typename Type // Data type of the sparse matrix
587  , bool SO > // Storage order
589 {
590  delete [] begin_[0UL];
591  delete [] begin_;
592 }
593 //*************************************************************************************************
594 
595 
596 
597 
598 //=================================================================================================
599 //
600 // DATA ACCESS FUNCTIONS
601 //
602 //=================================================================================================
603 
604 //*************************************************************************************************
611 template< typename Type // Data type of the sparse matrix
612  , bool SO > // Storage order
615 {
616  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
617  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
618 
619  return Reference( *this, i, j );
620 }
621 //*************************************************************************************************
622 
623 
624 //*************************************************************************************************
631 template< typename Type // Data type of the sparse matrix
632  , bool SO > // Storage order
634  CompressedMatrix<Type,SO>::operator()( size_t i, size_t j ) const
635 {
636  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
637  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
638 
639  const ConstIterator pos( std::lower_bound( begin_[i], end_[i], j, FindIndex() ) );
640 
641  if( pos == end_[i] || pos->index_ != j )
642  return zero_;
643  else
644  return pos->value_;
645 }
646 //*************************************************************************************************
647 
648 
649 //*************************************************************************************************
660 template< typename Type // Data type of the sparse matrix
661  , bool SO > // Storage order
664 {
665  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
666  return begin_[i];
667 }
668 //*************************************************************************************************
669 
670 
671 //*************************************************************************************************
682 template< typename Type // Data type of the sparse matrix
683  , bool SO > // Storage order
686 {
687  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
688  return begin_[i];
689 }
690 //*************************************************************************************************
691 
692 
693 //*************************************************************************************************
704 template< typename Type // Data type of the sparse matrix
705  , bool SO > // Storage order
708 {
709  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
710  return begin_[i];
711 }
712 //*************************************************************************************************
713 
714 
715 //*************************************************************************************************
726 template< typename Type // Data type of the sparse matrix
727  , bool SO > // Storage order
730 {
731  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
732  return end_[i];
733 }
734 //*************************************************************************************************
735 
736 
737 //*************************************************************************************************
748 template< typename Type // Data type of the sparse matrix
749  , bool SO > // Storage order
752 {
753  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
754  return end_[i];
755 }
756 //*************************************************************************************************
757 
758 
759 //*************************************************************************************************
770 template< typename Type // Data type of the sparse matrix
771  , bool SO > // Storage order
774 {
775  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
776  return end_[i];
777 }
778 //*************************************************************************************************
779 
780 
781 
782 
783 //=================================================================================================
784 //
785 // ASSIGNMENT OPERATORS
786 //
787 //=================================================================================================
788 
789 //*************************************************************************************************
798 template< typename Type // Data type of the sparse matrix
799  , bool SO > // Storage order
802 {
803  if( &rhs == this ) return *this;
804 
805  const size_t nonzeros( rhs.nonZeros() );
806 
807  if( rhs.m_ > capacity_ || nonzeros > capacity() )
808  {
809  Iterator* newBegin( new Iterator[2UL*rhs.m_+2UL] );
810  Iterator* newEnd ( newBegin+(rhs.m_+1UL) );
811 
812  newBegin[0UL] = new Element[nonzeros];
813  for( size_t i=0UL; i<rhs.m_; ++i ) {
814  newBegin[i+1UL] = newEnd[i] = std::copy( rhs.begin_[i], rhs.end_[i], newBegin[i] );
815  }
816  newEnd[rhs.m_] = newBegin[0UL]+nonzeros;
817 
818  std::swap( begin_, newBegin );
819  end_ = newEnd;
820  delete [] newBegin[0UL];
821  delete [] newBegin;
822  capacity_ = rhs.m_;
823  }
824  else {
825  for( size_t i=0UL; i<rhs.m_; ++i ) {
826  begin_[i+1UL] = end_[i] = std::copy( rhs.begin_[i], rhs.end_[i], begin_[i] );
827  }
828  }
829 
830  m_ = rhs.m_;
831  n_ = rhs.n_;
832 
833  return *this;
834 }
835 //*************************************************************************************************
836 
837 
838 //*************************************************************************************************
847 template< typename Type // Data type of the sparse matrix
848  , bool SO > // Storage order
849 template< typename MT // Type of the right-hand side dense matrix
850  , bool SO2 > // Storage order of the right-hand side dense matrix
853 {
854  using blaze::assign;
855 
856  if( (~rhs).canAlias( this ) ) {
857  CompressedMatrix tmp( rhs );
858  swap( tmp );
859  }
860  else {
861  resize( (~rhs).rows(), (~rhs).columns(), false );
862  assign( *this, ~rhs );
863  }
864 
865  return *this;
866 }
867 //*************************************************************************************************
868 
869 
870 //*************************************************************************************************
879 template< typename Type // Data type of the sparse matrix
880  , bool SO > // Storage order
881 template< typename MT // Type of the right-hand side sparse matrix
882  , bool SO2 > // Storage order of the right-hand side sparse matrix
885 {
886  using blaze::assign;
887 
888  if( (~rhs).canAlias( this ) ||
889  (~rhs).rows() > capacity_ ||
890  (~rhs).nonZeros() > capacity() ) {
891  CompressedMatrix tmp( rhs );
892  swap( tmp );
893  }
894  else {
895  resize( (~rhs).rows(), (~rhs).columns(), false );
896  reset();
897  assign( *this, ~rhs );
898  }
899 
900  return *this;
901 }
902 //*************************************************************************************************
903 
904 
905 //*************************************************************************************************
915 template< typename Type // Data type of the sparse matrix
916  , bool SO > // Storage order
917 template< typename MT // Type of the right-hand side matrix
918  , bool SO2 > // Storage order of the right-hand side matrix
921 {
922  using blaze::addAssign;
923 
924  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
925  throw std::invalid_argument( "Matrix sizes do not match" );
926 
927  addAssign( *this, ~rhs );
928  return *this;
929 }
930 //*************************************************************************************************
931 
932 
933 //*************************************************************************************************
943 template< typename Type // Data type of the sparse matrix
944  , bool SO > // Storage order
945 template< typename MT // Type of the right-hand side matrix
946  , bool SO2 > // Storage order of the right-hand side matrix
948 {
949  using blaze::subAssign;
950 
951  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
952  throw std::invalid_argument( "Matrix sizes do not match" );
953 
954  subAssign( *this, ~rhs );
955  return *this;
956 }
957 //*************************************************************************************************
958 
959 
960 //*************************************************************************************************
970 template< typename Type // Data type of the sparse matrix
971  , bool SO > // Storage order
972 template< typename MT // Type of the right-hand side matrix
973  , bool SO2 > // Storage order of the right-hand side matrix
976 {
977  if( (~rhs).rows() != n_ )
978  throw std::invalid_argument( "Matrix sizes do not match" );
979 
980  CompressedMatrix tmp( *this * (~rhs) );
981  swap( tmp );
982 
983  return *this;
984 }
985 //*************************************************************************************************
986 
987 
988 //*************************************************************************************************
995 template< typename Type // Data type of the sparse matrix
996  , bool SO > // Storage order
997 template< typename Other > // Data type of the right-hand side scalar
1000 {
1001  for( size_t i=0UL; i<m_; ++i ) {
1002  const Iterator endElem( end(i) );
1003  for( Iterator elem=begin(i); elem<endElem; ++elem )
1004  elem->value_ *= rhs;
1005  }
1006 
1007  return *this;
1008 }
1009 //*************************************************************************************************
1010 
1011 
1012 //*************************************************************************************************
1019 template< typename Type // Data type of the sparse matrix
1020  , bool SO > // Storage order
1021 template< typename Other > // Data type of the right-hand side scalar
1022 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,SO> >::Type&
1024 {
1025  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1026 
1027  typedef typename DivTrait<Type,Other>::Type DT;
1028  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
1029 
1030  // Depending on the two involved data types, an integer division is applied or a
1031  // floating point division is selected.
1033  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1034  for( size_t i=0UL; i<m_; ++i ) {
1035  const Iterator endElem( end(i) );
1036  for( Iterator elem=begin(i); elem<endElem; ++elem )
1037  elem->value_ *= tmp;
1038  }
1039  }
1040  else {
1041  for( size_t i=0UL; i<m_; ++i ) {
1042  const Iterator endElem( end(i) );
1043  for( Iterator elem=begin(i); elem<endElem; ++elem )
1044  elem->value_ /= rhs;
1045  }
1046  }
1047 
1048  return *this;
1049 }
1050 //*************************************************************************************************
1051 
1052 
1053 
1054 
1055 //=================================================================================================
1056 //
1057 // UTILITY FUNCTIONS
1058 //
1059 //=================================================================================================
1060 
1061 //*************************************************************************************************
1066 template< typename Type // Data type of the sparse matrix
1067  , bool SO > // Storage order
1068 inline size_t CompressedMatrix<Type,SO>::rows() const
1069 {
1070  return m_;
1071 }
1072 //*************************************************************************************************
1073 
1074 
1075 //*************************************************************************************************
1080 template< typename Type // Data type of the sparse matrix
1081  , bool SO > // Storage order
1083 {
1084  return n_;
1085 }
1086 //*************************************************************************************************
1087 
1088 
1089 //*************************************************************************************************
1094 template< typename Type // Data type of the sparse matrix
1095  , bool SO > // Storage order
1097 {
1098  return end_[m_] - begin_[0UL];
1099 }
1100 //*************************************************************************************************
1101 
1102 
1103 //*************************************************************************************************
1114 template< typename Type // Data type of the sparse matrix
1115  , bool SO > // Storage order
1116 inline size_t CompressedMatrix<Type,SO>::capacity( size_t i ) const
1117 {
1118  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1119  return begin_[i+1UL] - begin_[i];
1120 }
1121 //*************************************************************************************************
1122 
1123 
1124 //*************************************************************************************************
1129 template< typename Type // Data type of the sparse matrix
1130  , bool SO > // Storage order
1132 {
1133  size_t nonzeros( 0UL );
1134 
1135  for( size_t i=0UL; i<m_; ++i )
1136  nonzeros += nonZeros( i );
1137 
1138  return nonzeros;
1139 }
1140 //*************************************************************************************************
1141 
1142 
1143 //*************************************************************************************************
1154 template< typename Type // Data type of the sparse matrix
1155  , bool SO > // Storage order
1156 inline size_t CompressedMatrix<Type,SO>::nonZeros( size_t i ) const
1157 {
1158  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1159  return end_[i] - begin_[i];
1160 }
1161 //*************************************************************************************************
1162 
1163 
1164 //*************************************************************************************************
1169 template< typename Type // Data type of the sparse matrix
1170  , bool SO > // Storage order
1172 {
1173  for( size_t i=0UL; i<m_; ++i )
1174  end_[i] = begin_[i];
1175 }
1176 //*************************************************************************************************
1177 
1178 
1179 //*************************************************************************************************
1190 template< typename Type // Data type of the sparse matrix
1191  , bool SO > // Storage order
1192 inline void CompressedMatrix<Type,SO>::reset( size_t i )
1193 {
1194  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1195  end_[i] = begin_[i];
1196 }
1197 //*************************************************************************************************
1198 
1199 
1200 //*************************************************************************************************
1207 template< typename Type // Data type of the sparse matrix
1208  , bool SO > // Storage order
1210 {
1211  end_[0UL] = end_[m_];
1212  m_ = 0UL;
1213  n_ = 0UL;
1214 }
1215 //*************************************************************************************************
1216 
1217 
1218 //*************************************************************************************************
1231 template< typename Type // Data type of the sparse matrix
1232  , bool SO > // Storage order
1234  CompressedMatrix<Type,SO>::insert( size_t i, size_t j, const Type& value )
1235 {
1236  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1237  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1238 
1239  const Iterator pos( std::lower_bound( begin_[i], end_[i], j, FindIndex() ) );
1240 
1241  if( pos != end_[i] && pos->index_ == j )
1242  throw std::invalid_argument( "Bad access index" );
1243 
1244  if( begin_[i+1UL] - end_[i] != 0 ) {
1245  std::copy_backward( pos, end_[i], end_[i]+1 );
1246  pos->value_ = value;
1247  pos->index_ = j;
1248  ++end_[i];
1249 
1250  return pos;
1251  }
1252  else if( end_[m_] - begin_[m_] != 0 ) {
1253  std::copy_backward( pos, end_[m_-1UL], end_[m_-1UL]+1 );
1254 
1255  pos->value_ = value;
1256  pos->index_ = j;
1257 
1258  for( size_t k=i+1UL; k<m_+1UL; ++k ) {
1259  ++begin_[k];
1260  ++end_[k-1UL];
1261  }
1262 
1263  return pos;
1264  }
1265  else {
1266  size_t newCapacity( extendCapacity() );
1267 
1268  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1269  Iterator* newEnd = newBegin+capacity_+1UL;
1270 
1271  newBegin[0UL] = new Element[newCapacity];
1272 
1273  for( size_t k=0UL; k<i; ++k ) {
1274  const size_t nonzeros( end_[k] - begin_[k] );
1275  const size_t total( begin_[k+1UL] - begin_[k] );
1276  newEnd [k] = newBegin[k] + nonzeros;
1277  newBegin[k+1UL] = newBegin[k] + total;
1278  }
1279  newEnd [i] = newBegin[i] + ( end_[i] - begin_[i] ) + 1;
1280  newBegin[i+1UL] = newBegin[i] + ( begin_[i+1] - begin_[i] ) + 1;
1281  for( size_t k=i+1UL; k<m_; ++k ) {
1282  const size_t nonzeros( end_[k] - begin_[k] );
1283  const size_t total( begin_[k+1UL] - begin_[k] );
1284  newEnd [k] = newBegin[k] + nonzeros;
1285  newBegin[k+1UL] = newBegin[k] + total;
1286  }
1287 
1288  newEnd[m_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
1289 
1290  Iterator tmp = std::copy( begin_[0UL], pos, newBegin[0UL] );
1291  tmp->value_ = value;
1292  tmp->index_ = j;
1293  std::copy( pos, end_[m_-1UL], tmp+1UL );
1294 
1295  std::swap( newBegin, begin_ );
1296  end_ = newEnd;
1297  delete [] newBegin[0UL];
1298  delete [] newBegin;
1299 
1300  return tmp;
1301  }
1302 }
1303 //*************************************************************************************************
1304 
1305 
1306 //*************************************************************************************************
1315 template< typename Type // Data type of the sparse matrix
1316  , bool SO > // Storage order
1317 inline void CompressedMatrix<Type,SO>::erase( size_t i, size_t j )
1318 {
1319  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1320  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1321 
1322  const Iterator pos( find( i, j ) );
1323  if( pos != end_[i] )
1324  end_[i] = std::copy( pos+1, end_[i], pos );
1325 }
1326 //*************************************************************************************************
1327 
1328 
1329 //*************************************************************************************************
1338 template< typename Type // Data type of the sparse matrix
1339  , bool SO > // Storage order
1342 {
1343  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1344  BLAZE_USER_ASSERT( pos >= begin_[i] && pos <= end_[i], "Invalid compressed matrix iterator" );
1345 
1346  if( pos != end_[i] )
1347  end_[i] = std::copy( pos+1, end_[i], pos );
1348 
1349  return pos;
1350 }
1351 //*************************************************************************************************
1352 
1353 
1354 //*************************************************************************************************
1368 template< typename Type // Data type of the sparse matrix
1369  , bool SO > // Storage order
1371  CompressedMatrix<Type,SO>::find( size_t i, size_t j )
1372 {
1373  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
1374 }
1375 //*************************************************************************************************
1376 
1377 
1378 //*************************************************************************************************
1392 template< typename Type // Data type of the sparse matrix
1393  , bool SO > // Storage order
1395  CompressedMatrix<Type,SO>::find( size_t i, size_t j ) const
1396 {
1397  const Iterator pos( std::lower_bound( begin_[i], end_[i], j, FindIndex() ) );
1398  if( pos != end_[i] && pos->index_ == j )
1399  return pos;
1400  else return end_[i];
1401 }
1402 //*************************************************************************************************
1403 
1404 
1405 //*************************************************************************************************
1419 template< typename Type // Data type of the sparse matrix
1420  , bool SO > // Storage order
1421 void CompressedMatrix<Type,SO>::resize( size_t m, size_t n, bool preserve )
1422 {
1423  BLAZE_INTERNAL_ASSERT( end_ - begin_ == capacity_ + 1UL, "Invalid storage setting detected" );
1424 
1425  if( m == m_ && n == n_ ) return;
1426 
1427  if( m > capacity_ )
1428  {
1429  Iterator* newBegin( new Iterator[2UL*m+2UL] );
1430  Iterator* newEnd ( newBegin+m+1UL );
1431 
1432  newBegin[0UL] = begin_[0UL];
1433 
1434  if( preserve ) {
1435  for( size_t i=0UL; i<m_; ++i ) {
1436  newEnd [i] = end_ [i];
1437  newBegin[i+1UL] = begin_[i+1UL];
1438  }
1439  for( size_t i=m_; i<m; ++i ) {
1440  newBegin[i+1UL] = newEnd[i] = begin_[m_];
1441  }
1442  }
1443  else {
1444  for( size_t i=0UL; i<m; ++i ) {
1445  newBegin[i+1UL] = newEnd[i] = begin_[0UL];
1446  }
1447  }
1448 
1449  newEnd[m] = end_[m_];
1450 
1451  std::swap( newBegin, begin_ );
1452  delete [] newBegin;
1453 
1454  end_ = newEnd;
1455  capacity_ = m;
1456  }
1457  else if( m > m_ )
1458  {
1459  end_[m] = end_[m_];
1460 
1461  if( !preserve ) {
1462  for( size_t i=0UL; i<m_; ++i )
1463  end_[i] = begin_[i];
1464  }
1465 
1466  for( size_t i=m_; i<m; ++i )
1467  begin_[i+1UL] = end_[i] = begin_[m_];
1468  }
1469  else
1470  {
1471  if( preserve ) {
1472  for( size_t i=0UL; i<m; ++i )
1473  end_[i] = std::lower_bound( begin_[i], end_[i], n, FindIndex() );
1474  }
1475  else {
1476  for( size_t i=0UL; i<m; ++i )
1477  end_[i] = begin_[i];
1478  }
1479 
1480  end_[m] = end_[m_];
1481  }
1482 
1483  m_ = m;
1484  n_ = n;
1485 }
1486 //*************************************************************************************************
1487 
1488 
1489 //*************************************************************************************************
1499 template< typename Type // Data type of the sparse matrix
1500  , bool SO > // Storage order
1501 inline void CompressedMatrix<Type,SO>::reserve( size_t nonzeros )
1502 {
1503  if( nonzeros > capacity() )
1504  reserveElements( nonzeros );
1505 }
1506 //*************************************************************************************************
1507 
1508 
1509 //*************************************************************************************************
1523 template< typename Type // Data type of the sparse matrix
1524  , bool SO > // Storage order
1525 void CompressedMatrix<Type,SO>::reserve( size_t i, size_t nonzeros )
1526 {
1527  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1528 
1529  const size_t current( capacity(i) );
1530 
1531  if( current >= nonzeros ) return;
1532 
1533  const ptrdiff_t additional( nonzeros - current );
1534 
1535  if( end_[m_] - begin_[m_] < additional )
1536  {
1537  const size_t newCapacity( begin_[m_] - begin_[0UL] + additional );
1538  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
1539 
1540  Iterator* newBegin( new Iterator[2UL*m_+2UL] );
1541  Iterator* newEnd ( newBegin+m_+1UL );
1542 
1543  newBegin[0UL] = new Element[newCapacity];
1544  newEnd [m_ ] = newBegin[0UL]+newCapacity;
1545 
1546  for( size_t k=0UL; k<i; ++k ) {
1547  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
1548  newBegin[k+1UL] = newBegin[k] + capacity(k);
1549  }
1550  newEnd [i ] = std::copy( begin_[i], end_[i], newBegin[i] );
1551  newBegin[i+1UL] = newBegin[i] + nonzeros;
1552  for( size_t k=i+1UL; k<m_; ++k ) {
1553  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
1554  newBegin[k+1UL] = newBegin[k] + capacity(k);
1555  }
1556 
1557  BLAZE_INTERNAL_ASSERT( newBegin[m_] == newEnd[m_], "Invalid pointer calculations" );
1558 
1559  std::swap( newBegin, begin_ );
1560  delete [] newBegin[0UL];
1561  delete [] newBegin;
1562  end_ = newEnd;
1563  }
1564  else
1565  {
1566  begin_[m_] += additional;
1567  for( size_t j=m_-1UL; j>i; --j ) {
1568  begin_[j] = std::copy_backward( begin_[j], end_[j], end_[j]+additional );
1569  end_ [j] += additional;
1570  }
1571  }
1572 }
1573 //*************************************************************************************************
1574 
1575 
1576 //*************************************************************************************************
1581 template< typename Type // Data type of the sparse matrix
1582  , bool SO > // Storage order
1584 {
1585  CompressedMatrix tmp( trans( *this ) );
1586  swap( tmp );
1587  return *this;
1588 }
1589 //*************************************************************************************************
1590 
1591 
1592 //*************************************************************************************************
1609 template< typename Type // Data type of the sparse matrix
1610  , bool SO > // Storage order
1612 {
1613  if( m_ != n_ ) return false;
1614 
1615  for( size_t i=0UL; i<rows(); ++i ) {
1616  for( ConstIterator element=begin_[i]; element!=end_[i]; ++element )
1617  if( element->index_ != i && !isDefault( element->value_ ) )
1618  return false;
1619  }
1620 
1621  return true;
1622 }
1623 //*************************************************************************************************
1624 
1625 
1626 //*************************************************************************************************
1631 template< typename Type // Data type of the sparse matrix
1632  , bool SO > // Storage order
1634 {
1635  if( m_ != n_ ) return false;
1636 
1637  for( size_t i=0UL; i<rows(); ++i ) {
1638  for( ConstIterator element=begin_[i]; element!=end_[i]; ++element )
1639  {
1640  const size_t index( element->index_ );
1641 
1642  if( isDefault( element->value_ ) )
1643  continue;
1644 
1645  const Iterator pos( std::lower_bound( begin_[index], end_[index], i, FindIndex() ) );
1646  if( pos == end_[index] || pos->index_ != i || !equal( pos->value_, element->value_ ) )
1647  return false;
1648  }
1649  }
1650 
1651  return true;
1652 }
1653 //*************************************************************************************************
1654 
1655 
1656 //*************************************************************************************************
1662 template< typename Type // Data type of the sparse matrix
1663  , bool SO > // Storage order
1664 template< typename Other > // Data type of the scalar value
1666 {
1667  for( size_t i=0UL; i<m_; ++i )
1668  for( Iterator element=begin_[i]; element!=end_[i]; ++element )
1669  element->value_ *= scalar;
1670 
1671  return *this;
1672 }
1673 //*************************************************************************************************
1674 
1675 
1676 //*************************************************************************************************
1682 template< typename Type // Data type of the sparse matrix
1683  , bool SO > // Storage order
1684 template< typename Other > // Data type of the scalar value
1686 {
1687  const size_t size( blaze::min( m_, n_ ) );
1688 
1689  for( size_t i=0UL; i<size; ++i ) {
1690  Iterator pos = std::lower_bound( begin_[i], end_[i], i, FindIndex() );
1691  if( pos != end_[i] && pos->index_ == i )
1692  pos->value_ *= scalar;
1693  }
1694 
1695  return *this;
1696 }
1697 //*************************************************************************************************
1698 
1699 
1700 //*************************************************************************************************
1707 template< typename Type // Data type of the sparse matrix
1708  , bool SO > // Storage order
1709 inline void CompressedMatrix<Type,SO>::swap( CompressedMatrix& sm ) /* throw() */
1710 {
1711  std::swap( m_, sm.m_ );
1712  std::swap( n_, sm.n_ );
1713  std::swap( capacity_, sm.capacity_ );
1714  std::swap( begin_, sm.begin_ );
1715  std::swap( end_ , sm.end_ );
1716 }
1717 //*************************************************************************************************
1718 
1719 
1720 //*************************************************************************************************
1728 template< typename Type // Data type of the sparse matrix
1729  , bool SO > // Storage order
1731 {
1732  size_t nonzeros( 2UL*capacity()+1UL );
1733  nonzeros = blaze::max( nonzeros, 7UL );
1734  nonzeros = blaze::min( nonzeros, m_*n_ );
1735 
1736  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
1737 
1738  return nonzeros;
1739 }
1740 //*************************************************************************************************
1741 
1742 
1743 //*************************************************************************************************
1749 template< typename Type // Data type of the sparse matrix
1750  , bool SO > // Storage order
1752 {
1753  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1754  Iterator* newEnd = newBegin+capacity_+1UL;
1755 
1756  newBegin[0UL] = new Element[nonzeros];
1757 
1758  for( size_t k=0UL; k<m_; ++k ) {
1759  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid row pointers" );
1760  newEnd [k] = std::copy( begin_[k], end_[k], newBegin[k] );
1761  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
1762  }
1763 
1764  newEnd[m_] = newBegin[0UL]+nonzeros;
1765 
1766  std::swap( newBegin, begin_ );
1767  delete [] newBegin[0UL];
1768  delete [] newBegin;
1769  end_ = newEnd;
1770 }
1771 //*************************************************************************************************
1772 
1773 
1774 
1775 
1776 //=================================================================================================
1777 //
1778 // LOW-LEVEL UTILITY FUNCTIONS
1779 //
1780 //=================================================================================================
1781 
1782 //*************************************************************************************************
1822 template< typename Type // Data type of the sparse matrix
1823  , bool SO > // Storage order
1824 inline void CompressedMatrix<Type,SO>::append( size_t i, size_t j, const Type& value, bool check )
1825 {
1826  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
1827  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
1828  BLAZE_USER_ASSERT( end_[i] < end_[m_], "Not enough reserved space left" );
1829  BLAZE_USER_ASSERT( begin_[i] == end_[i] || j > ( end_[i]-1UL )->index_, "Index is not strictly increasing" );
1830 
1831  end_[i]->value_ = value;
1832 
1833  if( !check || !isDefault( end_[i]->value_ ) ) {
1834  end_[i]->index_ = j;
1835  ++end_[i];
1836  }
1837 }
1838 //*************************************************************************************************
1839 
1840 
1841 //*************************************************************************************************
1854 template< typename Type // Data type of the sparse matrix
1855  , bool SO > // Storage order
1857 {
1858  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
1859 
1860  begin_[i+1UL] = end_[i];
1861  if( i != m_-1UL )
1862  end_[i+1UL] = end_[i];
1863 }
1864 //*************************************************************************************************
1865 
1866 
1867 
1868 
1869 //=================================================================================================
1870 //
1871 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1872 //
1873 //=================================================================================================
1874 
1875 //*************************************************************************************************
1885 template< typename Type // Data type of the sparse matrix
1886  , bool SO > // Storage order
1887 template< typename Other > // Data type of the foreign expression
1888 inline bool CompressedMatrix<Type,SO>::canAlias( const Other* alias ) const
1889 {
1890  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1891 }
1892 //*************************************************************************************************
1893 
1894 
1895 //*************************************************************************************************
1905 template< typename Type // Data type of the sparse matrix
1906  , bool SO > // Storage order
1907 template< typename Other > // Data type of the foreign expression
1908 inline bool CompressedMatrix<Type,SO>::isAliased( const Other* alias ) const
1909 {
1910  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1911 }
1912 //*************************************************************************************************
1913 
1914 
1915 //*************************************************************************************************
1926 template< typename Type // Data type of the sparse matrix
1927  , bool SO > // Storage order
1928 template< typename MT // Type of the right-hand side dense matrix
1929  , bool SO2 > // Storage order of the right-hand side dense matrix
1931 {
1932  size_t nonzeros( 0UL );
1933 
1934  for( size_t i=1UL; i<=m_; ++i )
1935  begin_[i] = end_[i] = end_[m_];
1936 
1937  for( size_t i=0UL; i<m_; ++i )
1938  {
1939  begin_[i] = end_[i] = begin_[0UL]+nonzeros;
1940 
1941  for( size_t j=0UL; j<n_; ++j )
1942  {
1943  if( nonzeros == capacity() ) {
1944  reserveElements( extendCapacity() );
1945  for( size_t k=i+1UL; k<=m_; ++k )
1946  begin_[k] = end_[k] = end_[m_];
1947  }
1948 
1949  end_[i]->value_ = (~rhs)(i,j);
1950 
1951  if( !isDefault( end_[i]->value_ ) ) {
1952  end_[i]->index_ = j;
1953  ++end_[i];
1954  ++nonzeros;
1955  }
1956  }
1957  }
1958 
1959  begin_[m_] = begin_[0UL]+nonzeros;
1960 }
1961 //*************************************************************************************************
1962 
1963 
1964 //*************************************************************************************************
1975 template< typename Type // Data type of the sparse matrix
1976  , bool SO > // Storage order
1977 template< typename MT > // Type of the right-hand side sparse matrix
1979 {
1980  for( size_t i=0UL; i<(~rhs).rows(); ++i ) {
1981  begin_[i+1UL] = end_[i] = std::copy( (~rhs).begin(i), (~rhs).end(i), begin_[i] );
1982  }
1983 }
1984 //*************************************************************************************************
1985 
1986 
1987 //*************************************************************************************************
1998 template< typename Type // Data type of the sparse matrix
1999  , bool SO > // Storage order
2000 template< typename MT > // Type of the right-hand side sparse matrix
2002 {
2003  typedef typename MT::ConstIterator RhsIterator;
2004 
2005  // Counting the number of elements per row
2006  std::vector<size_t> rowLengths( m_, 0UL );
2007  for( size_t j=0UL; j<n_; ++j ) {
2008  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2009  ++rowLengths[element->index()];
2010  }
2011 
2012  // Resizing the sparse matrix
2013  for( size_t i=0UL; i<m_; ++i ) {
2014  begin_[i+1UL] = end_[i+1UL] = begin_[i] + rowLengths[i];
2015  }
2016 
2017  // Appending the elements to the rows of the sparse matrix
2018  for( size_t j=0UL; j<n_; ++j ) {
2019  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2020  append( element->index(), j, element->value() );
2021  }
2022 }
2023 //*************************************************************************************************
2024 
2025 
2026 //*************************************************************************************************
2037 template< typename Type // Data type of the sparse matrix
2038  , bool SO > // Storage order
2039 template< typename MT // Type of the right-hand side dense matrix
2040  , bool SO2 > // Storage order of the right-hand side dense matrix
2042 {
2043  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2044  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2045 
2046  CompressedMatrix tmp( *this + (~rhs) );
2047  swap( tmp );
2048 }
2049 //*************************************************************************************************
2050 
2051 
2052 //*************************************************************************************************
2063 template< typename Type // Data type of the sparse matrix
2064  , bool SO > // Storage order
2065 template< typename MT // Type of the right-hand side sparse matrix
2066  , bool SO2 > // Storage order of the right-hand side sparse matrix
2068 {
2069  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2070  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2071 
2072  CompressedMatrix tmp( *this + (~rhs) );
2073  swap( tmp );
2074 }
2075 //*************************************************************************************************
2076 
2077 
2078 //*************************************************************************************************
2089 template< typename Type // Data type of the sparse matrix
2090  , bool SO > // Storage order
2091 template< typename MT // Type of the right-hand side dense matrix
2092  , bool SO2 > // Storage order of the right-hand side dense matrix
2094 {
2095  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2096  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2097 
2098  CompressedMatrix tmp( *this - (~rhs) );
2099  swap( tmp );
2100 }
2101 //*************************************************************************************************
2102 
2103 
2104 //*************************************************************************************************
2115 template< typename Type // Data type of the sparse matrix
2116  , bool SO > // Storage order
2117 template< typename MT // Type of the right-hand side sparse matrix
2118  , bool SO2 > // Storage order of the right-hand sparse matrix
2120 {
2121  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2122  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2123 
2124  CompressedMatrix tmp( *this - (~rhs) );
2125  swap( tmp );
2126 }
2127 //*************************************************************************************************
2128 
2129 
2130 
2131 
2132 
2133 
2134 
2135 
2136 //=================================================================================================
2137 //
2138 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2139 //
2140 //=================================================================================================
2141 
2142 //*************************************************************************************************
2150 template< typename Type > // Data type of the sparse matrix
2151 class CompressedMatrix<Type,true> : public SparseMatrix< CompressedMatrix<Type,true>, true >
2152 {
2153  private:
2154  //**Type definitions****************************************************************************
2156  //**********************************************************************************************
2157 
2158  //**Private class Element***********************************************************************
2162  struct Element : public ElementBase
2163  {
2164  using ElementBase::operator=;
2165  friend class CompressedMatrix;
2166  };
2168  //**********************************************************************************************
2169 
2170  //**Private class FindIndex*********************************************************************
2174  struct FindIndex : public std::binary_function<Element,size_t,bool>
2175  {
2176  inline bool operator()( const Element& element, size_t index ) const {
2177  return element.index() < index;
2178  }
2179  inline bool operator()( size_t index, const Element& element ) const {
2180  return index < element.index();
2181  }
2182  inline bool operator()( const Element& element1, const Element& element2 ) const {
2183  return element1.index() < element2.index();
2184  }
2185  };
2187  //**********************************************************************************************
2188 
2189  public:
2190  //**Type definitions****************************************************************************
2191  typedef CompressedMatrix<Type,true> This;
2192  typedef This ResultType;
2193  typedef CompressedMatrix<Type,false> OppositeType;
2194  typedef CompressedMatrix<Type,false> TransposeType;
2195  typedef Type ElementType;
2196  typedef const Type& ReturnType;
2197  typedef const This& CompositeType;
2198  typedef MatrixAccessProxy<This> Reference;
2199  typedef const Type& ConstReference;
2200  typedef Element* Iterator;
2201  typedef const Element* ConstIterator;
2202  //**********************************************************************************************
2203 
2204  //**Constructors********************************************************************************
2207  explicit inline CompressedMatrix();
2208  explicit inline CompressedMatrix( size_t m, size_t n );
2209  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
2210  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
2211  inline CompressedMatrix( const CompressedMatrix& sm );
2212  template< typename MT, bool SO > inline CompressedMatrix( const DenseMatrix<MT,SO>& dm );
2213  template< typename MT, bool SO > inline CompressedMatrix( const SparseMatrix<MT,SO>& sm );
2215  //**********************************************************************************************
2216 
2217  //**Destructor**********************************************************************************
2220  inline ~CompressedMatrix();
2222  //**********************************************************************************************
2223 
2224  //**Data access functions***********************************************************************
2227  inline Reference operator()( size_t i, size_t j );
2228  inline ConstReference operator()( size_t i, size_t j ) const;
2229  inline Iterator begin ( size_t i );
2230  inline ConstIterator begin ( size_t i ) const;
2231  inline ConstIterator cbegin( size_t i ) const;
2232  inline Iterator end ( size_t i );
2233  inline ConstIterator end ( size_t i ) const;
2234  inline ConstIterator cend ( size_t i ) const;
2236  //**********************************************************************************************
2237 
2238  //**Assignment operators************************************************************************
2241  inline CompressedMatrix& operator= ( const CompressedMatrix& rhs );
2242  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO>& rhs );
2243  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO>& rhs );
2244  template< typename MT, bool SO > inline CompressedMatrix& operator+=( const Matrix<MT,SO>& rhs );
2245  template< typename MT, bool SO > inline CompressedMatrix& operator-=( const Matrix<MT,SO>& rhs );
2246  template< typename MT, bool SO > inline CompressedMatrix& operator*=( const Matrix<MT,SO>& rhs );
2247 
2248  template< typename Other >
2249  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
2250  operator*=( Other rhs );
2251 
2252  template< typename Other >
2253  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
2254  operator/=( Other rhs );
2256  //**********************************************************************************************
2257 
2258  //**Utility functions***************************************************************************
2261  inline size_t rows() const;
2262  inline size_t columns() const;
2263  inline size_t capacity() const;
2264  inline size_t capacity( size_t j ) const;
2265  inline size_t nonZeros() const;
2266  inline size_t nonZeros( size_t j ) const;
2267  inline void reset();
2268  inline void reset( size_t j );
2269  inline void clear();
2270  Iterator insert ( size_t i, size_t j, const Type& value );
2271  inline void erase ( size_t i, size_t j );
2272  inline Iterator erase ( size_t j, Iterator pos );
2273  inline Iterator find ( size_t i, size_t j );
2274  inline ConstIterator find ( size_t i, size_t j ) const;
2275  void resize ( size_t m, size_t n, bool preserve=true );
2276  inline void reserve( size_t nonzeros );
2277  void reserve( size_t j, size_t nonzeros );
2278  inline CompressedMatrix& transpose();
2279  bool isDiagonal() const;
2280  bool isSymmetric() const;
2281  template< typename Other > inline CompressedMatrix& scale( Other scalar );
2282  template< typename Other > inline CompressedMatrix& scaleDiagonal( Other scalar );
2283  inline void swap( CompressedMatrix& sm ) /* throw() */;
2285  //**********************************************************************************************
2286 
2287  //**Utility functions***************************************************************************
2290  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
2291  inline void finalize( size_t j );
2293  //**********************************************************************************************
2294 
2295  //**Expression template evaluation functions****************************************************
2298  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2299  template< typename Other > inline bool isAliased( const Other* alias ) const;
2300  template< typename MT, bool SO > inline void assign ( const DenseMatrix<MT,SO>& rhs );
2301  template< typename MT > inline void assign ( const SparseMatrix<MT,true>& rhs );
2302  template< typename MT > inline void assign ( const SparseMatrix<MT,false>& rhs );
2303  template< typename MT, bool SO > inline void addAssign( const DenseMatrix<MT,SO>& rhs );
2304  template< typename MT, bool SO > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
2305  template< typename MT, bool SO > inline void subAssign( const DenseMatrix<MT,SO>& rhs );
2306  template< typename MT, bool SO > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
2308  //**********************************************************************************************
2309 
2310  private:
2311  //**Utility functions***************************************************************************
2314  inline size_t extendCapacity() const;
2315  void reserveElements( size_t nonzeros );
2317  //**********************************************************************************************
2318 
2319  //**Member variables****************************************************************************
2322  size_t m_;
2323  size_t n_;
2324  size_t capacity_;
2325  Iterator* begin_;
2326  Iterator* end_;
2327 
2328  static const Type zero_;
2329 
2330  //**********************************************************************************************
2331 
2332  //**Compile time checks*************************************************************************
2340  //**********************************************************************************************
2341 };
2343 //*************************************************************************************************
2344 
2345 
2346 
2347 
2348 //=================================================================================================
2349 //
2350 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
2351 //
2352 //=================================================================================================
2353 
2354 template< typename Type >
2355 const Type CompressedMatrix<Type,true>::zero_ = Type();
2356 
2357 
2358 
2359 
2360 //=================================================================================================
2361 //
2362 // CONSTRUCTORS
2363 //
2364 //=================================================================================================
2365 
2366 //*************************************************************************************************
2370 template< typename Type > // Data type of the sparse matrix
2372  : m_ ( 0UL ) // The current number of rows of the sparse matrix
2373  , n_ ( 0UL ) // The current number of columns of the sparse matrix
2374  , capacity_( 0UL ) // The current capacity of the pointer array
2375  , begin_( new Iterator[2UL] ) // Pointers to the first non-zero element of each column
2376  , end_ ( begin_+1UL ) // Pointers one past the last non-zero element of each column
2377 {
2378  begin_[0UL] = end_[0UL] = NULL;
2379 }
2381 //*************************************************************************************************
2382 
2383 
2384 //*************************************************************************************************
2393 template< typename Type > // Data type of the sparse matrix
2394 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n )
2395  : m_ ( m ) // The current number of rows of the sparse matrix
2396  , n_ ( n ) // The current number of columns of the sparse matrix
2397  , capacity_( n ) // The current capacity of the pointer array
2398  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
2399  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
2400 {
2401  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
2402  begin_[j] = NULL;
2403 }
2405 //*************************************************************************************************
2406 
2407 
2408 //*************************************************************************************************
2418 template< typename Type > // Data type of the sparse matrix
2419 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
2420  : m_ ( m ) // The current number of rows of the sparse matrix
2421  , n_ ( n ) // The current number of columns of the sparse matrix
2422  , capacity_( n ) // The current capacity of the pointer array
2423  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
2424  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
2425 {
2426  begin_[0UL] = new Element[nonzeros];
2427  for( size_t j=1UL; j<(2UL*n_+1UL); ++j )
2428  begin_[j] = begin_[0UL];
2429  end_[n_] = begin_[0UL]+nonzeros;
2430 }
2432 //*************************************************************************************************
2433 
2434 
2435 //*************************************************************************************************
2445 template< typename Type > // Data type of the sparse matrix
2446 CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
2447  : m_ ( m ) // The current number of rows of the sparse matrix
2448  , n_ ( n ) // The current number of columns of the sparse matrix
2449  , capacity_( n ) // The current capacity of the pointer array
2450  , begin_( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2451  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2452 {
2453  BLAZE_USER_ASSERT( nonzeros.size() == n, "Size of capacity vector and number of columns don't match" );
2454 
2455  size_t newCapacity( 0UL );
2456  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
2457  newCapacity += *it;
2458 
2459  begin_[0UL] = end_[0UL] = new Element[newCapacity];
2460  for( size_t j=0UL; j<n_; ++j ) {
2461  begin_[j+1UL] = end_[j+1UL] = begin_[j] + nonzeros[j];
2462  }
2463 }
2465 //*************************************************************************************************
2466 
2467 
2468 //*************************************************************************************************
2474 template< typename Type > // Data type of the sparse matrix
2475 inline CompressedMatrix<Type,true>::CompressedMatrix( const CompressedMatrix& sm )
2476  : m_ ( sm.m_ ) // The current number of rows of the sparse matrix
2477  , n_ ( sm.n_ ) // The current number of columns of the sparse matrix
2478  , capacity_( sm.n_ ) // The current capacity of the pointer array
2479  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2480  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2481 {
2482  const size_t nonzeros( sm.nonZeros() );
2483 
2484  begin_[0UL] = new Element[nonzeros];
2485  for( size_t j=0UL; j<n_; ++j )
2486  begin_[j+1UL] = end_[j] = std::copy( sm.begin(j), sm.end(j), begin_[j] );
2487  end_[n_] = begin_[0UL]+nonzeros;
2488 }
2490 //*************************************************************************************************
2491 
2492 
2493 //*************************************************************************************************
2499 template< typename Type > // Data type of the sparse matrix
2500 template< typename MT // Type of the foreign dense matrix
2501  , bool SO > // Storage order of the foreign dense matrix
2502 inline CompressedMatrix<Type,true>::CompressedMatrix( const DenseMatrix<MT,SO>& dm )
2503  : m_ ( (~dm).rows() ) // The current number of rows of the sparse matrix
2504  , n_ ( (~dm).columns() ) // The current number of columns of the sparse matrix
2505  , capacity_( n_ ) // The current capacity of the pointer array
2506  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2507  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2508 {
2509  using blaze::assign;
2510 
2511  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
2512  begin_[j] = NULL;
2513 
2514  assign( *this, ~dm );
2515 }
2517 //*************************************************************************************************
2518 
2519 
2520 //*************************************************************************************************
2526 template< typename Type > // Data type of the sparse matrix
2527 template< typename MT // Type of the foreign sparse matrix
2528  , bool SO > // Storage order of the foreign sparse matrix
2529 inline CompressedMatrix<Type,true>::CompressedMatrix( const SparseMatrix<MT,SO>& sm )
2530  : m_ ( (~sm).rows() ) // The current number of rows of the sparse matrix
2531  , n_ ( (~sm).columns() ) // The current number of columns of the sparse matrix
2532  , capacity_( n_ ) // The current capacity of the pointer array
2533  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2534  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2535 {
2536  using blaze::assign;
2537 
2538  const size_t nonzeros( (~sm).nonZeros() );
2539 
2540  begin_[0UL] = new Element[nonzeros];
2541  for( size_t j=0UL; j<n_; ++j )
2542  begin_[j+1UL] = end_[j] = begin_[0UL];
2543  end_[n_] = begin_[0UL]+nonzeros;
2544 
2545  assign( *this, ~sm );
2546 }
2548 //*************************************************************************************************
2549 
2550 
2551 
2552 
2553 //=================================================================================================
2554 //
2555 // DESTRUCTOR
2556 //
2557 //=================================================================================================
2558 
2559 //*************************************************************************************************
2563 template< typename Type > // Data type of the sparse matrix
2565 {
2566  delete [] begin_[0UL];
2567  delete [] begin_;
2568 }
2570 //*************************************************************************************************
2571 
2572 
2573 
2574 
2575 //=================================================================================================
2576 //
2577 // DATA ACCESS FUNCTIONS
2578 //
2579 //=================================================================================================
2580 
2581 //*************************************************************************************************
2589 template< typename Type > // Data type of the sparse matrix
2590 inline typename CompressedMatrix<Type,true>::Reference
2591  CompressedMatrix<Type,true>::operator()( size_t i, size_t j )
2592 {
2593  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2594  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2595 
2596  return Reference( *this, i, j );
2597 }
2599 //*************************************************************************************************
2600 
2601 
2602 //*************************************************************************************************
2610 template< typename Type > // Data type of the sparse matrix
2611 inline typename CompressedMatrix<Type,true>::ConstReference
2612  CompressedMatrix<Type,true>::operator()( size_t i, size_t j ) const
2613 {
2614  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2615  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2616 
2617  const ConstIterator pos( std::lower_bound( begin_[j], end_[j], i, FindIndex() ) );
2618 
2619  if( pos == end_[j] || pos->index_ != i )
2620  return zero_;
2621  else
2622  return pos->value_;
2623 }
2625 //*************************************************************************************************
2626 
2627 
2628 //*************************************************************************************************
2635 template< typename Type > // Data type of the sparse matrix
2636 inline typename CompressedMatrix<Type,true>::Iterator
2638 {
2639  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2640  return begin_[j];
2641 }
2643 //*************************************************************************************************
2644 
2645 
2646 //*************************************************************************************************
2653 template< typename Type > // Data type of the sparse matrix
2654 inline typename CompressedMatrix<Type,true>::ConstIterator
2655  CompressedMatrix<Type,true>::begin( size_t j ) const
2656 {
2657  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2658  return begin_[j];
2659 }
2661 //*************************************************************************************************
2662 
2663 
2664 //*************************************************************************************************
2671 template< typename Type > // Data type of the sparse matrix
2672 inline typename CompressedMatrix<Type,true>::ConstIterator
2673  CompressedMatrix<Type,true>::cbegin( size_t j ) const
2674 {
2675  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2676  return begin_[j];
2677 }
2679 //*************************************************************************************************
2680 
2681 
2682 //*************************************************************************************************
2689 template< typename Type > // Data type of the sparse matrix
2690 inline typename CompressedMatrix<Type,true>::Iterator
2692 {
2693  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2694  return end_[j];
2695 }
2697 //*************************************************************************************************
2698 
2699 
2700 //*************************************************************************************************
2707 template< typename Type > // Data type of the sparse matrix
2708 inline typename CompressedMatrix<Type,true>::ConstIterator
2709  CompressedMatrix<Type,true>::end( size_t j ) const
2710 {
2711  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2712  return end_[j];
2713 }
2715 //*************************************************************************************************
2716 
2717 
2718 //*************************************************************************************************
2725 template< typename Type > // Data type of the sparse matrix
2726 inline typename CompressedMatrix<Type,true>::ConstIterator
2727  CompressedMatrix<Type,true>::cend( size_t j ) const
2728 {
2729  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2730  return end_[j];
2731 }
2733 //*************************************************************************************************
2734 
2735 
2736 
2737 
2738 //=================================================================================================
2739 //
2740 // ASSIGNMENT OPERATORS
2741 //
2742 //=================================================================================================
2743 
2744 //*************************************************************************************************
2754 template< typename Type > // Data type of the sparse matrix
2755 inline CompressedMatrix<Type,true>&
2756  CompressedMatrix<Type,true>::operator=( const CompressedMatrix& rhs )
2757 {
2758  if( &rhs == this ) return *this;
2759 
2760  const size_t nonzeros( rhs.nonZeros() );
2761 
2762  if( rhs.n_ > capacity_ || nonzeros > capacity() )
2763  {
2764  Iterator* newBegin( new Iterator[2UL*rhs.n_+2UL] );
2765  Iterator* newEnd ( newBegin+(rhs.n_+1UL) );
2766 
2767  newBegin[0UL] = new Element[nonzeros];
2768  for( size_t j=0UL; j<rhs.n_; ++j ) {
2769  newBegin[j+1UL] = newEnd[j] = std::copy( rhs.begin_[j], rhs.end_[j], newBegin[j] );
2770  }
2771  newEnd[rhs.n_] = newBegin[0UL]+nonzeros;
2772 
2773  std::swap( begin_, newBegin );
2774  end_ = newEnd;
2775  delete [] newBegin[0UL];
2776  delete [] newBegin;
2777  capacity_ = rhs.n_;
2778  }
2779  else {
2780  for( size_t j=0UL; j<rhs.n_; ++j ) {
2781  begin_[j+1UL] = end_[j] = std::copy( rhs.begin_[j], rhs.end_[j], begin_[j] );
2782  }
2783  }
2784 
2785  m_ = rhs.m_;
2786  n_ = rhs.n_;
2787 
2788  return *this;
2789 }
2791 //*************************************************************************************************
2792 
2793 
2794 //*************************************************************************************************
2804 template< typename Type > // Data type of the sparse matrix
2805 template< typename MT // Type of the right-hand side dense matrix
2806  , bool SO > // Storage order of the right-hand side dense matrix
2807 inline CompressedMatrix<Type,true>&
2808  CompressedMatrix<Type,true>::operator=( const DenseMatrix<MT,SO>& rhs )
2809 {
2810  using blaze::assign;
2811 
2812  if( (~rhs).canAlias( this ) ) {
2813  CompressedMatrix tmp( rhs );
2814  swap( tmp );
2815  }
2816  else {
2817  resize( (~rhs).rows(), (~rhs).columns(), false );
2818  assign( *this, ~rhs );
2819  }
2820 
2821  return *this;
2822 }
2824 //*************************************************************************************************
2825 
2826 
2827 //*************************************************************************************************
2837 template< typename Type > // Data type of the sparse matrix
2838 template< typename MT // Type of the right-hand side sparse matrix
2839  , bool SO > // Storage order of the right-hand side sparse matrix
2840 inline CompressedMatrix<Type,true>&
2841  CompressedMatrix<Type,true>::operator=( const SparseMatrix<MT,SO>& rhs )
2842 {
2843  using blaze::assign;
2844 
2845  if( (~rhs).canAlias( this ) ||
2846  (~rhs).columns() > capacity_ ||
2847  (~rhs).nonZeros() > capacity() ) {
2848  CompressedMatrix tmp( rhs );
2849  swap( tmp );
2850  }
2851  else {
2852  resize( (~rhs).rows(), (~rhs).columns(), false );
2853  reset();
2854  assign( *this, ~rhs );
2855  }
2856 
2857  return *this;
2858 }
2860 //*************************************************************************************************
2861 
2862 
2863 //*************************************************************************************************
2874 template< typename Type > // Data type of the sparse matrix
2875 template< typename MT // Type of the right-hand side matrix
2876  , bool SO > // Storage order of the right-hand side matrix
2877 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator+=( const Matrix<MT,SO>& rhs )
2878 {
2879  using blaze::addAssign;
2880 
2881  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
2882  throw std::invalid_argument( "Matrix sizes do not match" );
2883 
2884  addAssign( *this, ~rhs );
2885  return *this;
2886 }
2888 //*************************************************************************************************
2889 
2890 
2891 //*************************************************************************************************
2902 template< typename Type > // Data type of the sparse matrix
2903 template< typename MT // Type of the right-hand side matrix
2904  , bool SO > // Storage order of the right-hand side matrix
2905 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator-=( const Matrix<MT,SO>& rhs )
2906 {
2907  using blaze::subAssign;
2908 
2909  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
2910  throw std::invalid_argument( "Matrix sizes do not match" );
2911 
2912  subAssign( *this, ~rhs );
2913  return *this;
2914 }
2916 //*************************************************************************************************
2917 
2918 
2919 //*************************************************************************************************
2930 template< typename Type > // Data type of the sparse matrix
2931 template< typename MT // Type of the right-hand side matrix
2932  , bool SO > // Storage order of the right-hand side matrix
2933 inline CompressedMatrix<Type,true>&
2934  CompressedMatrix<Type,true>::operator*=( const Matrix<MT,SO>& rhs )
2935 {
2936  if( (~rhs).rows() != n_ )
2937  throw std::invalid_argument( "Matrix sizes do not match" );
2938 
2939  CompressedMatrix tmp( *this * (~rhs) );
2940  swap( tmp );
2941 
2942  return *this;
2943 }
2945 //*************************************************************************************************
2946 
2947 
2948 //*************************************************************************************************
2956 template< typename Type > // Data type of the sparse matrix
2957 template< typename Other > // Data type of the right-hand side scalar
2958 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,true> >::Type&
2959  CompressedMatrix<Type,true>::operator*=( Other rhs )
2960 {
2961  for( size_t j=0UL; j<n_; ++j ) {
2962  const Iterator endElem( end(j) );
2963  for( Iterator elem=begin(j); elem<endElem; ++elem )
2964  elem->value_ *= rhs;
2965  }
2966 
2967  return *this;
2968 }
2970 //*************************************************************************************************
2971 
2972 
2973 //*************************************************************************************************
2981 template< typename Type > // Data type of the sparse matrix
2982 template< typename Other > // Data type of the right-hand side scalar
2983 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,true> >::Type&
2984  CompressedMatrix<Type,true>::operator/=( Other rhs )
2985 {
2986  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
2987 
2988  typedef typename DivTrait<Type,Other>::Type DT;
2989  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
2990 
2991  // Depending on the two involved data types, an integer division is applied or a
2992  // floating point division is selected.
2993  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
2994  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
2995  for( size_t j=0UL; j<n_; ++j ) {
2996  const Iterator endElem( end(j) );
2997  for( Iterator elem=begin(j); elem<endElem; ++elem )
2998  elem->value_ *= tmp;
2999  }
3000  }
3001  else {
3002  for( size_t j=0UL; j<n_; ++j ) {
3003  const Iterator endElem( end(j) );
3004  for( Iterator elem=begin(j); elem<endElem; ++elem )
3005  elem->value_ /= rhs;
3006  }
3007  }
3008 
3009  return *this;
3010 }
3012 //*************************************************************************************************
3013 
3014 
3015 
3016 
3017 //=================================================================================================
3018 //
3019 // UTILITY FUNCTIONS
3020 //
3021 //=================================================================================================
3022 
3023 //*************************************************************************************************
3029 template< typename Type > // Data type of the sparse matrix
3030 inline size_t CompressedMatrix<Type,true>::rows() const
3031 {
3032  return m_;
3033 }
3035 //*************************************************************************************************
3036 
3037 
3038 //*************************************************************************************************
3044 template< typename Type > // Data type of the sparse matrix
3045 inline size_t CompressedMatrix<Type,true>::columns() const
3046 {
3047  return n_;
3048 }
3050 //*************************************************************************************************
3051 
3052 
3053 //*************************************************************************************************
3059 template< typename Type > // Data type of the sparse matrix
3060 inline size_t CompressedMatrix<Type,true>::capacity() const
3061 {
3062  return end_[n_] - begin_[0UL];
3063 }
3065 //*************************************************************************************************
3066 
3067 
3068 //*************************************************************************************************
3075 template< typename Type > // Data type of the sparse matrix
3076 inline size_t CompressedMatrix<Type,true>::capacity( size_t j ) const
3077 {
3078  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3079  return begin_[j+1UL] - begin_[j];
3080 }
3082 //*************************************************************************************************
3083 
3084 
3085 //*************************************************************************************************
3091 template< typename Type > // Data type of the sparse matrix
3092 inline size_t CompressedMatrix<Type,true>::nonZeros() const
3093 {
3094  size_t nonzeros( 0UL );
3095 
3096  for( size_t j=0UL; j<n_; ++j )
3097  nonzeros += nonZeros( j );
3098 
3099  return nonzeros;
3100 }
3102 //*************************************************************************************************
3103 
3104 
3105 //*************************************************************************************************
3112 template< typename Type > // Data type of the sparse matrix
3113 inline size_t CompressedMatrix<Type,true>::nonZeros( size_t j ) const
3114 {
3115  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3116  return end_[j] - begin_[j];
3117 }
3119 //*************************************************************************************************
3120 
3121 
3122 //*************************************************************************************************
3128 template< typename Type > // Data type of the sparse matrix
3130 {
3131  for( size_t j=0UL; j<n_; ++j )
3132  end_[j] = begin_[j];
3133 }
3135 //*************************************************************************************************
3136 
3137 
3138 //*************************************************************************************************
3148 template< typename Type > // Data type of the sparse matrix
3149 inline void CompressedMatrix<Type,true>::reset( size_t j )
3150 {
3151  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3152  end_[j] = begin_[j];
3153 }
3155 //*************************************************************************************************
3156 
3157 
3158 //*************************************************************************************************
3166 template< typename Type > // Data type of the sparse matrix
3168 {
3169  end_[0UL] = end_[n_];
3170  m_ = 0UL;
3171  n_ = 0UL;
3172 }
3174 //*************************************************************************************************
3175 
3176 
3177 //*************************************************************************************************
3191 template< typename Type > // Data type of the sparse matrix
3192 typename CompressedMatrix<Type,true>::Iterator
3193  CompressedMatrix<Type,true>::insert( size_t i, size_t j, const Type& value )
3194 {
3195  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3196  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3197 
3198  const Iterator pos( std::lower_bound( begin_[j], end_[j], i, FindIndex() ) );
3199 
3200  if( pos != end_[j] && pos->index_ == i )
3201  throw std::invalid_argument( "Bad access index" );
3202 
3203  if( begin_[j+1UL] - end_[j] != 0 ) {
3204  std::copy_backward( pos, end_[j], end_[j]+1 );
3205  pos->value_ = value;
3206  pos->index_ = i;
3207  ++end_[j];
3208 
3209  return pos;
3210  }
3211  else if( end_[n_] - begin_[n_] != 0 ) {
3212  std::copy_backward( pos, end_[n_-1UL], end_[n_-1]+1 );
3213 
3214  pos->value_ = value;
3215  pos->index_ = i;
3216 
3217  for( size_t k=j+1UL; k<n_+1UL; ++k ) {
3218  ++begin_[k];
3219  ++end_[k-1UL];
3220  }
3221 
3222  return pos;
3223  }
3224  else {
3225  size_t newCapacity( extendCapacity() );
3226 
3227  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
3228  Iterator* newEnd = newBegin+capacity_+1UL;
3229 
3230  newBegin[0UL] = new Element[newCapacity];
3231 
3232  for( size_t k=0UL; k<j; ++k ) {
3233  const size_t nonzeros( end_[k] - begin_[k] );
3234  const size_t total( begin_[k+1UL] - begin_[k] );
3235  newEnd [k] = newBegin[k] + nonzeros;
3236  newBegin[k+1UL] = newBegin[k] + total;
3237  }
3238  newEnd [j] = newBegin[j] + ( end_[j] - begin_[j] ) + 1;
3239  newBegin[j+1UL] = newBegin[j] + ( begin_[j+1UL] - begin_[j] ) + 1;
3240  for( size_t k=j+1UL; k<n_; ++k ) {
3241  const size_t nonzeros( end_[k] - begin_[k] );
3242  const size_t total( begin_[k+1UL] - begin_[k] );
3243  newEnd [k] = newBegin[k] + nonzeros;
3244  newBegin[k+1UL] = newBegin[k] + total;
3245  }
3246 
3247  newEnd[n_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
3248 
3249  Iterator tmp = std::copy( begin_[0UL], pos, newBegin[0UL] );
3250  tmp->value_ = value;
3251  tmp->index_ = i;
3252  std::copy( pos, end_[n_-1UL], tmp+1UL );
3253 
3254  std::swap( newBegin, begin_ );
3255  end_ = newEnd;
3256  delete [] newBegin[0UL];
3257  delete [] newBegin;
3258 
3259  return tmp;
3260  }
3261 }
3263 //*************************************************************************************************
3264 
3265 
3266 //*************************************************************************************************
3275 template< typename Type > // Data type of the sparse matrix
3276 inline void CompressedMatrix<Type,true>::erase( size_t i, size_t j )
3277 {
3278  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3279  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3280 
3281  const Iterator pos( find( i, j ) );
3282  if( pos != end_[j] )
3283  end_[j] = std::copy( pos+1, end_[j], pos );
3284 }
3285 //*************************************************************************************************
3286 
3287 
3288 //*************************************************************************************************
3297 template< typename Type > // Data type of the sparse matrix
3298 inline typename CompressedMatrix<Type,true>::Iterator
3299  CompressedMatrix<Type,true>::erase( size_t j, Iterator pos )
3300 {
3301  BLAZE_USER_ASSERT( j < columns() , "Invalid row access index" );
3302  BLAZE_USER_ASSERT( pos >= begin_[j] && pos <= end_[j], "Invalid compressed matrix iterator" );
3303 
3304  if( pos != end_[j] )
3305  end_[j] = std::copy( pos+1, end_[j], pos );
3306 
3307  return pos;
3308 }
3309 //*************************************************************************************************
3310 
3311 
3312 //*************************************************************************************************
3327 template< typename Type > // Data type of the sparse matrix
3328 inline typename CompressedMatrix<Type,true>::Iterator
3329  CompressedMatrix<Type,true>::find( size_t i, size_t j )
3330 {
3331  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
3332 }
3334 //*************************************************************************************************
3335 
3336 
3337 //*************************************************************************************************
3352 template< typename Type > // Data type of the sparse matrix
3353 inline typename CompressedMatrix<Type,true>::ConstIterator
3354  CompressedMatrix<Type,true>::find( size_t i, size_t j ) const
3355 {
3356  const Iterator pos( std::lower_bound( begin_[j], end_[j], i, FindIndex() ) );
3357  if( pos != end_[j] && pos->index_ == i )
3358  return pos;
3359  else return end_[j];
3360 }
3362 //*************************************************************************************************
3363 
3364 
3365 //*************************************************************************************************
3380 template< typename Type > // Data type of the sparse matrix
3381 void CompressedMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
3382 {
3383  BLAZE_INTERNAL_ASSERT( end_ - begin_ == capacity_ + 1UL, "Invalid storage setting detected" );
3384 
3385  if( m == m_ && n == n_ ) return;
3386 
3387  if( n > capacity_ )
3388  {
3389  Iterator* newBegin( new Iterator[2UL*n+2UL] );
3390  Iterator* newEnd ( newBegin+n+1UL );
3391 
3392  newBegin[0UL] = begin_[0UL];
3393 
3394  if( preserve ) {
3395  for( size_t j=0UL; j<n_; ++j ) {
3396  newEnd [j] = end_ [j];
3397  newBegin[j+1UL] = begin_[j+1UL];
3398  }
3399  for( size_t j=n_; j<n; ++j ) {
3400  newBegin[j+1UL] = newEnd[j] = begin_[n_];
3401  }
3402  }
3403  else {
3404  for( size_t j=0UL; j<n; ++j ) {
3405  newBegin[j+1UL] = newEnd[j] = begin_[0UL];
3406  }
3407  }
3408 
3409  newEnd[n] = end_[n_];
3410 
3411  std::swap( newBegin, begin_ );
3412  delete [] newBegin;
3413 
3414  end_ = newEnd;
3415  capacity_ = n;
3416  }
3417  else if( n > n_ )
3418  {
3419  end_[n] = end_[n_];
3420 
3421  if( !preserve ) {
3422  for( size_t j=0UL; j<n_; ++j )
3423  end_[j] = begin_[j];
3424  }
3425 
3426  for( size_t j=n_; j<n; ++j )
3427  begin_[j+1UL] = end_[j] = begin_[n_];
3428  }
3429  else
3430  {
3431  if( preserve ) {
3432  for( size_t j=0UL; j<n; ++j )
3433  end_[j] = std::lower_bound( begin_[j], end_[j], m, FindIndex() );
3434  }
3435  else {
3436  for( size_t j=0UL; j<n; ++j )
3437  end_[j] = begin_[j];
3438  }
3439 
3440  end_[n] = end_[n_];
3441  }
3442 
3443  m_ = m;
3444  n_ = n;
3445 }
3447 //*************************************************************************************************
3448 
3449 
3450 //*************************************************************************************************
3461 template< typename Type > // Data type of the sparse matrix
3462 inline void CompressedMatrix<Type,true>::reserve( size_t nonzeros )
3463 {
3464  if( nonzeros > capacity() )
3465  reserveElements( nonzeros );
3466 }
3468 //*************************************************************************************************
3469 
3470 
3471 //*************************************************************************************************
3483 template< typename Type > // Data type of the sparse matrix
3484 void CompressedMatrix<Type,true>::reserve( size_t j, size_t nonzeros )
3485 {
3486  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3487 
3488  const size_t current( capacity(j) );
3489 
3490  if( current >= nonzeros ) return;
3491 
3492  const ptrdiff_t additional( nonzeros - current );
3493 
3494  if( end_[n_] - begin_[n_] < additional )
3495  {
3496  const size_t newCapacity( begin_[n_] - begin_[0UL] + additional );
3497  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
3498 
3499  Iterator* newBegin( new Iterator[2UL*n_+2UL] );
3500  Iterator* newEnd ( newBegin+n_+1UL );
3501 
3502  newBegin[0UL] = new Element[newCapacity];
3503  newEnd [n_ ] = newBegin[0UL]+newCapacity;
3504 
3505  for( size_t k=0UL; k<j; ++k ) {
3506  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
3507  newBegin[k+1UL] = newBegin[k] + capacity(k);
3508  }
3509  newEnd [j ] = std::copy( begin_[j], end_[j], newBegin[j] );
3510  newBegin[j+1UL] = newBegin[j] + nonzeros;
3511  for( size_t k=j+1UL; k<n_; ++k ) {
3512  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
3513  newBegin[k+1UL] = newBegin[k] + capacity(k);
3514  }
3515 
3516  BLAZE_INTERNAL_ASSERT( newBegin[n_] == newEnd[n_], "Invalid pointer calculations" );
3517 
3518  std::swap( newBegin, begin_ );
3519  delete [] newBegin[0UL];
3520  delete [] newBegin;
3521  end_ = newEnd;
3522  }
3523  else
3524  {
3525  begin_[n_] += additional;
3526  for( size_t k=n_-1UL; k>j; --k ) {
3527  begin_[k] = std::copy_backward( begin_[k], end_[k], end_[k]+additional );
3528  end_ [k] += additional;
3529  }
3530  }
3531 }
3533 //*************************************************************************************************
3534 
3535 
3536 //*************************************************************************************************
3542 template< typename Type > // Data type of the sparse matrix
3543 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::transpose()
3544 {
3545  CompressedMatrix tmp( trans( *this ) );
3546  swap( tmp );
3547  return *this;
3548 }
3550 //*************************************************************************************************
3551 
3552 
3553 //*************************************************************************************************
3571 template< typename Type > // Data type of the sparse matrix
3573 {
3574  if( m_ != n_ ) return false;
3575 
3576  for( size_t j=0UL; j<columns(); ++j ) {
3577  for( ConstIterator element=begin_[j]; element!=end_[j]; ++element )
3578  if( element->index_ != j && !isDefault( element->value_ ) )
3579  return false;
3580  }
3581 
3582  return true;
3583 }
3585 //*************************************************************************************************
3586 
3587 
3588 //*************************************************************************************************
3594 template< typename Type > // Data type of the sparse matrix
3596 {
3597  if( m_ != n_ ) return false;
3598 
3599  for( size_t j=0UL; j<rows(); ++j ) {
3600  for( ConstIterator element=begin_[j]; element!=end_[j]; ++element )
3601  {
3602  const size_t index( element->index_ );
3603 
3604  if( isDefault( element->value_ ) )
3605  continue;
3606 
3607  const Iterator pos( std::lower_bound( begin_[index], end_[index], j, FindIndex() ) );
3608  if( pos == end_[index] || pos->index_ != j || !equal( pos->value_, element->value_ ) )
3609  return false;
3610  }
3611  }
3612 
3613  return true;
3614 }
3616 //*************************************************************************************************
3617 
3618 
3619 //*************************************************************************************************
3626 template< typename Type > // Data type of the sparse matrix
3627 template< typename Other > // Data type of the scalar value
3628 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scale( Other scalar )
3629 {
3630  for( size_t j=0UL; j<n_; ++j )
3631  for( Iterator element=begin_[j]; element!=end_[j]; ++element )
3632  element->value_ *= scalar;
3633 
3634  return *this;
3635 }
3637 //*************************************************************************************************
3638 
3639 
3640 //*************************************************************************************************
3647 template< typename Type > // Data type of the sparse matrix
3648 template< typename Other > // Data type of the scalar value
3649 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scaleDiagonal( Other scalar )
3650 {
3651  const size_t size( blaze::min( m_, n_ ) );
3652 
3653  for( size_t j=0UL; j<size; ++j ) {
3654  Iterator pos = std::lower_bound( begin_[j], end_[j], j, FindIndex() );
3655  if( pos != end_[j] && pos->index_ == j )
3656  pos->value_ *= scalar;
3657  }
3658 
3659  return *this;
3660 }
3662 //*************************************************************************************************
3663 
3664 
3665 //*************************************************************************************************
3673 template< typename Type > // Data type of the sparse matrix
3674 inline void CompressedMatrix<Type,true>::swap( CompressedMatrix& sm ) /* throw() */
3675 {
3676  std::swap( m_, sm.m_ );
3677  std::swap( n_, sm.n_ );
3678  std::swap( capacity_, sm.capacity_ );
3679  std::swap( begin_, sm.begin_ );
3680  std::swap( end_ , sm.end_ );
3681 }
3683 //*************************************************************************************************
3684 
3685 
3686 //*************************************************************************************************
3695 template< typename Type > // Data type of the sparse matrix
3696 inline size_t CompressedMatrix<Type,true>::extendCapacity() const
3697 {
3698  size_t nonzeros( 2UL*capacity()+1UL );
3699  nonzeros = blaze::max( nonzeros, 7UL );
3700  nonzeros = blaze::min( nonzeros, m_*n_ );
3701 
3702  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
3703 
3704  return nonzeros;
3705 }
3707 //*************************************************************************************************
3708 
3709 
3710 //*************************************************************************************************
3717 template< typename Type > // Data type of the sparse matrix
3718 void CompressedMatrix<Type,true>::reserveElements( size_t nonzeros )
3719 {
3720  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
3721  Iterator* newEnd = newBegin+capacity_+1UL;
3722 
3723  newBegin[0UL] = new Element[nonzeros];
3724 
3725  for( size_t k=0UL; k<n_; ++k ) {
3726  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid column pointers" );
3727  newEnd [k] = std::copy( begin_[k], end_[k], newBegin[k] );
3728  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
3729  }
3730 
3731  newEnd[n_] = newBegin[0UL]+nonzeros;
3732 
3733  std::swap( newBegin, begin_ );
3734  delete [] newBegin[0UL];
3735  delete [] newBegin;
3736  end_ = newEnd;
3737 }
3739 //*************************************************************************************************
3740 
3741 
3742 
3743 
3744 //=================================================================================================
3745 //
3746 // LOW-LEVEL UTILITY FUNCTIONS
3747 //
3748 //=================================================================================================
3749 
3750 //*************************************************************************************************
3791 template< typename Type > // Data type of the sparse matrix
3792 inline void CompressedMatrix<Type,true>::append( size_t i, size_t j, const Type& value, bool check )
3793 {
3794  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
3795  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
3796  BLAZE_USER_ASSERT( end_[j] < end_[n_], "Not enough reserved space left" );
3797  BLAZE_USER_ASSERT( begin_[j] == end_[j] || i > ( end_[j]-1UL )->index_, "Index is not strictly increasing" );
3798 
3799  end_[j]->value_ = value;
3800 
3801  if( !check || !isDefault( end_[j]->value_ ) ) {
3802  end_[j]->index_ = i;
3803  ++end_[j];
3804  }
3805 }
3807 //*************************************************************************************************
3808 
3809 
3810 //*************************************************************************************************
3824 template< typename Type > // Data type of the sparse matrix
3825 inline void CompressedMatrix<Type,true>::finalize( size_t j )
3826 {
3827  BLAZE_USER_ASSERT( j < n_, "Invalid row access index" );
3828 
3829  begin_[j+1UL] = end_[j];
3830  if( j != n_-1UL )
3831  end_[j+1UL] = end_[j];
3832 }
3834 //*************************************************************************************************
3835 
3836 
3837 
3838 
3839 //=================================================================================================
3840 //
3841 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3842 //
3843 //=================================================================================================
3844 
3845 //*************************************************************************************************
3856 template< typename Type > // Data type of the sparse matrix
3857 template< typename Other > // Data type of the foreign expression
3858 inline bool CompressedMatrix<Type,true>::canAlias( const Other* alias ) const
3859 {
3860  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
3861 }
3863 //*************************************************************************************************
3864 
3865 
3866 //*************************************************************************************************
3877 template< typename Type > // Data type of the sparse matrix
3878 template< typename Other > // Data type of the foreign expression
3879 inline bool CompressedMatrix<Type,true>::isAliased( const Other* alias ) const
3880 {
3881  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
3882 }
3884 //*************************************************************************************************
3885 
3886 
3887 //*************************************************************************************************
3899 template< typename Type > // Data type of the sparse matrix
3900 template< typename MT // Type of the right-hand side dense matrix
3901  , bool SO > // Storage order of the right-hand side dense matrix
3902 inline void CompressedMatrix<Type,true>::assign( const DenseMatrix<MT,SO>& rhs )
3903 {
3904  size_t nonzeros( 0UL );
3905 
3906  for( size_t j=1UL; j<=n_; ++j )
3907  begin_[j] = end_[j] = end_[n_];
3908 
3909  for( size_t j=0UL; j<n_; ++j )
3910  {
3911  begin_[j] = end_[j] = begin_[0UL]+nonzeros;
3912 
3913  for( size_t i=0UL; i<m_; ++i )
3914  {
3915  if( nonzeros == capacity() ) {
3916  reserveElements( extendCapacity() );
3917  for( size_t k=j+1UL; k<=n_; ++k )
3918  begin_[k] = end_[k] = end_[n_];
3919  }
3920 
3921  end_[j]->value_ = (~rhs)(i,j);
3922 
3923  if( !isDefault( end_[j]->value_ ) ) {
3924  end_[j]->index_ = i;
3925  ++end_[j];
3926  ++nonzeros;
3927  }
3928  }
3929  }
3930 
3931  begin_[n_] = begin_[0UL]+nonzeros;
3932 }
3934 //*************************************************************************************************
3935 
3936 
3937 //*************************************************************************************************
3949 template< typename Type > // Data type of the sparse matrix
3950 template< typename MT > // Type of the right-hand side sparse matrix
3951 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,true>& rhs )
3952 {
3953  for( size_t j=0UL; j<(~rhs).columns(); ++j ) {
3954  begin_[j+1UL] = end_[j] = std::copy( (~rhs).begin(j), (~rhs).end(j), begin_[j] );
3955  }
3956 }
3958 //*************************************************************************************************
3959 
3960 
3961 //*************************************************************************************************
3973 template< typename Type > // Data type of the sparse matrix
3974 template< typename MT > // Type of the right-hand side sparse matrix
3975 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,false>& rhs )
3976 {
3977  typedef typename MT::ConstIterator RhsIterator;
3978 
3979  // Counting the number of elements per column
3980  std::vector<size_t> columnLengths( n_, 0UL );
3981  for( size_t i=0UL; i<m_; ++i ) {
3982  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3983  ++columnLengths[element->index()];
3984  }
3985 
3986  // Resizing the sparse matrix
3987  for( size_t j=0UL; j<n_; ++j ) {
3988  begin_[j+1UL] = end_[j+1UL] = begin_[j] + columnLengths[j];
3989  }
3990 
3991  // Appending the elements to the columns of the sparse matrix
3992  for( size_t i=0UL; i<m_; ++i ) {
3993  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3994  append( i, element->index(), element->value() );
3995  }
3996 }
3998 //*************************************************************************************************
3999 
4000 
4001 //*************************************************************************************************
4013 template< typename Type > // Data type of the sparse matrix
4014 template< typename MT // Type of the right-hand side dense matrix
4015  , bool SO > // Storage order of the right-hand side dense matrix
4016 inline void CompressedMatrix<Type,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
4017 {
4018  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4019  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4020 
4021  CompressedMatrix tmp( *this + (~rhs) );
4022  swap( tmp );
4023 }
4025 //*************************************************************************************************
4026 
4027 
4028 //*************************************************************************************************
4040 template< typename Type > // Data type of the sparse matrix
4041 template< typename MT // Type of the right-hand side sparse matrix
4042  , bool SO > // Storage order of the right-hand side sparse matrix
4043 inline void CompressedMatrix<Type,true>::addAssign( const SparseMatrix<MT,SO>& rhs )
4044 {
4045  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4046  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4047 
4048  CompressedMatrix tmp( *this + (~rhs) );
4049  swap( tmp );
4050 }
4052 //*************************************************************************************************
4053 
4054 
4055 //*************************************************************************************************
4067 template< typename Type > // Data type of the sparse matrix
4068 template< typename MT // Type of the right-hand side dense matrix
4069  , bool SO > // Storage order of the right-hand side dense matrix
4070 inline void CompressedMatrix<Type,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
4071 {
4072  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4073  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4074 
4075  CompressedMatrix tmp( *this - (~rhs) );
4076  swap( tmp );
4077 }
4079 //*************************************************************************************************
4080 
4081 
4082 //*************************************************************************************************
4094 template< typename Type > // Data type of the sparse matrix
4095 template< typename MT // Type of the right-hand side sparse matrix
4096  , bool SO > // Storage order of the right-hand side sparse matrix
4097 inline void CompressedMatrix<Type,true>::subAssign( const SparseMatrix<MT,SO>& rhs )
4098 {
4099  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4100  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4101 
4102  CompressedMatrix tmp( *this - (~rhs) );
4103  swap( tmp );
4104 }
4106 //*************************************************************************************************
4107 
4108 
4109 
4110 
4111 
4112 
4113 
4114 
4115 //=================================================================================================
4116 //
4117 // COMPRESSEDMATRIX OPERATORS
4118 //
4119 //=================================================================================================
4120 
4121 //*************************************************************************************************
4124 template< typename Type, bool SO >
4125 inline bool isnan( const CompressedMatrix<Type,SO>& m );
4126 
4127 template< typename Type, bool SO >
4128 inline void reset( CompressedMatrix<Type,SO>& m );
4129 
4130 template< typename Type, bool SO >
4131 inline void clear( CompressedMatrix<Type,SO>& m );
4132 
4133 template< typename Type, bool SO >
4134 inline bool isDefault( const CompressedMatrix<Type,SO>& m );
4135 
4136 template< typename Type, bool SO >
4137 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) /* throw() */;
4139 //*************************************************************************************************
4140 
4141 
4142 //*************************************************************************************************
4149 template< typename Type // Data type of the sparse matrix
4150  , bool SO > // Storage order
4151 inline bool isnan( const CompressedMatrix<Type,SO>& m )
4152 {
4153  typedef typename CompressedMatrix<Type,SO>::ConstIterator ConstIterator;
4154 
4155  for( size_t i=0UL; i<m.rows(); ++i ) {
4156  for( ConstIterator element=m.begin(i); element!=m.end(i); ++element )
4157  if( isnan( *element ) ) return true;
4158  }
4159  return false;
4160 }
4161 //*************************************************************************************************
4162 
4163 
4164 //*************************************************************************************************
4171 template< typename Type // Data type of the sparse matrix
4172  , bool SO > // Storage order
4174 {
4175  m.reset();
4176 }
4177 //*************************************************************************************************
4178 
4179 
4180 //*************************************************************************************************
4187 template< typename Type // Data type of the sparse matrix
4188  , bool SO > // Storage order
4190 {
4191  m.clear();
4192 }
4193 //*************************************************************************************************
4194 
4195 
4196 //*************************************************************************************************
4214 template< typename Type // Data type of the sparse matrix
4215  , bool SO > // Storage order
4216 inline bool isDefault( const CompressedMatrix<Type,SO>& m )
4217 {
4218  typedef typename CompressedMatrix<Type,SO>::ConstIterator ConstIterator;
4219 
4220  if( SO == rowMajor ) {
4221  for( size_t i=0UL; i<m.rows(); ++i ) {
4222  for( ConstIterator element=m.begin(i); element!=m.end(i); ++element )
4223  if( !isDefault( element->value() ) ) return false;
4224  }
4225  }
4226  else {
4227  for( size_t j=0UL; j<m.columns(); ++j ) {
4228  for( ConstIterator element=m.begin(j); element!=m.end(j); ++element )
4229  if( !isDefault( element->value() ) ) return false;
4230  }
4231  }
4232 
4233  return true;
4234 }
4235 //*************************************************************************************************
4236 
4237 
4238 //*************************************************************************************************
4247 template< typename Type // Data type of the sparse matrix
4248  , bool SO > // Storage order
4249 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) /* throw() */
4250 {
4251  a.swap( b );
4252 }
4253 //*************************************************************************************************
4254 
4255 
4256 
4257 
4258 //=================================================================================================
4259 //
4260 // ISRESIZABLE SPECIALIZATIONS
4261 //
4262 //=================================================================================================
4263 
4264 //*************************************************************************************************
4266 template< typename T, bool SO >
4267 struct IsResizable< CompressedMatrix<T,SO> > : public TrueType
4268 {
4269  enum { value = 1 };
4270  typedef TrueType Type;
4271 };
4272 
4273 template< typename T, bool SO >
4274 struct IsResizable< const CompressedMatrix<T,SO> > : public TrueType
4275 {
4276  enum { value = 1 };
4277  typedef TrueType Type;
4278 };
4279 
4280 template< typename T, bool SO >
4281 struct IsResizable< volatile CompressedMatrix<T,SO> > : public TrueType
4282 {
4283  enum { value = 1 };
4284  typedef TrueType Type;
4285 };
4286 
4287 template< typename T, bool SO >
4288 struct IsResizable< const volatile CompressedMatrix<T,SO> > : public TrueType
4289 {
4290  enum { value = 1 };
4291  typedef TrueType Type;
4292 };
4294 //*************************************************************************************************
4295 
4296 
4297 
4298 
4299 //=================================================================================================
4300 //
4301 // ADDTRAIT SPECIALIZATIONS
4302 //
4303 //=================================================================================================
4304 
4305 //*************************************************************************************************
4307 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4308 struct AddTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4309 {
4310  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4311 };
4312 
4313 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4314 struct AddTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4315 {
4316  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
4317 };
4318 
4319 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4320 struct AddTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4321 {
4322  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4323 };
4324 
4325 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4326 struct AddTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4327 {
4328  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
4329 };
4330 
4331 template< typename T1, bool SO, typename T2 >
4332 struct AddTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4333 {
4334  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4335 };
4336 
4337 template< typename T1, bool SO1, typename T2, bool SO2 >
4338 struct AddTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4339 {
4340  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4341 };
4342 
4343 template< typename T1, bool SO, typename T2 >
4344 struct AddTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4345 {
4346  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4347 };
4348 
4349 template< typename T1, bool SO1, typename T2, bool SO2 >
4350 struct AddTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4351 {
4352  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4353 };
4354 
4355 template< typename T1, bool SO, typename T2 >
4356 struct AddTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4357 {
4358  typedef CompressedMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4359 };
4360 
4361 template< typename T1, bool SO1, typename T2, bool SO2 >
4362 struct AddTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4363 {
4364  typedef CompressedMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4365 };
4367 //*************************************************************************************************
4368 
4369 
4370 
4371 
4372 //=================================================================================================
4373 //
4374 // SUBTRAIT SPECIALIZATIONS
4375 //
4376 //=================================================================================================
4377 
4378 //*************************************************************************************************
4380 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4381 struct SubTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4382 {
4383  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4384 };
4385 
4386 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4387 struct SubTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4388 {
4389  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
4390 };
4391 
4392 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4393 struct SubTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4394 {
4395  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4396 };
4397 
4398 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4399 struct SubTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4400 {
4401  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
4402 };
4403 
4404 template< typename T1, bool SO, typename T2 >
4405 struct SubTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4406 {
4407  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4408 };
4409 
4410 template< typename T1, bool SO1, typename T2, bool SO2 >
4411 struct SubTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4412 {
4413  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , false > Type;
4414 };
4415 
4416 template< typename T1, bool SO, typename T2 >
4417 struct SubTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4418 {
4419  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4420 };
4421 
4422 template< typename T1, bool SO1, typename T2, bool SO2 >
4423 struct SubTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4424 {
4425  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , false > Type;
4426 };
4427 
4428 template< typename T1, bool SO, typename T2 >
4429 struct SubTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4430 {
4431  typedef CompressedMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4432 };
4433 
4434 template< typename T1, bool SO1, typename T2, bool SO2 >
4435 struct SubTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4436 {
4437  typedef CompressedMatrix< typename SubTrait<T1,T2>::Type , false > Type;
4438 };
4440 //*************************************************************************************************
4441 
4442 
4443 
4444 
4445 //=================================================================================================
4446 //
4447 // MULTTRAIT SPECIALIZATIONS
4448 //
4449 //=================================================================================================
4450 
4451 //*************************************************************************************************
4453 template< typename T1, bool SO, typename T2 >
4454 struct MultTrait< CompressedMatrix<T1,SO>, T2 >
4455 {
4456  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
4458 };
4459 
4460 template< typename T1, typename T2, bool SO >
4461 struct MultTrait< T1, CompressedMatrix<T2,SO> >
4462 {
4463  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
4465 };
4466 
4467 template< typename T1, bool SO, typename T2, size_t N >
4468 struct MultTrait< CompressedMatrix<T1,SO>, StaticVector<T2,N,false> >
4469 {
4470  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4471 };
4472 
4473 template< typename T1, size_t N, typename T2, bool SO >
4474 struct MultTrait< StaticVector<T1,N,true>, CompressedMatrix<T2,SO> >
4475 {
4476  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4477 };
4478 
4479 template< typename T1, bool SO, typename T2 >
4480 struct MultTrait< CompressedMatrix<T1,SO>, DynamicVector<T2,false> >
4481 {
4482  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4483 };
4484 
4485 template< typename T1, typename T2, bool SO >
4486 struct MultTrait< DynamicVector<T1,true>, CompressedMatrix<T2,SO> >
4487 {
4488  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4489 };
4490 
4491 template< typename T1, bool SO, typename T2 >
4492 struct MultTrait< CompressedMatrix<T1,SO>, CompressedVector<T2,false> >
4493 {
4494  typedef CompressedVector< typename MultTrait<T1,T2>::Type, false > Type;
4495 };
4496 
4497 template< typename T1, typename T2, bool SO >
4498 struct MultTrait< CompressedVector<T1,true>, CompressedMatrix<T2,SO> >
4499 {
4500  typedef CompressedVector< typename MultTrait<T1,T2>::Type, true > Type;
4501 };
4502 
4503 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4504 struct MultTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4505 {
4506  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4507 };
4508 
4509 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4510 struct MultTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4511 {
4512  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4513 };
4514 
4515 template< typename T1, bool SO1, typename T2, bool SO2 >
4516 struct MultTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4517 {
4518  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4519 };
4520 
4521 template< typename T1, bool SO1, typename T2, bool SO2 >
4522 struct MultTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4523 {
4524  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4525 };
4526 
4527 template< typename T1, bool SO1, typename T2, bool SO2 >
4528 struct MultTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4529 {
4530  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4531 };
4533 //*************************************************************************************************
4534 
4535 
4536 
4537 
4538 //=================================================================================================
4539 //
4540 // DIVTRAIT SPECIALIZATIONS
4541 //
4542 //=================================================================================================
4543 
4544 //*************************************************************************************************
4546 template< typename T1, bool SO, typename T2 >
4547 struct DivTrait< CompressedMatrix<T1,SO>, T2 >
4548 {
4549  typedef CompressedMatrix< typename DivTrait<T1,T2>::Type, SO > Type;
4551 };
4553 //*************************************************************************************************
4554 
4555 
4556 
4557 
4558 //=================================================================================================
4559 //
4560 // MATHTRAIT SPECIALIZATIONS
4561 //
4562 //=================================================================================================
4563 
4564 //*************************************************************************************************
4566 template< typename T1, bool SO, typename T2 >
4567 struct MathTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4568 {
4569  typedef CompressedMatrix< typename MathTrait<T1,T2>::HighType, SO > HighType;
4570  typedef CompressedMatrix< typename MathTrait<T1,T2>::LowType , SO > LowType;
4571 };
4573 //*************************************************************************************************
4574 
4575 
4576 
4577 
4578 //=================================================================================================
4579 //
4580 // ROWTRAIT SPECIALIZATIONS
4581 //
4582 //=================================================================================================
4583 
4584 //*************************************************************************************************
4586 template< typename T1, bool SO >
4587 struct RowTrait< CompressedMatrix<T1,SO> >
4588 {
4589  typedef CompressedVector<T1,true> Type;
4590 };
4592 //*************************************************************************************************
4593 
4594 
4595 
4596 
4597 //=================================================================================================
4598 //
4599 // COLUMNTRAIT SPECIALIZATIONS
4600 //
4601 //=================================================================================================
4602 
4603 //*************************************************************************************************
4605 template< typename T1, bool SO >
4606 struct ColumnTrait< CompressedMatrix<T1,SO> >
4607 {
4608  typedef CompressedVector<T1,false> Type;
4609 };
4611 //*************************************************************************************************
4612 
4613 } // namespace blaze
4614 
4615 #endif