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 #include <blaze/util/Unused.h>
67 
68 
69 namespace blaze {
70 
71 //=================================================================================================
72 //
73 // CLASS DEFINITION
74 //
75 //=================================================================================================
76 
77 //*************************************************************************************************
182 template< typename Type // Data type of the sparse matrix
183  , bool SO = defaultStorageOrder > // Storage order
184 class CompressedMatrix : public SparseMatrix< CompressedMatrix<Type,SO>, SO >
185 {
186  private:
187  //**Type definitions****************************************************************************
189  //**********************************************************************************************
190 
191  //**Private class Element***********************************************************************
195  struct Element : public ElementBase
196  {
197  using ElementBase::operator=;
198  friend class CompressedMatrix;
199  };
201  //**********************************************************************************************
202 
203  //**Private class FindIndex*********************************************************************
207  struct FindIndex : public std::binary_function<Element,size_t,bool>
208  {
209  inline bool operator()( const Element& element, size_t index ) const {
210  return element.index() < index;
211  }
212  inline bool operator()( size_t index, const Element& element ) const {
213  return index < element.index();
214  }
215  inline bool operator()( const Element& element1, const Element& element2 ) const {
216  return element1.index() < element2.index();
217  }
218  };
220  //**********************************************************************************************
221 
222  public:
223  //**Type definitions****************************************************************************
225  typedef This ResultType;
228  typedef Type ElementType;
229  typedef const Type& ReturnType;
230  typedef const This& CompositeType;
232  typedef const Type& ConstReference;
233  typedef Element* Iterator;
234  typedef const Element* ConstIterator;
235  //**********************************************************************************************
236 
237  //**Constructors********************************************************************************
240  explicit inline CompressedMatrix();
241  explicit inline CompressedMatrix( size_t m, size_t n );
242  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
243  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
244  inline CompressedMatrix( const CompressedMatrix& sm );
245  template< typename MT, bool SO2 > inline CompressedMatrix( const DenseMatrix<MT,SO2>& dm );
246  template< typename MT, bool SO2 > inline CompressedMatrix( const SparseMatrix<MT,SO2>& sm );
248  //**********************************************************************************************
249 
250  //**Destructor**********************************************************************************
253  inline ~CompressedMatrix();
255  //**********************************************************************************************
256 
257  //**Data access functions***********************************************************************
260  inline Reference operator()( size_t i, size_t j );
261  inline ConstReference operator()( size_t i, size_t j ) const;
262  inline Iterator begin ( size_t i );
263  inline ConstIterator begin ( size_t i ) const;
264  inline ConstIterator cbegin( size_t i ) const;
265  inline Iterator end ( size_t i );
266  inline ConstIterator end ( size_t i ) const;
267  inline ConstIterator cend ( size_t i ) const;
269  //**********************************************************************************************
270 
271  //**Assignment operators************************************************************************
274  inline CompressedMatrix& operator= ( const CompressedMatrix& rhs );
275  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO2>& rhs );
276  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const SparseMatrix<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  template< typename MT, bool SO2 > inline CompressedMatrix& operator*=( const Matrix<MT,SO2>& rhs );
280 
281  template< typename Other >
282  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
283  operator*=( Other rhs );
284 
285  template< typename Other >
286  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
287  operator/=( Other rhs );
289  //**********************************************************************************************
290 
291  //**Utility functions***************************************************************************
294  inline size_t rows() const;
295  inline size_t columns() const;
296  inline size_t capacity() const;
297  inline size_t capacity( size_t i ) const;
298  inline size_t nonZeros() const;
299  inline size_t nonZeros( size_t i ) const;
300  inline void reset();
301  inline void reset( size_t i );
302  inline void clear();
303  Iterator insert ( size_t i, size_t j, const Type& value );
304  inline void erase ( size_t i, size_t j );
305  inline Iterator erase ( size_t i, Iterator pos );
306  inline Iterator find ( size_t i, size_t j );
307  inline ConstIterator find ( size_t i, size_t j ) const;
308  void resize ( size_t m, size_t n, bool preserve=true );
309  inline void reserve( size_t nonzeros );
310  void reserve( size_t i, size_t nonzeros );
311  inline CompressedMatrix& transpose();
312  bool isDiagonal() const;
313  bool isSymmetric() const;
314  template< typename Other > inline CompressedMatrix& scale( Other scalar );
315  template< typename Other > inline CompressedMatrix& scaleDiagonal( Other scalar );
316  inline void swap( CompressedMatrix& sm ) /* throw() */;
318  //**********************************************************************************************
319 
320  //**Low-level utility functions*****************************************************************
323  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
324  inline void finalize( size_t i );
326  //**********************************************************************************************
327 
328  //**Expression template evaluation functions****************************************************
331  template< typename Other > inline bool canAlias ( const Other* alias ) const;
332  template< typename Other > inline bool isAliased( const Other* alias ) const;
333  template< typename MT, bool SO2 > inline void assign ( const DenseMatrix<MT,SO2>& rhs );
334  template< typename MT > inline void assign ( const SparseMatrix<MT,SO>& rhs );
335  template< typename MT > inline void assign ( const SparseMatrix<MT,!SO>& rhs );
336  template< typename MT, bool SO2 > inline void addAssign( const DenseMatrix<MT,SO2>& rhs );
337  template< typename MT, bool SO2 > inline void addAssign( const SparseMatrix<MT,SO2>& rhs );
338  template< typename MT, bool SO2 > inline void subAssign( const DenseMatrix<MT,SO2>& rhs );
339  template< typename MT, bool SO2 > inline void subAssign( const SparseMatrix<MT,SO2>& rhs );
341  //**********************************************************************************************
342 
343  private:
344  //**Utility functions***************************************************************************
347  inline size_t extendCapacity() const;
348  void reserveElements( size_t nonzeros );
350  //**********************************************************************************************
351 
352  //**Member variables****************************************************************************
355  size_t m_;
356  size_t n_;
357  size_t capacity_;
360 
361  static const Type zero_;
362 
363  //**********************************************************************************************
364 
365  //**Compile time checks*************************************************************************
373  //**********************************************************************************************
374 };
375 //*************************************************************************************************
376 
377 
378 
379 
380 //=================================================================================================
381 //
382 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
383 //
384 //=================================================================================================
385 
386 template< typename Type, bool SO >
387 const Type CompressedMatrix<Type,SO>::zero_ = Type();
388 
389 
390 
391 
392 //=================================================================================================
393 //
394 // CONSTRUCTORS
395 //
396 //=================================================================================================
397 
398 //*************************************************************************************************
401 template< typename Type // Data type of the sparse matrix
402  , bool SO > // Storage order
404  : m_ ( 0UL ) // The current number of rows of the sparse matrix
405  , n_ ( 0UL ) // The current number of columns of the sparse matrix
406  , capacity_( 0UL ) // The current capacity of the pointer array
407  , begin_( new Iterator[2] ) // Pointers to the first non-zero element of each row
408  , end_ ( begin_+1 ) // Pointers one past the last non-zero element of each row
409 {
410  begin_[0] = end_[0] = NULL;
411 }
412 //*************************************************************************************************
413 
414 
415 //*************************************************************************************************
423 template< typename Type // Data type of the sparse matrix
424  , bool SO > // Storage order
426  : m_ ( m ) // The current number of rows of the sparse matrix
427  , n_ ( n ) // The current number of columns of the sparse matrix
428  , capacity_( m ) // The current capacity of the pointer array
429  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
430  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
431 {
432  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
433  begin_[i] = NULL;
434 }
435 //*************************************************************************************************
436 
437 
438 //*************************************************************************************************
447 template< typename Type // Data type of the sparse matrix
448  , bool SO > // Storage order
449 inline CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
450  : m_ ( m ) // The current number of rows of the sparse matrix
451  , n_ ( n ) // The current number of columns of the sparse matrix
452  , capacity_( m ) // The current capacity of the pointer array
453  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
454  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
455 {
456  begin_[0UL] = new Element[nonzeros];
457  for( size_t i=1UL; i<(2UL*m_+1UL); ++i )
458  begin_[i] = begin_[0UL];
459  end_[m_] = begin_[0UL]+nonzeros;
460 }
461 //*************************************************************************************************
462 
463 
464 //*************************************************************************************************
473 template< typename Type // Data type of the sparse matrix
474  , bool SO > // Storage order
475 CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
476  : m_ ( m ) // The current number of rows of the sparse matrix
477  , n_ ( n ) // The current number of columns of the sparse matrix
478  , capacity_( m ) // The current capacity of the pointer array
479  , begin_( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
480  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
481 {
482  BLAZE_USER_ASSERT( nonzeros.size() == m, "Size of capacity vector and number of rows don't match" );
483 
484  size_t newCapacity( 0UL );
485  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
486  newCapacity += *it;
487 
488  begin_[0UL] = end_[0UL] = new Element[newCapacity];
489  for( size_t i=0UL; i<m_; ++i ) {
490  begin_[i+1UL] = end_[i+1UL] = begin_[i] + nonzeros[i];
491  }
492 }
493 //*************************************************************************************************
494 
495 
496 //*************************************************************************************************
501 template< typename Type // Data type of the sparse matrix
502  , bool SO > // Storage order
504  : m_ ( sm.m_ ) // The current number of rows of the sparse matrix
505  , n_ ( sm.n_ ) // The current number of columns of the sparse matrix
506  , capacity_( sm.m_ ) // The current capacity of the pointer array
507  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
508  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
509 {
510  const size_t nonzeros( sm.nonZeros() );
511 
512  begin_[0UL] = new Element[nonzeros];
513  for( size_t i=0UL; i<m_; ++i )
514  begin_[i+1UL] = end_[i] = std::copy( sm.begin(i), sm.end(i), begin_[i] );
515  end_[m_] = begin_[0UL]+nonzeros;
516 }
517 //*************************************************************************************************
518 
519 
520 //*************************************************************************************************
525 template< typename Type // Data type of the sparse matrix
526  , bool SO > // Storage order
527 template< typename MT // Type of the foreign dense matrix
528  , bool SO2 > // Storage order of the foreign dense matrix
530  : m_ ( (~dm).rows() ) // The current number of rows of the sparse matrix
531  , n_ ( (~dm).columns() ) // The current number of columns of the sparse matrix
532  , capacity_( m_ ) // The current capacity of the pointer array
533  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
534  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
535 {
536  using blaze::assign;
537 
538  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
539  begin_[i] = NULL;
540 
541  assign( *this, ~dm );
542 }
543 //*************************************************************************************************
544 
545 
546 //*************************************************************************************************
551 template< typename Type // Data type of the sparse matrix
552  , bool SO > // Storage order
553 template< typename MT // Type of the foreign sparse matrix
554  , bool SO2 > // Storage order of the foreign sparse matrix
556  : m_ ( (~sm).rows() ) // The current number of rows of the sparse matrix
557  , n_ ( (~sm).columns() ) // The current number of columns of the sparse matrix
558  , capacity_( m_ ) // The current capacity of the pointer array
559  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
560  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
561 {
562  using blaze::assign;
563 
564  const size_t nonzeros( (~sm).nonZeros() );
565 
566  begin_[0UL] = new Element[nonzeros];
567  for( size_t i=0UL; i<m_; ++i )
568  begin_[i+1UL] = end_[i] = begin_[0UL];
569  end_[m_] = begin_[0UL]+nonzeros;
570 
571  assign( *this, ~sm );
572 }
573 //*************************************************************************************************
574 
575 
576 
577 
578 //=================================================================================================
579 //
580 // DESTRUCTOR
581 //
582 //=================================================================================================
583 
584 //*************************************************************************************************
587 template< typename Type // Data type of the sparse matrix
588  , bool SO > // Storage order
590 {
591  delete [] begin_[0UL];
592  delete [] begin_;
593 }
594 //*************************************************************************************************
595 
596 
597 
598 
599 //=================================================================================================
600 //
601 // DATA ACCESS FUNCTIONS
602 //
603 //=================================================================================================
604 
605 //*************************************************************************************************
612 template< typename Type // Data type of the sparse matrix
613  , bool SO > // Storage order
616 {
617  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
618  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
619 
620  return Reference( *this, i, j );
621 }
622 //*************************************************************************************************
623 
624 
625 //*************************************************************************************************
632 template< typename Type // Data type of the sparse matrix
633  , bool SO > // Storage order
635  CompressedMatrix<Type,SO>::operator()( size_t i, size_t j ) const
636 {
637  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
638  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
639 
640  const ConstIterator pos( std::lower_bound( begin_[i], end_[i], j, FindIndex() ) );
641 
642  if( pos == end_[i] || pos->index_ != j )
643  return zero_;
644  else
645  return pos->value_;
646 }
647 //*************************************************************************************************
648 
649 
650 //*************************************************************************************************
661 template< typename Type // Data type of the sparse matrix
662  , bool SO > // Storage order
665 {
666  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
667  return begin_[i];
668 }
669 //*************************************************************************************************
670 
671 
672 //*************************************************************************************************
683 template< typename Type // Data type of the sparse matrix
684  , bool SO > // Storage order
687 {
688  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
689  return begin_[i];
690 }
691 //*************************************************************************************************
692 
693 
694 //*************************************************************************************************
705 template< typename Type // Data type of the sparse matrix
706  , bool SO > // Storage order
709 {
710  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
711  return begin_[i];
712 }
713 //*************************************************************************************************
714 
715 
716 //*************************************************************************************************
727 template< typename Type // Data type of the sparse matrix
728  , bool SO > // Storage order
731 {
732  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
733  return end_[i];
734 }
735 //*************************************************************************************************
736 
737 
738 //*************************************************************************************************
749 template< typename Type // Data type of the sparse matrix
750  , bool SO > // Storage order
753 {
754  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
755  return end_[i];
756 }
757 //*************************************************************************************************
758 
759 
760 //*************************************************************************************************
771 template< typename Type // Data type of the sparse matrix
772  , bool SO > // Storage order
775 {
776  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
777  return end_[i];
778 }
779 //*************************************************************************************************
780 
781 
782 
783 
784 //=================================================================================================
785 //
786 // ASSIGNMENT OPERATORS
787 //
788 //=================================================================================================
789 
790 //*************************************************************************************************
799 template< typename Type // Data type of the sparse matrix
800  , bool SO > // Storage order
803 {
804  if( &rhs == this ) return *this;
805 
806  const size_t nonzeros( rhs.nonZeros() );
807 
808  if( rhs.m_ > capacity_ || nonzeros > capacity() )
809  {
810  Iterator* newBegin( new Iterator[2UL*rhs.m_+2UL] );
811  Iterator* newEnd ( newBegin+(rhs.m_+1UL) );
812 
813  newBegin[0UL] = new Element[nonzeros];
814  for( size_t i=0UL; i<rhs.m_; ++i ) {
815  newBegin[i+1UL] = newEnd[i] = std::copy( rhs.begin_[i], rhs.end_[i], newBegin[i] );
816  }
817  newEnd[rhs.m_] = newBegin[0UL]+nonzeros;
818 
819  std::swap( begin_, newBegin );
820  end_ = newEnd;
821  delete [] newBegin[0UL];
822  delete [] newBegin;
823  capacity_ = rhs.m_;
824  }
825  else {
826  for( size_t i=0UL; i<rhs.m_; ++i ) {
827  begin_[i+1UL] = end_[i] = std::copy( rhs.begin_[i], rhs.end_[i], begin_[i] );
828  }
829  }
830 
831  m_ = rhs.m_;
832  n_ = rhs.n_;
833 
834  return *this;
835 }
836 //*************************************************************************************************
837 
838 
839 //*************************************************************************************************
848 template< typename Type // Data type of the sparse matrix
849  , bool SO > // Storage order
850 template< typename MT // Type of the right-hand side dense matrix
851  , bool SO2 > // Storage order of the right-hand side dense matrix
854 {
855  using blaze::assign;
856 
857  if( (~rhs).canAlias( this ) ) {
858  CompressedMatrix tmp( rhs );
859  swap( tmp );
860  }
861  else {
862  resize( (~rhs).rows(), (~rhs).columns(), false );
863  assign( *this, ~rhs );
864  }
865 
866  return *this;
867 }
868 //*************************************************************************************************
869 
870 
871 //*************************************************************************************************
880 template< typename Type // Data type of the sparse matrix
881  , bool SO > // Storage order
882 template< typename MT // Type of the right-hand side sparse matrix
883  , bool SO2 > // Storage order of the right-hand side sparse matrix
886 {
887  using blaze::assign;
888 
889  if( (~rhs).canAlias( this ) ||
890  (~rhs).rows() > capacity_ ||
891  (~rhs).nonZeros() > capacity() ) {
892  CompressedMatrix tmp( rhs );
893  swap( tmp );
894  }
895  else {
896  resize( (~rhs).rows(), (~rhs).columns(), false );
897  reset();
898  assign( *this, ~rhs );
899  }
900 
901  return *this;
902 }
903 //*************************************************************************************************
904 
905 
906 //*************************************************************************************************
916 template< typename Type // Data type of the sparse matrix
917  , bool SO > // Storage order
918 template< typename MT // Type of the right-hand side matrix
919  , bool SO2 > // Storage order of the right-hand side matrix
922 {
923  using blaze::addAssign;
924 
925  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
926  throw std::invalid_argument( "Matrix sizes do not match" );
927 
928  addAssign( *this, ~rhs );
929  return *this;
930 }
931 //*************************************************************************************************
932 
933 
934 //*************************************************************************************************
944 template< typename Type // Data type of the sparse matrix
945  , bool SO > // Storage order
946 template< typename MT // Type of the right-hand side matrix
947  , bool SO2 > // Storage order of the right-hand side matrix
949 {
950  using blaze::subAssign;
951 
952  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
953  throw std::invalid_argument( "Matrix sizes do not match" );
954 
955  subAssign( *this, ~rhs );
956  return *this;
957 }
958 //*************************************************************************************************
959 
960 
961 //*************************************************************************************************
971 template< typename Type // Data type of the sparse matrix
972  , bool SO > // Storage order
973 template< typename MT // Type of the right-hand side matrix
974  , bool SO2 > // Storage order of the right-hand side matrix
977 {
978  if( (~rhs).rows() != n_ )
979  throw std::invalid_argument( "Matrix sizes do not match" );
980 
981  CompressedMatrix tmp( *this * (~rhs) );
982  swap( tmp );
983 
984  return *this;
985 }
986 //*************************************************************************************************
987 
988 
989 //*************************************************************************************************
996 template< typename Type // Data type of the sparse matrix
997  , bool SO > // Storage order
998 template< typename Other > // Data type of the right-hand side scalar
1001 {
1002  for( size_t i=0UL; i<m_; ++i ) {
1003  const Iterator endElem( end(i) );
1004  for( Iterator elem=begin(i); elem<endElem; ++elem )
1005  elem->value_ *= rhs;
1006  }
1007 
1008  return *this;
1009 }
1010 //*************************************************************************************************
1011 
1012 
1013 //*************************************************************************************************
1020 template< typename Type // Data type of the sparse matrix
1021  , bool SO > // Storage order
1022 template< typename Other > // Data type of the right-hand side scalar
1023 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,SO> >::Type&
1025 {
1026  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1027 
1028  typedef typename DivTrait<Type,Other>::Type DT;
1029  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
1030 
1031  // Depending on the two involved data types, an integer division is applied or a
1032  // floating point division is selected.
1034  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1035  for( size_t i=0UL; i<m_; ++i ) {
1036  const Iterator endElem( end(i) );
1037  for( Iterator elem=begin(i); elem<endElem; ++elem )
1038  elem->value_ *= tmp;
1039  }
1040  }
1041  else {
1042  for( size_t i=0UL; i<m_; ++i ) {
1043  const Iterator endElem( end(i) );
1044  for( Iterator elem=begin(i); elem<endElem; ++elem )
1045  elem->value_ /= rhs;
1046  }
1047  }
1048 
1049  return *this;
1050 }
1051 //*************************************************************************************************
1052 
1053 
1054 
1055 
1056 //=================================================================================================
1057 //
1058 // UTILITY FUNCTIONS
1059 //
1060 //=================================================================================================
1061 
1062 //*************************************************************************************************
1067 template< typename Type // Data type of the sparse matrix
1068  , bool SO > // Storage order
1069 inline size_t CompressedMatrix<Type,SO>::rows() const
1070 {
1071  return m_;
1072 }
1073 //*************************************************************************************************
1074 
1075 
1076 //*************************************************************************************************
1081 template< typename Type // Data type of the sparse matrix
1082  , bool SO > // Storage order
1084 {
1085  return n_;
1086 }
1087 //*************************************************************************************************
1088 
1089 
1090 //*************************************************************************************************
1095 template< typename Type // Data type of the sparse matrix
1096  , bool SO > // Storage order
1098 {
1099  return end_[m_] - begin_[0UL];
1100 }
1101 //*************************************************************************************************
1102 
1103 
1104 //*************************************************************************************************
1115 template< typename Type // Data type of the sparse matrix
1116  , bool SO > // Storage order
1117 inline size_t CompressedMatrix<Type,SO>::capacity( size_t i ) const
1118 {
1119  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1120  return begin_[i+1UL] - begin_[i];
1121 }
1122 //*************************************************************************************************
1123 
1124 
1125 //*************************************************************************************************
1130 template< typename Type // Data type of the sparse matrix
1131  , bool SO > // Storage order
1133 {
1134  size_t nonzeros( 0UL );
1135 
1136  for( size_t i=0UL; i<m_; ++i )
1137  nonzeros += nonZeros( i );
1138 
1139  return nonzeros;
1140 }
1141 //*************************************************************************************************
1142 
1143 
1144 //*************************************************************************************************
1155 template< typename Type // Data type of the sparse matrix
1156  , bool SO > // Storage order
1157 inline size_t CompressedMatrix<Type,SO>::nonZeros( size_t i ) const
1158 {
1159  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1160  return end_[i] - begin_[i];
1161 }
1162 //*************************************************************************************************
1163 
1164 
1165 //*************************************************************************************************
1170 template< typename Type // Data type of the sparse matrix
1171  , bool SO > // Storage order
1173 {
1174  for( size_t i=0UL; i<m_; ++i )
1175  end_[i] = begin_[i];
1176 }
1177 //*************************************************************************************************
1178 
1179 
1180 //*************************************************************************************************
1191 template< typename Type // Data type of the sparse matrix
1192  , bool SO > // Storage order
1193 inline void CompressedMatrix<Type,SO>::reset( size_t i )
1194 {
1195  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1196  end_[i] = begin_[i];
1197 }
1198 //*************************************************************************************************
1199 
1200 
1201 //*************************************************************************************************
1208 template< typename Type // Data type of the sparse matrix
1209  , bool SO > // Storage order
1211 {
1212  end_[0UL] = end_[m_];
1213  m_ = 0UL;
1214  n_ = 0UL;
1215 }
1216 //*************************************************************************************************
1217 
1218 
1219 //*************************************************************************************************
1232 template< typename Type // Data type of the sparse matrix
1233  , bool SO > // Storage order
1235  CompressedMatrix<Type,SO>::insert( size_t i, size_t j, const Type& value )
1236 {
1237  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1238  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1239 
1240  const Iterator pos( std::lower_bound( begin_[i], end_[i], j, FindIndex() ) );
1241 
1242  if( pos != end_[i] && pos->index_ == j )
1243  throw std::invalid_argument( "Bad access index" );
1244 
1245  if( begin_[i+1UL] - end_[i] != 0 ) {
1246  std::copy_backward( pos, end_[i], end_[i]+1 );
1247  pos->value_ = value;
1248  pos->index_ = j;
1249  ++end_[i];
1250 
1251  return pos;
1252  }
1253  else if( end_[m_] - begin_[m_] != 0 ) {
1254  std::copy_backward( pos, end_[m_-1UL], end_[m_-1UL]+1 );
1255 
1256  pos->value_ = value;
1257  pos->index_ = j;
1258 
1259  for( size_t k=i+1UL; k<m_+1UL; ++k ) {
1260  ++begin_[k];
1261  ++end_[k-1UL];
1262  }
1263 
1264  return pos;
1265  }
1266  else {
1267  size_t newCapacity( extendCapacity() );
1268 
1269  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1270  Iterator* newEnd = newBegin+capacity_+1UL;
1271 
1272  newBegin[0UL] = new Element[newCapacity];
1273 
1274  for( size_t k=0UL; k<i; ++k ) {
1275  const size_t nonzeros( end_[k] - begin_[k] );
1276  const size_t total( begin_[k+1UL] - begin_[k] );
1277  newEnd [k] = newBegin[k] + nonzeros;
1278  newBegin[k+1UL] = newBegin[k] + total;
1279  }
1280  newEnd [i] = newBegin[i] + ( end_[i] - begin_[i] ) + 1;
1281  newBegin[i+1UL] = newBegin[i] + ( begin_[i+1] - begin_[i] ) + 1;
1282  for( size_t k=i+1UL; k<m_; ++k ) {
1283  const size_t nonzeros( end_[k] - begin_[k] );
1284  const size_t total( begin_[k+1UL] - begin_[k] );
1285  newEnd [k] = newBegin[k] + nonzeros;
1286  newBegin[k+1UL] = newBegin[k] + total;
1287  }
1288 
1289  newEnd[m_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
1290 
1291  Iterator tmp = std::copy( begin_[0UL], pos, newBegin[0UL] );
1292  tmp->value_ = value;
1293  tmp->index_ = j;
1294  std::copy( pos, end_[m_-1UL], tmp+1UL );
1295 
1296  std::swap( newBegin, begin_ );
1297  end_ = newEnd;
1298  delete [] newBegin[0UL];
1299  delete [] newBegin;
1300 
1301  return tmp;
1302  }
1303 }
1304 //*************************************************************************************************
1305 
1306 
1307 //*************************************************************************************************
1316 template< typename Type // Data type of the sparse matrix
1317  , bool SO > // Storage order
1318 inline void CompressedMatrix<Type,SO>::erase( size_t i, size_t j )
1319 {
1320  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1321  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1322 
1323  const Iterator pos( find( i, j ) );
1324  if( pos != end_[i] )
1325  end_[i] = std::copy( pos+1, end_[i], pos );
1326 }
1327 //*************************************************************************************************
1328 
1329 
1330 //*************************************************************************************************
1339 template< typename Type // Data type of the sparse matrix
1340  , bool SO > // Storage order
1343 {
1344  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1345  BLAZE_USER_ASSERT( pos >= begin_[i] && pos <= end_[i], "Invalid compressed matrix iterator" );
1346 
1347  if( pos != end_[i] )
1348  end_[i] = std::copy( pos+1, end_[i], pos );
1349 
1350  return pos;
1351 }
1352 //*************************************************************************************************
1353 
1354 
1355 //*************************************************************************************************
1369 template< typename Type // Data type of the sparse matrix
1370  , bool SO > // Storage order
1372  CompressedMatrix<Type,SO>::find( size_t i, size_t j )
1373 {
1374  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
1375 }
1376 //*************************************************************************************************
1377 
1378 
1379 //*************************************************************************************************
1393 template< typename Type // Data type of the sparse matrix
1394  , bool SO > // Storage order
1396  CompressedMatrix<Type,SO>::find( size_t i, size_t j ) const
1397 {
1398  const Iterator pos( std::lower_bound( begin_[i], end_[i], j, FindIndex() ) );
1399  if( pos != end_[i] && pos->index_ == j )
1400  return pos;
1401  else return end_[i];
1402 }
1403 //*************************************************************************************************
1404 
1405 
1406 //*************************************************************************************************
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  if( m == m_ && n == n_ ) return;
1424 
1425  if( m > capacity_ )
1426  {
1427  Iterator* newBegin( new Iterator[2*m+2] );
1428  Iterator* newEnd ( newBegin+m+1 );
1429 
1430  newBegin[0UL] = begin_[0UL];
1431 
1432  if( preserve ) {
1433  for( size_t i=0UL; i<m_; ++i ) {
1434  newEnd [i] = end_ [i];
1435  newBegin[i+1UL] = begin_[i+1UL];
1436  }
1437  for( size_t i=m_; i<m; ++i ) {
1438  newBegin[i+1UL] = newEnd[i] = begin_[m_];
1439  }
1440  }
1441  else {
1442  for( size_t i=0UL; i<m; ++i ) {
1443  newBegin[i+1UL] = newEnd[i] = begin_[0UL];
1444  }
1445  }
1446 
1447  newEnd[m] = end_[m_];
1448 
1449  std::swap( newBegin, begin_ );
1450  delete [] newBegin;
1451 
1452  end_ = newEnd;
1453  capacity_ = m;
1454  }
1455  else if( m > m_ )
1456  {
1457  end_[m] = end_[m_];
1458 
1459  if( !preserve ) {
1460  for( size_t i=0UL; i<m_; ++i )
1461  end_[i] = begin_[i];
1462  }
1463 
1464  for( size_t i=m_; i<m; ++i )
1465  begin_[i+1UL] = end_[i] = begin_[m_];
1466  }
1467  else
1468  {
1469  if( preserve ) {
1470  for( size_t i=0UL; i<m; ++i )
1471  end_[i] = std::lower_bound( begin_[i], end_[i], n, FindIndex() );
1472  }
1473  else {
1474  for( size_t i=0UL; i<m; ++i )
1475  end_[i] = begin_[i];
1476  }
1477 
1478  end_[m] = end_[m_];
1479  }
1480 
1481  m_ = m;
1482  n_ = n;
1483 }
1484 //*************************************************************************************************
1485 
1486 
1487 //*************************************************************************************************
1497 template< typename Type // Data type of the sparse matrix
1498  , bool SO > // Storage order
1499 inline void CompressedMatrix<Type,SO>::reserve( size_t nonzeros )
1500 {
1501  if( nonzeros > capacity() )
1502  reserveElements( nonzeros );
1503 }
1504 //*************************************************************************************************
1505 
1506 
1507 //*************************************************************************************************
1521 template< typename Type // Data type of the sparse matrix
1522  , bool SO > // Storage order
1523 void CompressedMatrix<Type,SO>::reserve( size_t i, size_t nonzeros )
1524 {
1525  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1526 
1527  const size_t current( capacity(i) );
1528 
1529  if( current >= nonzeros ) return;
1530 
1531  const ptrdiff_t additional( nonzeros - current );
1532 
1533  if( end_[m_] - begin_[m_] < additional )
1534  {
1535  const size_t newCapacity( begin_[m_] - begin_[0UL] + additional );
1536  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
1537 
1538  Iterator* newBegin( new Iterator[2UL*m_+2UL] );
1539  Iterator* newEnd ( newBegin+m_+1UL );
1540 
1541  newBegin[0UL] = new Element[newCapacity];
1542  newEnd [m_ ] = newBegin[0UL]+newCapacity;
1543 
1544  for( size_t k=0UL; k<i; ++k ) {
1545  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
1546  newBegin[k+1UL] = newBegin[k] + capacity(k);
1547  }
1548  newEnd [i ] = std::copy( begin_[i], end_[i], newBegin[i] );
1549  newBegin[i+1UL] = newBegin[i] + nonzeros;
1550  for( size_t k=i+1UL; k<m_; ++k ) {
1551  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
1552  newBegin[k+1UL] = newBegin[k] + capacity(k);
1553  }
1554 
1555  BLAZE_INTERNAL_ASSERT( newBegin[m_] == newEnd[m_], "Invalid pointer calculations" );
1556 
1557  std::swap( newBegin, begin_ );
1558  delete [] newBegin[0UL];
1559  delete [] newBegin;
1560  end_ = newEnd;
1561  }
1562  else
1563  {
1564  begin_[m_] += additional;
1565  for( size_t j=m_-1UL; j>i; --j ) {
1566  begin_[j] = std::copy_backward( begin_[j], end_[j], end_[j]+additional );
1567  end_ [j] += additional;
1568  }
1569  }
1570 }
1571 //*************************************************************************************************
1572 
1573 
1574 //*************************************************************************************************
1579 template< typename Type // Data type of the sparse matrix
1580  , bool SO > // Storage order
1582 {
1583  CompressedMatrix tmp( trans( *this ) );
1584  swap( tmp );
1585  return *this;
1586 }
1587 //*************************************************************************************************
1588 
1589 
1590 //*************************************************************************************************
1607 template< typename Type // Data type of the sparse matrix
1608  , bool SO > // Storage order
1610 {
1611  if( m_ != n_ ) return false;
1612 
1613  for( size_t i=0UL; i<rows(); ++i ) {
1614  for( ConstIterator element=begin_[i]; element!=end_[i]; ++element )
1615  if( element->index_ != i && !isDefault( element->value_ ) )
1616  return false;
1617  }
1618 
1619  return true;
1620 }
1621 //*************************************************************************************************
1622 
1623 
1624 //*************************************************************************************************
1629 template< typename Type // Data type of the sparse matrix
1630  , bool SO > // Storage order
1632 {
1633  if( m_ != n_ ) return false;
1634 
1635  for( size_t i=0UL; i<rows(); ++i ) {
1636  for( ConstIterator element=begin_[i]; element!=end_[i]; ++element )
1637  {
1638  const size_t index( element->index_ );
1639 
1640  if( isDefault( element->value_ ) )
1641  continue;
1642 
1643  const Iterator pos( std::lower_bound( begin_[index], end_[index], i, FindIndex() ) );
1644  if( pos == end_[index] || pos->index_ != i || !equal( pos->value_, element->value_ ) )
1645  return false;
1646  }
1647  }
1648 
1649  return true;
1650 }
1651 //*************************************************************************************************
1652 
1653 
1654 //*************************************************************************************************
1660 template< typename Type // Data type of the sparse matrix
1661  , bool SO > // Storage order
1662 template< typename Other > // Data type of the scalar value
1664 {
1665  for( size_t i=0UL; i<m_; ++i )
1666  for( Iterator element=begin_[i]; element!=end_[i]; ++element )
1667  element->value_ *= scalar;
1668 
1669  return *this;
1670 }
1671 //*************************************************************************************************
1672 
1673 
1674 //*************************************************************************************************
1680 template< typename Type // Data type of the sparse matrix
1681  , bool SO > // Storage order
1682 template< typename Other > // Data type of the scalar value
1684 {
1685  const size_t size( blaze::min( m_, n_ ) );
1686 
1687  for( size_t i=0UL; i<size; ++i ) {
1688  Iterator pos = std::lower_bound( begin_[i], end_[i], i, FindIndex() );
1689  if( pos != end_[i] && pos->index_ == i )
1690  pos->value_ *= scalar;
1691  }
1692 
1693  return *this;
1694 }
1695 //*************************************************************************************************
1696 
1697 
1698 //*************************************************************************************************
1705 template< typename Type // Data type of the sparse matrix
1706  , bool SO > // Storage order
1707 inline void CompressedMatrix<Type,SO>::swap( CompressedMatrix& sm ) /* throw() */
1708 {
1709  std::swap( m_, sm.m_ );
1710  std::swap( n_, sm.n_ );
1711  std::swap( capacity_, sm.capacity_ );
1712  std::swap( begin_, sm.begin_ );
1713  std::swap( end_ , sm.end_ );
1714 }
1715 //*************************************************************************************************
1716 
1717 
1718 //*************************************************************************************************
1726 template< typename Type // Data type of the sparse matrix
1727  , bool SO > // Storage order
1729 {
1730  size_t nonzeros( 2UL*capacity()+1UL );
1731  nonzeros = blaze::max( nonzeros, 7UL );
1732  nonzeros = blaze::min( nonzeros, m_*n_ );
1733 
1734  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
1735 
1736  return nonzeros;
1737 }
1738 //*************************************************************************************************
1739 
1740 
1741 //*************************************************************************************************
1747 template< typename Type // Data type of the sparse matrix
1748  , bool SO > // Storage order
1750 {
1751  Iterator* newBegin = new Iterator[2UL*m_+2UL];
1752  Iterator* newEnd = newBegin+m_+1UL;
1753 
1754  newBegin[0UL] = new Element[nonzeros];
1755 
1756  for( size_t k=0UL; k<m_; ++k ) {
1757  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid row pointers" );
1758  newEnd [k] = std::copy( begin_[k], end_[k], newBegin[k] );
1759  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
1760  }
1761 
1762  newEnd[m_] = newBegin[0UL]+nonzeros;
1763 
1764  std::swap( newBegin, begin_ );
1765  delete [] newBegin[0UL];
1766  delete [] newBegin;
1767  end_ = newEnd;
1768 }
1769 //*************************************************************************************************
1770 
1771 
1772 
1773 
1774 //=================================================================================================
1775 //
1776 // LOW-LEVEL UTILITY FUNCTIONS
1777 //
1778 //=================================================================================================
1779 
1780 //*************************************************************************************************
1820 template< typename Type // Data type of the sparse matrix
1821  , bool SO > // Storage order
1822 inline void CompressedMatrix<Type,SO>::append( size_t i, size_t j, const Type& value, bool check )
1823 {
1824  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
1825  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
1826  BLAZE_USER_ASSERT( end_[i] < end_[m_], "Not enough reserved space left" );
1827  BLAZE_USER_ASSERT( begin_[i] == end_[i] || j > ( end_[i]-1UL )->index_, "Index is not strictly increasing" );
1828 
1829  end_[i]->value_ = value;
1830 
1831  if( !check || !isDefault( end_[i]->value_ ) ) {
1832  end_[i]->index_ = j;
1833  ++end_[i];
1834  }
1835 }
1836 //*************************************************************************************************
1837 
1838 
1839 //*************************************************************************************************
1852 template< typename Type // Data type of the sparse matrix
1853  , bool SO > // Storage order
1855 {
1856  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
1857 
1858  begin_[i+1UL] = end_[i];
1859  if( i != m_-1UL )
1860  end_[i+1UL] = end_[i];
1861 }
1862 //*************************************************************************************************
1863 
1864 
1865 
1866 
1867 //=================================================================================================
1868 //
1869 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1870 //
1871 //=================================================================================================
1872 
1873 //*************************************************************************************************
1883 template< typename Type // Data type of the sparse matrix
1884  , bool SO > // Storage order
1885 template< typename Other > // Data type of the foreign expression
1886 inline bool CompressedMatrix<Type,SO>::canAlias( const Other* alias ) const
1887 {
1888  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1889 }
1890 //*************************************************************************************************
1891 
1892 
1893 //*************************************************************************************************
1903 template< typename Type // Data type of the sparse matrix
1904  , bool SO > // Storage order
1905 template< typename Other > // Data type of the foreign expression
1906 inline bool CompressedMatrix<Type,SO>::isAliased( const Other* alias ) const
1907 {
1908  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1909 }
1910 //*************************************************************************************************
1911 
1912 
1913 //*************************************************************************************************
1924 template< typename Type // Data type of the sparse matrix
1925  , bool SO > // Storage order
1926 template< typename MT // Type of the right-hand side dense matrix
1927  , bool SO2 > // Storage order of the right-hand side dense matrix
1929 {
1930  size_t nonzeros( 0UL );
1931 
1932  for( size_t i=1UL; i<=m_; ++i )
1933  begin_[i] = end_[i] = end_[m_];
1934 
1935  for( size_t i=0UL; i<m_; ++i )
1936  {
1937  begin_[i] = end_[i] = begin_[0UL]+nonzeros;
1938 
1939  for( size_t j=0UL; j<n_; ++j )
1940  {
1941  if( nonzeros == capacity() ) {
1942  reserveElements( extendCapacity() );
1943  for( size_t k=i+1UL; k<=m_; ++k )
1944  begin_[k] = end_[k] = end_[m_];
1945  }
1946 
1947  end_[i]->value_ = (~rhs)(i,j);
1948 
1949  if( !isDefault( end_[i]->value_ ) ) {
1950  end_[i]->index_ = j;
1951  ++end_[i];
1952  ++nonzeros;
1953  }
1954  }
1955  }
1956 
1957  begin_[m_] = begin_[0UL]+nonzeros;
1958 }
1959 //*************************************************************************************************
1960 
1961 
1962 //*************************************************************************************************
1973 template< typename Type // Data type of the sparse matrix
1974  , bool SO > // Storage order
1975 template< typename MT > // Type of the right-hand side sparse matrix
1977 {
1978  for( size_t i=0UL; i<(~rhs).rows(); ++i ) {
1979  begin_[i+1UL] = end_[i] = std::copy( (~rhs).begin(i), (~rhs).end(i), begin_[i] );
1980  }
1981 }
1982 //*************************************************************************************************
1983 
1984 
1985 //*************************************************************************************************
1996 template< typename Type // Data type of the sparse matrix
1997  , bool SO > // Storage order
1998 template< typename MT > // Type of the right-hand side sparse matrix
2000 {
2001  typedef typename MT::ConstIterator RhsIterator;
2002 
2003  // Counting the number of elements per row
2004  std::vector<size_t> rowLengths( m_, 0UL );
2005  for( size_t j=0UL; j<n_; ++j ) {
2006  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2007  ++rowLengths[element->index()];
2008  }
2009 
2010  // Resizing the sparse matrix
2011  for( size_t i=0UL; i<m_; ++i ) {
2012  begin_[i+1UL] = end_[i+1UL] = begin_[i] + rowLengths[i];
2013  }
2014 
2015  // Appending the elements to the rows of the sparse matrix
2016  for( size_t j=0UL; j<n_; ++j ) {
2017  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2018  append( element->index(), j, element->value() );
2019  }
2020 }
2021 //*************************************************************************************************
2022 
2023 
2024 //*************************************************************************************************
2035 template< typename Type // Data type of the sparse matrix
2036  , bool SO > // Storage order
2037 template< typename MT // Type of the right-hand side dense matrix
2038  , bool SO2 > // Storage order of the right-hand side dense matrix
2040 {
2041  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2042  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2043 
2044  CompressedMatrix tmp( *this + (~rhs) );
2045  swap( tmp );
2046 }
2047 //*************************************************************************************************
2048 
2049 
2050 //*************************************************************************************************
2061 template< typename Type // Data type of the sparse matrix
2062  , bool SO > // Storage order
2063 template< typename MT // Type of the right-hand side sparse matrix
2064  , bool SO2 > // Storage order of the right-hand side sparse matrix
2066 {
2067  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2068  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2069 
2070  CompressedMatrix tmp( *this + (~rhs) );
2071  swap( tmp );
2072 }
2073 //*************************************************************************************************
2074 
2075 
2076 //*************************************************************************************************
2087 template< typename Type // Data type of the sparse matrix
2088  , bool SO > // Storage order
2089 template< typename MT // Type of the right-hand side dense matrix
2090  , bool SO2 > // Storage order of the right-hand side dense matrix
2092 {
2093  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2094  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2095 
2096  CompressedMatrix tmp( *this - (~rhs) );
2097  swap( tmp );
2098 }
2099 //*************************************************************************************************
2100 
2101 
2102 //*************************************************************************************************
2113 template< typename Type // Data type of the sparse matrix
2114  , bool SO > // Storage order
2115 template< typename MT // Type of the right-hand side sparse matrix
2116  , bool SO2 > // Storage order of the right-hand sparse matrix
2118 {
2119  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2120  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2121 
2122  CompressedMatrix tmp( *this - (~rhs) );
2123  swap( tmp );
2124 }
2125 //*************************************************************************************************
2126 
2127 
2128 
2129 
2130 
2131 
2132 
2133 
2134 //=================================================================================================
2135 //
2136 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2137 //
2138 //=================================================================================================
2139 
2140 //*************************************************************************************************
2148 template< typename Type > // Data type of the sparse matrix
2149 class CompressedMatrix<Type,true> : public SparseMatrix< CompressedMatrix<Type,true>, true >
2150 {
2151  private:
2152  //**Type definitions****************************************************************************
2154  //**********************************************************************************************
2155 
2156  //**Private class Element***********************************************************************
2160  struct Element : public ElementBase
2161  {
2162  using ElementBase::operator=;
2163  friend class CompressedMatrix;
2164  };
2166  //**********************************************************************************************
2167 
2168  //**Private class FindIndex*********************************************************************
2172  struct FindIndex : public std::binary_function<Element,size_t,bool>
2173  {
2174  inline bool operator()( const Element& element, size_t index ) const {
2175  return element.index() < index;
2176  }
2177  inline bool operator()( size_t index, const Element& element ) const {
2178  return index < element.index();
2179  }
2180  inline bool operator()( const Element& element1, const Element& element2 ) const {
2181  return element1.index() < element2.index();
2182  }
2183  };
2185  //**********************************************************************************************
2186 
2187  public:
2188  //**Type definitions****************************************************************************
2189  typedef CompressedMatrix<Type,true> This;
2190  typedef This ResultType;
2191  typedef CompressedMatrix<Type,false> OppositeType;
2192  typedef CompressedMatrix<Type,false> TransposeType;
2193  typedef Type ElementType;
2194  typedef const Type& ReturnType;
2195  typedef const This& CompositeType;
2196  typedef MatrixAccessProxy<This> Reference;
2197  typedef const Type& ConstReference;
2198  typedef Element* Iterator;
2199  typedef const Element* ConstIterator;
2200  //**********************************************************************************************
2201 
2202  //**Constructors********************************************************************************
2205  explicit inline CompressedMatrix();
2206  explicit inline CompressedMatrix( size_t m, size_t n );
2207  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
2208  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
2209  inline CompressedMatrix( const CompressedMatrix& sm );
2210  template< typename MT, bool SO > inline CompressedMatrix( const DenseMatrix<MT,SO>& dm );
2211  template< typename MT, bool SO > inline CompressedMatrix( const SparseMatrix<MT,SO>& sm );
2213  //**********************************************************************************************
2214 
2215  //**Destructor**********************************************************************************
2218  inline ~CompressedMatrix();
2220  //**********************************************************************************************
2221 
2222  //**Data access functions***********************************************************************
2225  inline Reference operator()( size_t i, size_t j );
2226  inline ConstReference operator()( size_t i, size_t j ) const;
2227  inline Iterator begin ( size_t i );
2228  inline ConstIterator begin ( size_t i ) const;
2229  inline ConstIterator cbegin( size_t i ) const;
2230  inline Iterator end ( size_t i );
2231  inline ConstIterator end ( size_t i ) const;
2232  inline ConstIterator cend ( size_t i ) const;
2234  //**********************************************************************************************
2235 
2236  //**Assignment operators************************************************************************
2239  inline CompressedMatrix& operator= ( const CompressedMatrix& rhs );
2240  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO>& rhs );
2241  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO>& rhs );
2242  template< typename MT, bool SO > inline CompressedMatrix& operator+=( const Matrix<MT,SO>& rhs );
2243  template< typename MT, bool SO > inline CompressedMatrix& operator-=( const Matrix<MT,SO>& rhs );
2244  template< typename MT, bool SO > inline CompressedMatrix& operator*=( const Matrix<MT,SO>& rhs );
2245 
2246  template< typename Other >
2247  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
2248  operator*=( Other rhs );
2249 
2250  template< typename Other >
2251  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
2252  operator/=( Other rhs );
2254  //**********************************************************************************************
2255 
2256  //**Utility functions***************************************************************************
2259  inline size_t rows() const;
2260  inline size_t columns() const;
2261  inline size_t capacity() const;
2262  inline size_t capacity( size_t j ) const;
2263  inline size_t nonZeros() const;
2264  inline size_t nonZeros( size_t j ) const;
2265  inline void reset();
2266  inline void reset( size_t j );
2267  inline void clear();
2268  Iterator insert ( size_t i, size_t j, const Type& value );
2269  inline void erase ( size_t i, size_t j );
2270  inline Iterator erase ( size_t j, Iterator pos );
2271  inline Iterator find ( size_t i, size_t j );
2272  inline ConstIterator find ( size_t i, size_t j ) const;
2273  void resize ( size_t m, size_t n, bool preserve=true );
2274  inline void reserve( size_t nonzeros );
2275  void reserve( size_t j, size_t nonzeros );
2276  inline CompressedMatrix& transpose();
2277  bool isDiagonal() const;
2278  bool isSymmetric() const;
2279  template< typename Other > inline CompressedMatrix& scale( Other scalar );
2280  template< typename Other > inline CompressedMatrix& scaleDiagonal( Other scalar );
2281  inline void swap( CompressedMatrix& sm ) /* throw() */;
2283  //**********************************************************************************************
2284 
2285  //**Utility functions***************************************************************************
2288  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
2289  inline void finalize( size_t j );
2291  //**********************************************************************************************
2292 
2293  //**Expression template evaluation functions****************************************************
2296  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2297  template< typename Other > inline bool isAliased( const Other* alias ) const;
2298  template< typename MT, bool SO > inline void assign ( const DenseMatrix<MT,SO>& rhs );
2299  template< typename MT > inline void assign ( const SparseMatrix<MT,true>& rhs );
2300  template< typename MT > inline void assign ( const SparseMatrix<MT,false>& rhs );
2301  template< typename MT, bool SO > inline void addAssign( const DenseMatrix<MT,SO>& rhs );
2302  template< typename MT, bool SO > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
2303  template< typename MT, bool SO > inline void subAssign( const DenseMatrix<MT,SO>& rhs );
2304  template< typename MT, bool SO > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
2306  //**********************************************************************************************
2307 
2308  private:
2309  //**Utility functions***************************************************************************
2312  inline size_t extendCapacity() const;
2313  void reserveElements( size_t nonzeros );
2315  //**********************************************************************************************
2316 
2317  //**Member variables****************************************************************************
2320  size_t m_;
2321  size_t n_;
2322  size_t capacity_;
2323  Iterator* begin_;
2324  Iterator* end_;
2325 
2326  static const Type zero_;
2327 
2328  //**********************************************************************************************
2329 
2330  //**Compile time checks*************************************************************************
2338  //**********************************************************************************************
2339 };
2341 //*************************************************************************************************
2342 
2343 
2344 
2345 
2346 //=================================================================================================
2347 //
2348 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
2349 //
2350 //=================================================================================================
2351 
2352 template< typename Type >
2353 const Type CompressedMatrix<Type,true>::zero_ = Type();
2354 
2355 
2356 
2357 
2358 //=================================================================================================
2359 //
2360 // CONSTRUCTORS
2361 //
2362 //=================================================================================================
2363 
2364 //*************************************************************************************************
2368 template< typename Type > // Data type of the sparse matrix
2370  : m_ ( 0UL ) // The current number of rows of the sparse matrix
2371  , n_ ( 0UL ) // The current number of columns of the sparse matrix
2372  , capacity_( 0UL ) // The current capacity of the pointer array
2373  , begin_( new Iterator[2UL] ) // Pointers to the first non-zero element of each column
2374  , end_ ( begin_+1UL ) // Pointers one past the last non-zero element of each column
2375 {
2376  begin_[0UL] = end_[0UL] = NULL;
2377 }
2379 //*************************************************************************************************
2380 
2381 
2382 //*************************************************************************************************
2391 template< typename Type > // Data type of the sparse matrix
2392 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n )
2393  : m_ ( m ) // The current number of rows of the sparse matrix
2394  , n_ ( n ) // The current number of columns of the sparse matrix
2395  , capacity_( n ) // The current capacity of the pointer array
2396  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
2397  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
2398 {
2399  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
2400  begin_[j] = NULL;
2401 }
2403 //*************************************************************************************************
2404 
2405 
2406 //*************************************************************************************************
2416 template< typename Type > // Data type of the sparse matrix
2417 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
2418  : m_ ( m ) // The current number of rows of the sparse matrix
2419  , n_ ( n ) // The current number of columns of the sparse matrix
2420  , capacity_( n ) // The current capacity of the pointer array
2421  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
2422  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
2423 {
2424  begin_[0UL] = new Element[nonzeros];
2425  for( size_t j=1UL; j<(2UL*n_+1UL); ++j )
2426  begin_[j] = begin_[0UL];
2427  end_[n_] = begin_[0UL]+nonzeros;
2428 }
2430 //*************************************************************************************************
2431 
2432 
2433 //*************************************************************************************************
2443 template< typename Type > // Data type of the sparse matrix
2444 CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
2445  : m_ ( m ) // The current number of rows of the sparse matrix
2446  , n_ ( n ) // The current number of columns of the sparse matrix
2447  , capacity_( n ) // The current capacity of the pointer array
2448  , begin_( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2449  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2450 {
2451  BLAZE_USER_ASSERT( nonzeros.size() == n, "Size of capacity vector and number of columns don't match" );
2452 
2453  size_t newCapacity( 0UL );
2454  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
2455  newCapacity += *it;
2456 
2457  begin_[0UL] = end_[0UL] = new Element[newCapacity];
2458  for( size_t j=0UL; j<n_; ++j ) {
2459  begin_[j+1UL] = end_[j+1UL] = begin_[j] + nonzeros[j];
2460  }
2461 }
2463 //*************************************************************************************************
2464 
2465 
2466 //*************************************************************************************************
2472 template< typename Type > // Data type of the sparse matrix
2473 inline CompressedMatrix<Type,true>::CompressedMatrix( const CompressedMatrix& sm )
2474  : m_ ( sm.m_ ) // The current number of rows of the sparse matrix
2475  , n_ ( sm.n_ ) // The current number of columns of the sparse matrix
2476  , capacity_( sm.n_ ) // The current capacity of the pointer array
2477  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2478  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2479 {
2480  const size_t nonzeros( sm.nonZeros() );
2481 
2482  begin_[0UL] = new Element[nonzeros];
2483  for( size_t j=0UL; j<n_; ++j )
2484  begin_[j+1UL] = end_[j] = std::copy( sm.begin(j), sm.end(j), begin_[j] );
2485  end_[n_] = begin_[0UL]+nonzeros;
2486 }
2488 //*************************************************************************************************
2489 
2490 
2491 //*************************************************************************************************
2497 template< typename Type > // Data type of the sparse matrix
2498 template< typename MT // Type of the foreign dense matrix
2499  , bool SO > // Storage order of the foreign dense matrix
2500 inline CompressedMatrix<Type,true>::CompressedMatrix( const DenseMatrix<MT,SO>& dm )
2501  : m_ ( (~dm).rows() ) // The current number of rows of the sparse matrix
2502  , n_ ( (~dm).columns() ) // The current number of columns of the sparse matrix
2503  , capacity_( n_ ) // The current capacity of the pointer array
2504  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2505  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2506 {
2507  using blaze::assign;
2508 
2509  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
2510  begin_[j] = NULL;
2511 
2512  assign( *this, ~dm );
2513 }
2515 //*************************************************************************************************
2516 
2517 
2518 //*************************************************************************************************
2524 template< typename Type > // Data type of the sparse matrix
2525 template< typename MT // Type of the foreign sparse matrix
2526  , bool SO > // Storage order of the foreign sparse matrix
2527 inline CompressedMatrix<Type,true>::CompressedMatrix( const SparseMatrix<MT,SO>& sm )
2528  : m_ ( (~sm).rows() ) // The current number of rows of the sparse matrix
2529  , n_ ( (~sm).columns() ) // The current number of columns of the sparse matrix
2530  , capacity_( n_ ) // The current capacity of the pointer array
2531  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2532  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2533 {
2534  using blaze::assign;
2535 
2536  const size_t nonzeros( (~sm).nonZeros() );
2537 
2538  begin_[0UL] = new Element[nonzeros];
2539  for( size_t j=0UL; j<n_; ++j )
2540  begin_[j+1UL] = end_[j] = begin_[0UL];
2541  end_[n_] = begin_[0UL]+nonzeros;
2542 
2543  assign( *this, ~sm );
2544 }
2546 //*************************************************************************************************
2547 
2548 
2549 
2550 
2551 //=================================================================================================
2552 //
2553 // DESTRUCTOR
2554 //
2555 //=================================================================================================
2556 
2557 //*************************************************************************************************
2561 template< typename Type > // Data type of the sparse matrix
2563 {
2564  delete [] begin_[0UL];
2565  delete [] begin_;
2566 }
2568 //*************************************************************************************************
2569 
2570 
2571 
2572 
2573 //=================================================================================================
2574 //
2575 // DATA ACCESS FUNCTIONS
2576 //
2577 //=================================================================================================
2578 
2579 //*************************************************************************************************
2587 template< typename Type > // Data type of the sparse matrix
2588 inline typename CompressedMatrix<Type,true>::Reference
2589  CompressedMatrix<Type,true>::operator()( size_t i, size_t j )
2590 {
2591  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2592  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2593 
2594  return Reference( *this, i, j );
2595 }
2597 //*************************************************************************************************
2598 
2599 
2600 //*************************************************************************************************
2608 template< typename Type > // Data type of the sparse matrix
2609 inline typename CompressedMatrix<Type,true>::ConstReference
2610  CompressedMatrix<Type,true>::operator()( size_t i, size_t j ) const
2611 {
2612  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2613  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2614 
2615  const ConstIterator pos( std::lower_bound( begin_[j], end_[j], i, FindIndex() ) );
2616 
2617  if( pos == end_[j] || pos->index_ != i )
2618  return zero_;
2619  else
2620  return pos->value_;
2621 }
2623 //*************************************************************************************************
2624 
2625 
2626 //*************************************************************************************************
2633 template< typename Type > // Data type of the sparse matrix
2634 inline typename CompressedMatrix<Type,true>::Iterator
2636 {
2637  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2638  return begin_[j];
2639 }
2641 //*************************************************************************************************
2642 
2643 
2644 //*************************************************************************************************
2651 template< typename Type > // Data type of the sparse matrix
2652 inline typename CompressedMatrix<Type,true>::ConstIterator
2653  CompressedMatrix<Type,true>::begin( size_t j ) const
2654 {
2655  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2656  return begin_[j];
2657 }
2659 //*************************************************************************************************
2660 
2661 
2662 //*************************************************************************************************
2669 template< typename Type > // Data type of the sparse matrix
2670 inline typename CompressedMatrix<Type,true>::ConstIterator
2671  CompressedMatrix<Type,true>::cbegin( size_t j ) const
2672 {
2673  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2674  return begin_[j];
2675 }
2677 //*************************************************************************************************
2678 
2679 
2680 //*************************************************************************************************
2687 template< typename Type > // Data type of the sparse matrix
2688 inline typename CompressedMatrix<Type,true>::Iterator
2690 {
2691  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2692  return end_[j];
2693 }
2695 //*************************************************************************************************
2696 
2697 
2698 //*************************************************************************************************
2705 template< typename Type > // Data type of the sparse matrix
2706 inline typename CompressedMatrix<Type,true>::ConstIterator
2707  CompressedMatrix<Type,true>::end( size_t j ) const
2708 {
2709  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2710  return end_[j];
2711 }
2713 //*************************************************************************************************
2714 
2715 
2716 //*************************************************************************************************
2723 template< typename Type > // Data type of the sparse matrix
2724 inline typename CompressedMatrix<Type,true>::ConstIterator
2725  CompressedMatrix<Type,true>::cend( size_t j ) const
2726 {
2727  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2728  return end_[j];
2729 }
2731 //*************************************************************************************************
2732 
2733 
2734 
2735 
2736 //=================================================================================================
2737 //
2738 // ASSIGNMENT OPERATORS
2739 //
2740 //=================================================================================================
2741 
2742 //*************************************************************************************************
2752 template< typename Type > // Data type of the sparse matrix
2753 inline CompressedMatrix<Type,true>&
2754  CompressedMatrix<Type,true>::operator=( const CompressedMatrix& rhs )
2755 {
2756  if( &rhs == this ) return *this;
2757 
2758  const size_t nonzeros( rhs.nonZeros() );
2759 
2760  if( rhs.n_ > capacity_ || nonzeros > capacity() )
2761  {
2762  Iterator* newBegin( new Iterator[2UL*rhs.n_+2UL] );
2763  Iterator* newEnd ( newBegin+(rhs.n_+1UL) );
2764 
2765  newBegin[0UL] = new Element[nonzeros];
2766  for( size_t j=0UL; j<rhs.n_; ++j ) {
2767  newBegin[j+1UL] = newEnd[j] = std::copy( rhs.begin_[j], rhs.end_[j], newBegin[j] );
2768  }
2769  newEnd[rhs.n_] = newBegin[0UL]+nonzeros;
2770 
2771  std::swap( begin_, newBegin );
2772  end_ = newEnd;
2773  delete [] newBegin[0UL];
2774  delete [] newBegin;
2775  capacity_ = rhs.n_;
2776  }
2777  else {
2778  for( size_t j=0UL; j<rhs.n_; ++j ) {
2779  begin_[j+1UL] = end_[j] = std::copy( rhs.begin_[j], rhs.end_[j], begin_[j] );
2780  }
2781  }
2782 
2783  m_ = rhs.m_;
2784  n_ = rhs.n_;
2785 
2786  return *this;
2787 }
2789 //*************************************************************************************************
2790 
2791 
2792 //*************************************************************************************************
2802 template< typename Type > // Data type of the sparse matrix
2803 template< typename MT // Type of the right-hand side dense matrix
2804  , bool SO > // Storage order of the right-hand side dense matrix
2805 inline CompressedMatrix<Type,true>&
2806  CompressedMatrix<Type,true>::operator=( const DenseMatrix<MT,SO>& rhs )
2807 {
2808  using blaze::assign;
2809 
2810  if( (~rhs).canAlias( this ) ) {
2811  CompressedMatrix tmp( rhs );
2812  swap( tmp );
2813  }
2814  else {
2815  resize( (~rhs).rows(), (~rhs).columns(), false );
2816  assign( *this, ~rhs );
2817  }
2818 
2819  return *this;
2820 }
2822 //*************************************************************************************************
2823 
2824 
2825 //*************************************************************************************************
2835 template< typename Type > // Data type of the sparse matrix
2836 template< typename MT // Type of the right-hand side sparse matrix
2837  , bool SO > // Storage order of the right-hand side sparse matrix
2838 inline CompressedMatrix<Type,true>&
2839  CompressedMatrix<Type,true>::operator=( const SparseMatrix<MT,SO>& rhs )
2840 {
2841  using blaze::assign;
2842 
2843  if( (~rhs).canAlias( this ) ||
2844  (~rhs).columns() > capacity_ ||
2845  (~rhs).nonZeros() > capacity() ) {
2846  CompressedMatrix tmp( rhs );
2847  swap( tmp );
2848  }
2849  else {
2850  resize( (~rhs).rows(), (~rhs).columns(), false );
2851  reset();
2852  assign( *this, ~rhs );
2853  }
2854 
2855  return *this;
2856 }
2858 //*************************************************************************************************
2859 
2860 
2861 //*************************************************************************************************
2872 template< typename Type > // Data type of the sparse matrix
2873 template< typename MT // Type of the right-hand side matrix
2874  , bool SO > // Storage order of the right-hand side matrix
2875 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator+=( const Matrix<MT,SO>& rhs )
2876 {
2877  using blaze::addAssign;
2878 
2879  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
2880  throw std::invalid_argument( "Matrix sizes do not match" );
2881 
2882  addAssign( *this, ~rhs );
2883  return *this;
2884 }
2886 //*************************************************************************************************
2887 
2888 
2889 //*************************************************************************************************
2900 template< typename Type > // Data type of the sparse matrix
2901 template< typename MT // Type of the right-hand side matrix
2902  , bool SO > // Storage order of the right-hand side matrix
2903 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator-=( const Matrix<MT,SO>& rhs )
2904 {
2905  using blaze::subAssign;
2906 
2907  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
2908  throw std::invalid_argument( "Matrix sizes do not match" );
2909 
2910  subAssign( *this, ~rhs );
2911  return *this;
2912 }
2914 //*************************************************************************************************
2915 
2916 
2917 //*************************************************************************************************
2928 template< typename Type > // Data type of the sparse matrix
2929 template< typename MT // Type of the right-hand side matrix
2930  , bool SO > // Storage order of the right-hand side matrix
2931 inline CompressedMatrix<Type,true>&
2932  CompressedMatrix<Type,true>::operator*=( const Matrix<MT,SO>& rhs )
2933 {
2934  if( (~rhs).rows() != n_ )
2935  throw std::invalid_argument( "Matrix sizes do not match" );
2936 
2937  CompressedMatrix tmp( *this * (~rhs) );
2938  swap( tmp );
2939 
2940  return *this;
2941 }
2943 //*************************************************************************************************
2944 
2945 
2946 //*************************************************************************************************
2954 template< typename Type > // Data type of the sparse matrix
2955 template< typename Other > // Data type of the right-hand side scalar
2956 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,true> >::Type&
2957  CompressedMatrix<Type,true>::operator*=( Other rhs )
2958 {
2959  for( size_t j=0UL; j<n_; ++j ) {
2960  const Iterator endElem( end(j) );
2961  for( Iterator elem=begin(j); elem<endElem; ++elem )
2962  elem->value_ *= rhs;
2963  }
2964 
2965  return *this;
2966 }
2968 //*************************************************************************************************
2969 
2970 
2971 //*************************************************************************************************
2979 template< typename Type > // Data type of the sparse matrix
2980 template< typename Other > // Data type of the right-hand side scalar
2981 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,true> >::Type&
2982  CompressedMatrix<Type,true>::operator/=( Other rhs )
2983 {
2984  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
2985 
2986  typedef typename DivTrait<Type,Other>::Type DT;
2987  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
2988 
2989  // Depending on the two involved data types, an integer division is applied or a
2990  // floating point division is selected.
2991  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
2992  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
2993  for( size_t j=0UL; j<n_; ++j ) {
2994  const Iterator endElem( end(j) );
2995  for( Iterator elem=begin(j); elem<endElem; ++elem )
2996  elem->value_ *= tmp;
2997  }
2998  }
2999  else {
3000  for( size_t j=0UL; j<n_; ++j ) {
3001  const Iterator endElem( end(j) );
3002  for( Iterator elem=begin(j); elem<endElem; ++elem )
3003  elem->value_ /= rhs;
3004  }
3005  }
3006 
3007  return *this;
3008 }
3010 //*************************************************************************************************
3011 
3012 
3013 
3014 
3015 //=================================================================================================
3016 //
3017 // UTILITY FUNCTIONS
3018 //
3019 //=================================================================================================
3020 
3021 //*************************************************************************************************
3027 template< typename Type > // Data type of the sparse matrix
3028 inline size_t CompressedMatrix<Type,true>::rows() const
3029 {
3030  return m_;
3031 }
3033 //*************************************************************************************************
3034 
3035 
3036 //*************************************************************************************************
3042 template< typename Type > // Data type of the sparse matrix
3043 inline size_t CompressedMatrix<Type,true>::columns() const
3044 {
3045  return n_;
3046 }
3048 //*************************************************************************************************
3049 
3050 
3051 //*************************************************************************************************
3057 template< typename Type > // Data type of the sparse matrix
3058 inline size_t CompressedMatrix<Type,true>::capacity() const
3059 {
3060  return end_[n_] - begin_[0UL];
3061 }
3063 //*************************************************************************************************
3064 
3065 
3066 //*************************************************************************************************
3073 template< typename Type > // Data type of the sparse matrix
3074 inline size_t CompressedMatrix<Type,true>::capacity( size_t j ) const
3075 {
3076  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3077  return begin_[j+1UL] - begin_[j];
3078 }
3080 //*************************************************************************************************
3081 
3082 
3083 //*************************************************************************************************
3089 template< typename Type > // Data type of the sparse matrix
3090 inline size_t CompressedMatrix<Type,true>::nonZeros() const
3091 {
3092  size_t nonzeros( 0UL );
3093 
3094  for( size_t j=0UL; j<n_; ++j )
3095  nonzeros += nonZeros( j );
3096 
3097  return nonzeros;
3098 }
3100 //*************************************************************************************************
3101 
3102 
3103 //*************************************************************************************************
3110 template< typename Type > // Data type of the sparse matrix
3111 inline size_t CompressedMatrix<Type,true>::nonZeros( size_t j ) const
3112 {
3113  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3114  return end_[j] - begin_[j];
3115 }
3117 //*************************************************************************************************
3118 
3119 
3120 //*************************************************************************************************
3126 template< typename Type > // Data type of the sparse matrix
3128 {
3129  for( size_t j=0UL; j<n_; ++j )
3130  end_[j] = begin_[j];
3131 }
3133 //*************************************************************************************************
3134 
3135 
3136 //*************************************************************************************************
3146 template< typename Type > // Data type of the sparse matrix
3147 inline void CompressedMatrix<Type,true>::reset( size_t j )
3148 {
3149  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3150  end_[j] = begin_[j];
3151 }
3153 //*************************************************************************************************
3154 
3155 
3156 //*************************************************************************************************
3164 template< typename Type > // Data type of the sparse matrix
3166 {
3167  end_[0UL] = end_[n_];
3168  m_ = 0UL;
3169  n_ = 0UL;
3170 }
3172 //*************************************************************************************************
3173 
3174 
3175 //*************************************************************************************************
3189 template< typename Type > // Data type of the sparse matrix
3190 typename CompressedMatrix<Type,true>::Iterator
3191  CompressedMatrix<Type,true>::insert( size_t i, size_t j, const Type& value )
3192 {
3193  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3194  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3195 
3196  const Iterator pos( std::lower_bound( begin_[j], end_[j], i, FindIndex() ) );
3197 
3198  if( pos != end_[j] && pos->index_ == i )
3199  throw std::invalid_argument( "Bad access index" );
3200 
3201  if( begin_[j+1UL] - end_[j] != 0 ) {
3202  std::copy_backward( pos, end_[j], end_[j]+1 );
3203  pos->value_ = value;
3204  pos->index_ = i;
3205  ++end_[j];
3206 
3207  return pos;
3208  }
3209  else if( end_[n_] - begin_[n_] != 0 ) {
3210  std::copy_backward( pos, end_[n_-1UL], end_[n_-1]+1 );
3211 
3212  pos->value_ = value;
3213  pos->index_ = i;
3214 
3215  for( size_t k=j+1UL; k<n_+1UL; ++k ) {
3216  ++begin_[k];
3217  ++end_[k-1UL];
3218  }
3219 
3220  return pos;
3221  }
3222  else {
3223  size_t newCapacity( extendCapacity() );
3224 
3225  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
3226  Iterator* newEnd = newBegin+capacity_+1UL;
3227 
3228  newBegin[0UL] = new Element[newCapacity];
3229 
3230  for( size_t k=0UL; k<j; ++k ) {
3231  const size_t nonzeros( end_[k] - begin_[k] );
3232  const size_t total( begin_[k+1UL] - begin_[k] );
3233  newEnd [k] = newBegin[k] + nonzeros;
3234  newBegin[k+1UL] = newBegin[k] + total;
3235  }
3236  newEnd [j] = newBegin[j] + ( end_[j] - begin_[j] ) + 1;
3237  newBegin[j+1UL] = newBegin[j] + ( begin_[j+1UL] - begin_[j] ) + 1;
3238  for( size_t k=j+1UL; k<n_; ++k ) {
3239  const size_t nonzeros( end_[k] - begin_[k] );
3240  const size_t total( begin_[k+1UL] - begin_[k] );
3241  newEnd [k] = newBegin[k] + nonzeros;
3242  newBegin[k+1UL] = newBegin[k] + total;
3243  }
3244 
3245  newEnd[n_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
3246 
3247  Iterator tmp = std::copy( begin_[0UL], pos, newBegin[0UL] );
3248  tmp->value_ = value;
3249  tmp->index_ = i;
3250  std::copy( pos, end_[n_-1UL], tmp+1UL );
3251 
3252  std::swap( newBegin, begin_ );
3253  end_ = newEnd;
3254  delete [] newBegin[0UL];
3255  delete [] newBegin;
3256 
3257  return tmp;
3258  }
3259 }
3261 //*************************************************************************************************
3262 
3263 
3264 //*************************************************************************************************
3273 template< typename Type > // Data type of the sparse matrix
3274 inline void CompressedMatrix<Type,true>::erase( size_t i, size_t j )
3275 {
3276  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3277  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3278 
3279  const Iterator pos( find( i, j ) );
3280  if( pos != end_[j] )
3281  end_[j] = std::copy( pos+1, end_[j], pos );
3282 }
3283 //*************************************************************************************************
3284 
3285 
3286 //*************************************************************************************************
3295 template< typename Type > // Data type of the sparse matrix
3296 inline typename CompressedMatrix<Type,true>::Iterator
3297  CompressedMatrix<Type,true>::erase( size_t j, Iterator pos )
3298 {
3299  BLAZE_USER_ASSERT( j < columns() , "Invalid row access index" );
3300  BLAZE_USER_ASSERT( pos >= begin_[j] && pos <= end_[j], "Invalid compressed matrix iterator" );
3301 
3302  if( pos != end_[j] )
3303  end_[j] = std::copy( pos+1, end_[j], pos );
3304 
3305  return pos;
3306 }
3307 //*************************************************************************************************
3308 
3309 
3310 //*************************************************************************************************
3325 template< typename Type > // Data type of the sparse matrix
3326 inline typename CompressedMatrix<Type,true>::Iterator
3327  CompressedMatrix<Type,true>::find( size_t i, size_t j )
3328 {
3329  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
3330 }
3332 //*************************************************************************************************
3333 
3334 
3335 //*************************************************************************************************
3350 template< typename Type > // Data type of the sparse matrix
3351 inline typename CompressedMatrix<Type,true>::ConstIterator
3352  CompressedMatrix<Type,true>::find( size_t i, size_t j ) const
3353 {
3354  const Iterator pos( std::lower_bound( begin_[j], end_[j], i, FindIndex() ) );
3355  if( pos != end_[j] && pos->index_ == i )
3356  return pos;
3357  else return end_[j];
3358 }
3360 //*************************************************************************************************
3361 
3362 
3363 //*************************************************************************************************
3377 template< typename Type > // Data type of the sparse matrix
3378 void CompressedMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
3379 {
3380  if( m == m_ && n == n_ ) return;
3381 
3382  if( n > capacity_ )
3383  {
3384  Iterator* newBegin( new Iterator[2UL*n+2UL] );
3385  Iterator* newEnd ( newBegin+n+1 );
3386 
3387  newBegin[0UL] = begin_[0UL];
3388 
3389  if( preserve ) {
3390  for( size_t j=0UL; j<n_; ++j ) {
3391  newEnd [j] = end_ [j];
3392  newBegin[j+1UL] = begin_[j+1UL];
3393  }
3394  for( size_t j=n_; j<n; ++j ) {
3395  newBegin[j+1UL] = newEnd[j] = begin_[n_];
3396  }
3397  }
3398  else {
3399  for( size_t j=0UL; j<n; ++j ) {
3400  newBegin[j+1UL] = newEnd[j] = begin_[0UL];
3401  }
3402  }
3403 
3404  newEnd[n] = end_[n_];
3405 
3406  std::swap( newBegin, begin_ );
3407  delete [] newBegin;
3408 
3409  end_ = newEnd;
3410  capacity_ = n;
3411  }
3412  else if( n > n_ )
3413  {
3414  end_[n] = end_[n_];
3415 
3416  if( !preserve ) {
3417  for( size_t j=0UL; j<n_; ++j )
3418  end_[j] = begin_[j];
3419  }
3420 
3421  for( size_t j=n_; j<n; ++j )
3422  begin_[j+1UL] = end_[j] = begin_[n_];
3423  }
3424  else
3425  {
3426  if( preserve ) {
3427  for( size_t j=0UL; j<n; ++j )
3428  end_[j] = std::lower_bound( begin_[j], end_[j], m, FindIndex() );
3429  }
3430  else {
3431  for( size_t j=0UL; j<n; ++j )
3432  end_[j] = begin_[j];
3433  }
3434 
3435  end_[n] = end_[n_];
3436  }
3437 
3438  m_ = m;
3439  n_ = n;
3440 }
3442 //*************************************************************************************************
3443 
3444 
3445 //*************************************************************************************************
3456 template< typename Type > // Data type of the sparse matrix
3457 inline void CompressedMatrix<Type,true>::reserve( size_t nonzeros )
3458 {
3459  if( nonzeros > capacity() )
3460  reserveElements( nonzeros );
3461 }
3463 //*************************************************************************************************
3464 
3465 
3466 //*************************************************************************************************
3478 template< typename Type > // Data type of the sparse matrix
3479 void CompressedMatrix<Type,true>::reserve( size_t j, size_t nonzeros )
3480 {
3481  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3482 
3483  const size_t current( capacity(j) );
3484 
3485  if( current >= nonzeros ) return;
3486 
3487  const ptrdiff_t additional( nonzeros - current );
3488 
3489  if( end_[n_] - begin_[n_] < additional )
3490  {
3491  const size_t newCapacity( begin_[n_] - begin_[0UL] + additional );
3492  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
3493 
3494  Iterator* newBegin( new Iterator[2UL*n_+2UL] );
3495  Iterator* newEnd ( newBegin+n_+1UL );
3496 
3497  newBegin[0UL] = new Element[newCapacity];
3498  newEnd [n_ ] = newBegin[0UL]+newCapacity;
3499 
3500  for( size_t k=0UL; k<j; ++k ) {
3501  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
3502  newBegin[k+1UL] = newBegin[k] + capacity(k);
3503  }
3504  newEnd [j ] = std::copy( begin_[j], end_[j], newBegin[j] );
3505  newBegin[j+1UL] = newBegin[j] + nonzeros;
3506  for( size_t k=j+1UL; k<n_; ++k ) {
3507  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
3508  newBegin[k+1UL] = newBegin[k] + capacity(k);
3509  }
3510 
3511  BLAZE_INTERNAL_ASSERT( newBegin[n_] == newEnd[n_], "Invalid pointer calculations" );
3512 
3513  std::swap( newBegin, begin_ );
3514  delete [] newBegin[0UL];
3515  delete [] newBegin;
3516  end_ = newEnd;
3517  }
3518  else
3519  {
3520  begin_[n_] += additional;
3521  for( size_t k=n_-1UL; k>j; --k ) {
3522  begin_[k] = std::copy_backward( begin_[k], end_[k], end_[k]+additional );
3523  end_ [k] += additional;
3524  }
3525  }
3526 }
3528 //*************************************************************************************************
3529 
3530 
3531 //*************************************************************************************************
3537 template< typename Type > // Data type of the sparse matrix
3538 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::transpose()
3539 {
3540  CompressedMatrix tmp( trans( *this ) );
3541  swap( tmp );
3542  return *this;
3543 }
3545 //*************************************************************************************************
3546 
3547 
3548 //*************************************************************************************************
3566 template< typename Type > // Data type of the sparse matrix
3568 {
3569  if( m_ != n_ ) return false;
3570 
3571  for( size_t j=0UL; j<columns(); ++j ) {
3572  for( ConstIterator element=begin_[j]; element!=end_[j]; ++element )
3573  if( element->index_ != j && !isDefault( element->value_ ) )
3574  return false;
3575  }
3576 
3577  return true;
3578 }
3580 //*************************************************************************************************
3581 
3582 
3583 //*************************************************************************************************
3589 template< typename Type > // Data type of the sparse matrix
3591 {
3592  if( m_ != n_ ) return false;
3593 
3594  for( size_t j=0UL; j<rows(); ++j ) {
3595  for( ConstIterator element=begin_[j]; element!=end_[j]; ++element )
3596  {
3597  const size_t index( element->index_ );
3598 
3599  if( isDefault( element->value_ ) )
3600  continue;
3601 
3602  const Iterator pos( std::lower_bound( begin_[index], end_[index], j, FindIndex() ) );
3603  if( pos == end_[index] || pos->index_ != j || !equal( pos->value_, element->value_ ) )
3604  return false;
3605  }
3606  }
3607 
3608  return true;
3609 }
3611 //*************************************************************************************************
3612 
3613 
3614 //*************************************************************************************************
3621 template< typename Type > // Data type of the sparse matrix
3622 template< typename Other > // Data type of the scalar value
3623 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scale( Other scalar )
3624 {
3625  for( size_t j=0UL; j<n_; ++j )
3626  for( Iterator element=begin_[j]; element!=end_[j]; ++element )
3627  element->value_ *= scalar;
3628 
3629  return *this;
3630 }
3632 //*************************************************************************************************
3633 
3634 
3635 //*************************************************************************************************
3642 template< typename Type > // Data type of the sparse matrix
3643 template< typename Other > // Data type of the scalar value
3644 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scaleDiagonal( Other scalar )
3645 {
3646  const size_t size( blaze::min( m_, n_ ) );
3647 
3648  for( size_t j=0UL; j<size; ++j ) {
3649  Iterator pos = std::lower_bound( begin_[j], end_[j], j, FindIndex() );
3650  if( pos != end_[j] && pos->index_ == j )
3651  pos->value_ *= scalar;
3652  }
3653 
3654  return *this;
3655 }
3657 //*************************************************************************************************
3658 
3659 
3660 //*************************************************************************************************
3668 template< typename Type > // Data type of the sparse matrix
3669 inline void CompressedMatrix<Type,true>::swap( CompressedMatrix& sm ) /* throw() */
3670 {
3671  std::swap( m_, sm.m_ );
3672  std::swap( n_, sm.n_ );
3673  std::swap( capacity_, sm.capacity_ );
3674  std::swap( begin_, sm.begin_ );
3675  std::swap( end_ , sm.end_ );
3676 }
3678 //*************************************************************************************************
3679 
3680 
3681 //*************************************************************************************************
3690 template< typename Type > // Data type of the sparse matrix
3691 inline size_t CompressedMatrix<Type,true>::extendCapacity() const
3692 {
3693  size_t nonzeros( 2UL*capacity()+1UL );
3694  nonzeros = blaze::max( nonzeros, 7UL );
3695  nonzeros = blaze::min( nonzeros, m_*n_ );
3696 
3697  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
3698 
3699  return nonzeros;
3700 }
3702 //*************************************************************************************************
3703 
3704 
3705 //*************************************************************************************************
3712 template< typename Type > // Data type of the sparse matrix
3713 void CompressedMatrix<Type,true>::reserveElements( size_t nonzeros )
3714 {
3715  Iterator* newBegin = new Iterator[2UL*n_+2UL];
3716  Iterator* newEnd = newBegin+n_+1UL;
3717 
3718  newBegin[0UL] = new Element[nonzeros];
3719 
3720  for( size_t k=0UL; k<n_; ++k ) {
3721  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid column pointers" );
3722  newEnd [k] = std::copy( begin_[k], end_[k], newBegin[k] );
3723  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
3724  }
3725 
3726  newEnd[n_] = newBegin[0UL]+nonzeros;
3727 
3728  std::swap( newBegin, begin_ );
3729  delete [] newBegin[0UL];
3730  delete [] newBegin;
3731  end_ = newEnd;
3732 }
3734 //*************************************************************************************************
3735 
3736 
3737 
3738 
3739 //=================================================================================================
3740 //
3741 // LOW-LEVEL UTILITY FUNCTIONS
3742 //
3743 //=================================================================================================
3744 
3745 //*************************************************************************************************
3786 template< typename Type > // Data type of the sparse matrix
3787 inline void CompressedMatrix<Type,true>::append( size_t i, size_t j, const Type& value, bool check )
3788 {
3789  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
3790  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
3791  BLAZE_USER_ASSERT( end_[j] < end_[n_], "Not enough reserved space left" );
3792  BLAZE_USER_ASSERT( begin_[j] == end_[j] || i > ( end_[j]-1UL )->index_, "Index is not strictly increasing" );
3793 
3794  end_[j]->value_ = value;
3795 
3796  if( !check || !isDefault( end_[j]->value_ ) ) {
3797  end_[j]->index_ = i;
3798  ++end_[j];
3799  }
3800 }
3802 //*************************************************************************************************
3803 
3804 
3805 //*************************************************************************************************
3819 template< typename Type > // Data type of the sparse matrix
3820 inline void CompressedMatrix<Type,true>::finalize( size_t j )
3821 {
3822  BLAZE_USER_ASSERT( j < n_, "Invalid row access index" );
3823 
3824  begin_[j+1UL] = end_[j];
3825  if( j != n_-1UL )
3826  end_[j+1UL] = end_[j];
3827 }
3829 //*************************************************************************************************
3830 
3831 
3832 
3833 
3834 //=================================================================================================
3835 //
3836 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3837 //
3838 //=================================================================================================
3839 
3840 //*************************************************************************************************
3851 template< typename Type > // Data type of the sparse matrix
3852 template< typename Other > // Data type of the foreign expression
3853 inline bool CompressedMatrix<Type,true>::canAlias( const Other* alias ) const
3854 {
3855  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
3856 }
3858 //*************************************************************************************************
3859 
3860 
3861 //*************************************************************************************************
3872 template< typename Type > // Data type of the sparse matrix
3873 template< typename Other > // Data type of the foreign expression
3874 inline bool CompressedMatrix<Type,true>::isAliased( const Other* alias ) const
3875 {
3876  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
3877 }
3879 //*************************************************************************************************
3880 
3881 
3882 //*************************************************************************************************
3894 template< typename Type > // Data type of the sparse matrix
3895 template< typename MT // Type of the right-hand side dense matrix
3896  , bool SO > // Storage order of the right-hand side dense matrix
3897 inline void CompressedMatrix<Type,true>::assign( const DenseMatrix<MT,SO>& rhs )
3898 {
3899  size_t nonzeros( 0UL );
3900 
3901  for( size_t j=1UL; j<=n_; ++j )
3902  begin_[j] = end_[j] = end_[n_];
3903 
3904  for( size_t j=0UL; j<n_; ++j )
3905  {
3906  begin_[j] = end_[j] = begin_[0UL]+nonzeros;
3907 
3908  for( size_t i=0UL; i<m_; ++i )
3909  {
3910  if( nonzeros == capacity() ) {
3911  reserveElements( extendCapacity() );
3912  for( size_t k=j+1UL; k<=n_; ++k )
3913  begin_[k] = end_[k] = end_[n_];
3914  }
3915 
3916  end_[j]->value_ = (~rhs)(i,j);
3917 
3918  if( !isDefault( end_[j]->value_ ) ) {
3919  end_[j]->index_ = i;
3920  ++end_[j];
3921  ++nonzeros;
3922  }
3923  }
3924  }
3925 
3926  begin_[n_] = begin_[0UL]+nonzeros;
3927 }
3929 //*************************************************************************************************
3930 
3931 
3932 //*************************************************************************************************
3944 template< typename Type > // Data type of the sparse matrix
3945 template< typename MT > // Type of the right-hand side sparse matrix
3946 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,true>& rhs )
3947 {
3948  for( size_t j=0UL; j<(~rhs).columns(); ++j ) {
3949  begin_[j+1UL] = end_[j] = std::copy( (~rhs).begin(j), (~rhs).end(j), begin_[j] );
3950  }
3951 }
3953 //*************************************************************************************************
3954 
3955 
3956 //*************************************************************************************************
3968 template< typename Type > // Data type of the sparse matrix
3969 template< typename MT > // Type of the right-hand side sparse matrix
3970 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,false>& rhs )
3971 {
3972  typedef typename MT::ConstIterator RhsIterator;
3973 
3974  // Counting the number of elements per column
3975  std::vector<size_t> columnLengths( n_, 0UL );
3976  for( size_t i=0UL; i<m_; ++i ) {
3977  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3978  ++columnLengths[element->index()];
3979  }
3980 
3981  // Resizing the sparse matrix
3982  for( size_t j=0UL; j<n_; ++j ) {
3983  begin_[j+1UL] = end_[j+1UL] = begin_[j] + columnLengths[j];
3984  }
3985 
3986  // Appending the elements to the columns of the sparse matrix
3987  for( size_t i=0UL; i<m_; ++i ) {
3988  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3989  append( i, element->index(), element->value() );
3990  }
3991 }
3993 //*************************************************************************************************
3994 
3995 
3996 //*************************************************************************************************
4008 template< typename Type > // Data type of the sparse matrix
4009 template< typename MT // Type of the right-hand side dense matrix
4010  , bool SO > // Storage order of the right-hand side dense matrix
4011 inline void CompressedMatrix<Type,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
4012 {
4013  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4014  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4015 
4016  CompressedMatrix tmp( *this + (~rhs) );
4017  swap( tmp );
4018 }
4020 //*************************************************************************************************
4021 
4022 
4023 //*************************************************************************************************
4035 template< typename Type > // Data type of the sparse matrix
4036 template< typename MT // Type of the right-hand side sparse matrix
4037  , bool SO > // Storage order of the right-hand side sparse matrix
4038 inline void CompressedMatrix<Type,true>::addAssign( const SparseMatrix<MT,SO>& rhs )
4039 {
4040  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4041  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4042 
4043  CompressedMatrix tmp( *this + (~rhs) );
4044  swap( tmp );
4045 }
4047 //*************************************************************************************************
4048 
4049 
4050 //*************************************************************************************************
4062 template< typename Type > // Data type of the sparse matrix
4063 template< typename MT // Type of the right-hand side dense matrix
4064  , bool SO > // Storage order of the right-hand side dense matrix
4065 inline void CompressedMatrix<Type,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
4066 {
4067  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4068  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4069 
4070  CompressedMatrix tmp( *this - (~rhs) );
4071  swap( tmp );
4072 }
4074 //*************************************************************************************************
4075 
4076 
4077 //*************************************************************************************************
4089 template< typename Type > // Data type of the sparse matrix
4090 template< typename MT // Type of the right-hand side sparse matrix
4091  , bool SO > // Storage order of the right-hand side sparse matrix
4092 inline void CompressedMatrix<Type,true>::subAssign( const SparseMatrix<MT,SO>& rhs )
4093 {
4094  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4095  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4096 
4097  CompressedMatrix tmp( *this - (~rhs) );
4098  swap( tmp );
4099 }
4101 //*************************************************************************************************
4102 
4103 
4104 
4105 
4106 
4107 
4108 
4109 
4110 //=================================================================================================
4111 //
4112 // COMPRESSEDMATRIX OPERATORS
4113 //
4114 //=================================================================================================
4115 
4116 //*************************************************************************************************
4119 template< typename Type, bool SO >
4120 inline bool isnan( const CompressedMatrix<Type,SO>& m );
4121 
4122 template< typename Type, bool SO >
4123 inline void reset( CompressedMatrix<Type,SO>& m );
4124 
4125 template< typename Type, bool SO >
4126 inline void clear( CompressedMatrix<Type,SO>& m );
4127 
4128 template< typename Type, bool SO >
4129 inline bool isDefault( const CompressedMatrix<Type,SO>& m );
4130 
4131 template< typename Type, bool SO >
4132 inline const CompressedMatrix<Type,SO> inv( const CompressedMatrix<Type,SO>& m );
4133 
4134 template< typename Type, bool SO >
4135 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) /* throw() */;
4137 //*************************************************************************************************
4138 
4139 
4140 //*************************************************************************************************
4147 template< typename Type // Data type of the sparse matrix
4148  , bool SO > // Storage order
4149 inline bool isnan( const CompressedMatrix<Type,SO>& m )
4150 {
4151  typedef typename CompressedMatrix<Type,SO>::ConstIterator ConstIterator;
4152 
4153  for( size_t i=0UL; i<m.rows(); ++i ) {
4154  for( ConstIterator element=m.begin(i); element!=m.end(i); ++element )
4155  if( isnan( *element ) ) return true;
4156  }
4157  return false;
4158 }
4159 //*************************************************************************************************
4160 
4161 
4162 //*************************************************************************************************
4169 template< typename Type // Data type of the sparse matrix
4170  , bool SO > // Storage order
4172 {
4173  m.reset();
4174 }
4175 //*************************************************************************************************
4176 
4177 
4178 //*************************************************************************************************
4185 template< typename Type // Data type of the sparse matrix
4186  , bool SO > // Storage order
4188 {
4189  m.clear();
4190 }
4191 //*************************************************************************************************
4192 
4193 
4194 //*************************************************************************************************
4212 template< typename Type // Data type of the sparse matrix
4213  , bool SO > // Storage order
4214 inline bool isDefault( const CompressedMatrix<Type,SO>& m )
4215 {
4216  typedef typename CompressedMatrix<Type,SO>::ConstIterator ConstIterator;
4217 
4218  if( SO == rowMajor ) {
4219  for( size_t i=0UL; i<m.rows(); ++i ) {
4220  for( ConstIterator element=m.begin(i); element!=m.end(i); ++element )
4221  if( !isDefault( element->value() ) ) return false;
4222  }
4223  }
4224  else {
4225  for( size_t j=0UL; j<m.columns(); ++j ) {
4226  for( ConstIterator element=m.begin(j); element!=m.end(j); ++element )
4227  if( !isDefault( element->value() ) ) return false;
4228  }
4229  }
4230 
4231  return true;
4232 }
4233 //*************************************************************************************************
4234 
4235 
4236 //*************************************************************************************************
4245 template< typename Type // Data type of the sparse matrix
4246  , bool SO > // Storage order
4248 {
4249  UNUSED_PARAMETER( m );
4250  return CompressedMatrix<Type,SO>();
4251 }
4252 //*************************************************************************************************
4253 
4254 
4255 //*************************************************************************************************
4264 template< typename Type // Data type of the sparse matrix
4265  , bool SO > // Storage order
4266 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) /* throw() */
4267 {
4268  a.swap( b );
4269 }
4270 //*************************************************************************************************
4271 
4272 
4273 
4274 
4275 //=================================================================================================
4276 //
4277 // ISRESIZABLE SPECIALIZATIONS
4278 //
4279 //=================================================================================================
4280 
4281 //*************************************************************************************************
4283 template< typename T, bool SO >
4284 struct IsResizable< CompressedMatrix<T,SO> > : public TrueType
4285 {
4286  enum { value = 1 };
4287  typedef TrueType Type;
4288 };
4289 
4290 template< typename T, bool SO >
4291 struct IsResizable< const CompressedMatrix<T,SO> > : public TrueType
4292 {
4293  enum { value = 1 };
4294  typedef TrueType Type;
4295 };
4296 
4297 template< typename T, bool SO >
4298 struct IsResizable< volatile CompressedMatrix<T,SO> > : public TrueType
4299 {
4300  enum { value = 1 };
4301  typedef TrueType Type;
4302 };
4303 
4304 template< typename T, bool SO >
4305 struct IsResizable< const volatile CompressedMatrix<T,SO> > : public TrueType
4306 {
4307  enum { value = 1 };
4308  typedef TrueType Type;
4309 };
4311 //*************************************************************************************************
4312 
4313 
4314 
4315 
4316 //=================================================================================================
4317 //
4318 // ADDTRAIT SPECIALIZATIONS
4319 //
4320 //=================================================================================================
4321 
4322 //*************************************************************************************************
4324 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4325 struct AddTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4326 {
4327  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4328 };
4329 
4330 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4331 struct AddTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4332 {
4333  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
4334 };
4335 
4336 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4337 struct AddTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4338 {
4339  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4340 };
4341 
4342 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4343 struct AddTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4344 {
4345  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
4346 };
4347 
4348 template< typename T1, bool SO, typename T2 >
4349 struct AddTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4350 {
4351  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4352 };
4353 
4354 template< typename T1, bool SO1, typename T2, bool SO2 >
4355 struct AddTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4356 {
4357  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4358 };
4359 
4360 template< typename T1, bool SO, typename T2 >
4361 struct AddTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4362 {
4363  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4364 };
4365 
4366 template< typename T1, bool SO1, typename T2, bool SO2 >
4367 struct AddTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4368 {
4369  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4370 };
4371 
4372 template< typename T1, bool SO, typename T2 >
4373 struct AddTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4374 {
4375  typedef CompressedMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4376 };
4377 
4378 template< typename T1, bool SO1, typename T2, bool SO2 >
4379 struct AddTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4380 {
4381  typedef CompressedMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4382 };
4384 //*************************************************************************************************
4385 
4386 
4387 
4388 
4389 //=================================================================================================
4390 //
4391 // SUBTRAIT SPECIALIZATIONS
4392 //
4393 //=================================================================================================
4394 
4395 //*************************************************************************************************
4397 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4398 struct SubTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4399 {
4400  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4401 };
4402 
4403 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4404 struct SubTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4405 {
4406  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
4407 };
4408 
4409 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4410 struct SubTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4411 {
4412  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4413 };
4414 
4415 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4416 struct SubTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4417 {
4418  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
4419 };
4420 
4421 template< typename T1, bool SO, typename T2 >
4422 struct SubTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4423 {
4424  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4425 };
4426 
4427 template< typename T1, bool SO1, typename T2, bool SO2 >
4428 struct SubTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4429 {
4430  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , false > Type;
4431 };
4432 
4433 template< typename T1, bool SO, typename T2 >
4434 struct SubTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4435 {
4436  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4437 };
4438 
4439 template< typename T1, bool SO1, typename T2, bool SO2 >
4440 struct SubTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4441 {
4442  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , false > Type;
4443 };
4444 
4445 template< typename T1, bool SO, typename T2 >
4446 struct SubTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4447 {
4448  typedef CompressedMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4449 };
4450 
4451 template< typename T1, bool SO1, typename T2, bool SO2 >
4452 struct SubTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4453 {
4454  typedef CompressedMatrix< typename SubTrait<T1,T2>::Type , false > Type;
4455 };
4457 //*************************************************************************************************
4458 
4459 
4460 
4461 
4462 //=================================================================================================
4463 //
4464 // MULTTRAIT SPECIALIZATIONS
4465 //
4466 //=================================================================================================
4467 
4468 //*************************************************************************************************
4470 template< typename T1, bool SO, typename T2 >
4471 struct MultTrait< CompressedMatrix<T1,SO>, T2 >
4472 {
4473  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
4475 };
4476 
4477 template< typename T1, typename T2, bool SO >
4478 struct MultTrait< T1, CompressedMatrix<T2,SO> >
4479 {
4480  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
4482 };
4483 
4484 template< typename T1, bool SO, typename T2, size_t N >
4485 struct MultTrait< CompressedMatrix<T1,SO>, StaticVector<T2,N,false> >
4486 {
4487  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4488 };
4489 
4490 template< typename T1, size_t N, typename T2, bool SO >
4491 struct MultTrait< StaticVector<T1,N,true>, CompressedMatrix<T2,SO> >
4492 {
4493  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4494 };
4495 
4496 template< typename T1, bool SO, typename T2 >
4497 struct MultTrait< CompressedMatrix<T1,SO>, DynamicVector<T2,false> >
4498 {
4499  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4500 };
4501 
4502 template< typename T1, typename T2, bool SO >
4503 struct MultTrait< DynamicVector<T1,true>, CompressedMatrix<T2,SO> >
4504 {
4505  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4506 };
4507 
4508 template< typename T1, bool SO, typename T2 >
4509 struct MultTrait< CompressedMatrix<T1,SO>, CompressedVector<T2,false> >
4510 {
4511  typedef CompressedVector< typename MultTrait<T1,T2>::Type, false > Type;
4512 };
4513 
4514 template< typename T1, typename T2, bool SO >
4515 struct MultTrait< CompressedVector<T1,true>, CompressedMatrix<T2,SO> >
4516 {
4517  typedef CompressedVector< typename MultTrait<T1,T2>::Type, true > Type;
4518 };
4519 
4520 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4521 struct MultTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4522 {
4523  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4524 };
4525 
4526 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4527 struct MultTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4528 {
4529  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4530 };
4531 
4532 template< typename T1, bool SO1, typename T2, bool SO2 >
4533 struct MultTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4534 {
4535  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4536 };
4537 
4538 template< typename T1, bool SO1, typename T2, bool SO2 >
4539 struct MultTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4540 {
4541  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4542 };
4543 
4544 template< typename T1, bool SO1, typename T2, bool SO2 >
4545 struct MultTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4546 {
4547  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4548 };
4550 //*************************************************************************************************
4551 
4552 
4553 
4554 
4555 //=================================================================================================
4556 //
4557 // DIVTRAIT SPECIALIZATIONS
4558 //
4559 //=================================================================================================
4560 
4561 //*************************************************************************************************
4563 template< typename T1, bool SO, typename T2 >
4564 struct DivTrait< CompressedMatrix<T1,SO>, T2 >
4565 {
4566  typedef CompressedMatrix< typename DivTrait<T1,T2>::Type, SO > Type;
4568 };
4570 //*************************************************************************************************
4571 
4572 
4573 
4574 
4575 //=================================================================================================
4576 //
4577 // MATHTRAIT SPECIALIZATIONS
4578 //
4579 //=================================================================================================
4580 
4581 //*************************************************************************************************
4583 template< typename T1, bool SO, typename T2 >
4584 struct MathTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4585 {
4586  typedef CompressedMatrix< typename MathTrait<T1,T2>::HighType, SO > HighType;
4587  typedef CompressedMatrix< typename MathTrait<T1,T2>::LowType , SO > LowType;
4588 };
4590 //*************************************************************************************************
4591 
4592 
4593 
4594 
4595 //=================================================================================================
4596 //
4597 // ROWTRAIT SPECIALIZATIONS
4598 //
4599 //=================================================================================================
4600 
4601 //*************************************************************************************************
4603 template< typename T1, bool SO >
4604 struct RowTrait< CompressedMatrix<T1,SO> >
4605 {
4606  typedef CompressedVector<T1,true> Type;
4607 };
4609 //*************************************************************************************************
4610 
4611 
4612 
4613 
4614 //=================================================================================================
4615 //
4616 // COLUMNTRAIT SPECIALIZATIONS
4617 //
4618 //=================================================================================================
4619 
4620 //*************************************************************************************************
4622 template< typename T1, bool SO >
4623 struct ColumnTrait< CompressedMatrix<T1,SO> >
4624 {
4625  typedef CompressedVector<T1,false> Type;
4626 };
4628 //*************************************************************************************************
4629 
4630 } // namespace blaze
4631 
4632 #endif