All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CompressedMatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_SPARSE_COMPRESSEDMATRIX_H_
36 #define _BLAZE_MATH_SPARSE_COMPRESSEDMATRIX_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <functional>
45 #include <stdexcept>
46 #include <vector>
48 #include <blaze/math/Forward.h>
49 #include <blaze/math/Functions.h>
50 #include <blaze/math/shims/Equal.h>
64 #include <blaze/system/Precision.h>
66 #include <blaze/util/Assert.h>
73 #include <blaze/util/EnableIf.h>
74 #include <blaze/util/mpl/If.h>
75 #include <blaze/util/Null.h>
76 #include <blaze/util/Types.h>
79 
80 
81 namespace blaze {
82 
83 //=================================================================================================
84 //
85 // CLASS DEFINITION
86 //
87 //=================================================================================================
88 
89 //*************************************************************************************************
194 template< typename Type // Data type of the sparse matrix
195  , bool SO = defaultStorageOrder > // Storage order
196 class CompressedMatrix : public SparseMatrix< CompressedMatrix<Type,SO>, SO >
197 {
198  private:
199  //**Type definitions****************************************************************************
201  //**********************************************************************************************
202 
203  //**Private class Element***********************************************************************
207  struct Element : public ElementBase
208  {
209  // This operator is required due to a bug in all versions of the the MSVC compiler.
210  // A simple 'using ElementBase::operator=;' statement results in ambiguity problems.
211  template< typename Other >
212  inline Element& operator=( const Other& rhs )
213  {
214  ElementBase::operator=( rhs );
215  return *this;
216  }
217 
218  friend class CompressedMatrix;
219  };
221  //**********************************************************************************************
222 
223  //**Private class FindIndex*********************************************************************
227  struct FindIndex : public std::binary_function<Element,size_t,bool>
228  {
229  inline bool operator()( const Element& element, size_t index ) const {
230  return element.index() < index;
231  }
232  inline bool operator()( size_t index, const Element& element ) const {
233  return index < element.index();
234  }
235  inline bool operator()( const Element& element1, const Element& element2 ) const {
236  return element1.index() < element2.index();
237  }
238  };
240  //**********************************************************************************************
241 
242  public:
243  //**Type definitions****************************************************************************
245  typedef This ResultType;
248  typedef Type ElementType;
249  typedef const Type& ReturnType;
250  typedef const This& CompositeType;
252  typedef const Type& ConstReference;
253  typedef Element* Iterator;
254  typedef const Element* ConstIterator;
255  //**********************************************************************************************
256 
257  //**Constructors********************************************************************************
260  explicit inline CompressedMatrix();
261  explicit inline CompressedMatrix( size_t m, size_t n );
262  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
263  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
264  inline CompressedMatrix( const CompressedMatrix& sm );
265  template< typename MT, bool SO2 > inline CompressedMatrix( const DenseMatrix<MT,SO2>& dm );
266  template< typename MT, bool SO2 > inline CompressedMatrix( const SparseMatrix<MT,SO2>& sm );
268  //**********************************************************************************************
269 
270  //**Destructor**********************************************************************************
273  inline ~CompressedMatrix();
275  //**********************************************************************************************
276 
277  //**Data access functions***********************************************************************
280  inline Reference operator()( size_t i, size_t j );
281  inline ConstReference operator()( size_t i, size_t j ) const;
282  inline Iterator begin ( size_t i );
283  inline ConstIterator begin ( size_t i ) const;
284  inline ConstIterator cbegin( size_t i ) const;
285  inline Iterator end ( size_t i );
286  inline ConstIterator end ( size_t i ) const;
287  inline ConstIterator cend ( size_t i ) const;
289  //**********************************************************************************************
290 
291  //**Assignment operators************************************************************************
294  inline CompressedMatrix& operator= ( const CompressedMatrix& rhs );
295  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO2>& rhs );
296  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO2>& rhs );
297  template< typename MT, bool SO2 > inline CompressedMatrix& operator+=( const Matrix<MT,SO2>& rhs );
298  template< typename MT, bool SO2 > inline CompressedMatrix& operator-=( const Matrix<MT,SO2>& rhs );
299  template< typename MT, bool SO2 > inline CompressedMatrix& operator*=( const Matrix<MT,SO2>& rhs );
300 
301  template< typename Other >
302  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
303  operator*=( Other rhs );
304 
305  template< typename Other >
306  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
307  operator/=( Other rhs );
309  //**********************************************************************************************
310 
311  //**Utility functions***************************************************************************
314  inline size_t rows() const;
315  inline size_t columns() const;
316  inline size_t capacity() const;
317  inline size_t capacity( size_t i ) const;
318  inline size_t nonZeros() const;
319  inline size_t nonZeros( size_t i ) const;
320  inline void reset();
321  inline void reset( size_t i );
322  inline void clear();
323  Iterator insert ( size_t i, size_t j, const Type& value );
324  inline void erase ( size_t i, size_t j );
325  inline Iterator erase ( size_t i, Iterator pos );
326  inline Iterator erase ( size_t i, Iterator first, Iterator last );
327  void resize ( size_t m, size_t n, bool preserve=true );
328  inline void reserve( size_t nonzeros );
329  void reserve( size_t i, size_t nonzeros );
330  inline void trim ();
331  inline void trim ( size_t i );
332  inline CompressedMatrix& transpose();
333  template< typename Other > inline CompressedMatrix& scale( Other scalar );
334  template< typename Other > inline CompressedMatrix& scaleDiagonal( Other scalar );
335  inline void swap( CompressedMatrix& sm ) /* throw() */;
337  //**********************************************************************************************
338 
339  //**Lookup functions****************************************************************************
342  inline Iterator find ( size_t i, size_t j );
343  inline ConstIterator find ( size_t i, size_t j ) const;
344  inline Iterator lowerBound( size_t i, size_t j );
345  inline ConstIterator lowerBound( size_t i, size_t j ) const;
346  inline Iterator upperBound( size_t i, size_t j );
347  inline ConstIterator upperBound( size_t i, size_t j ) const;
349  //**********************************************************************************************
350 
351  //**Low-level utility functions*****************************************************************
354  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
355  inline void finalize( size_t i );
357  //**********************************************************************************************
358 
359  //**Expression template evaluation functions****************************************************
362  template< typename Other > inline bool canAlias ( const Other* alias ) const;
363  template< typename Other > inline bool isAliased( const Other* alias ) const;
364  template< typename MT, bool SO2 > inline void assign ( const DenseMatrix<MT,SO2>& rhs );
365  template< typename MT > inline void assign ( const SparseMatrix<MT,SO>& rhs );
366  template< typename MT > inline void assign ( const SparseMatrix<MT,!SO>& rhs );
367  template< typename MT, bool SO2 > inline void addAssign( const DenseMatrix<MT,SO2>& rhs );
368  template< typename MT, bool SO2 > inline void addAssign( const SparseMatrix<MT,SO2>& rhs );
369  template< typename MT, bool SO2 > inline void subAssign( const DenseMatrix<MT,SO2>& rhs );
370  template< typename MT, bool SO2 > inline void subAssign( const SparseMatrix<MT,SO2>& rhs );
372  //**********************************************************************************************
373 
374  private:
375  //**Utility functions***************************************************************************
378  inline size_t extendCapacity() const;
379  void reserveElements( size_t nonzeros );
381  //**********************************************************************************************
382 
383  //**Member variables****************************************************************************
386  size_t m_;
387  size_t n_;
388  size_t capacity_;
391 
392  static const Type zero_;
393 
394  //**********************************************************************************************
395 
396  //**Compile time checks*************************************************************************
404  //**********************************************************************************************
405 };
406 //*************************************************************************************************
407 
408 
409 
410 
411 //=================================================================================================
412 //
413 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
414 //
415 //=================================================================================================
416 
417 template< typename Type, bool SO >
418 const Type CompressedMatrix<Type,SO>::zero_ = Type();
419 
420 
421 
422 
423 //=================================================================================================
424 //
425 // CONSTRUCTORS
426 //
427 //=================================================================================================
428 
429 //*************************************************************************************************
432 template< typename Type // Data type of the sparse matrix
433  , bool SO > // Storage order
435  : m_ ( 0UL ) // The current number of rows of the sparse matrix
436  , n_ ( 0UL ) // The current number of columns of the sparse matrix
437  , capacity_( 0UL ) // The current capacity of the pointer array
438  , begin_( new Iterator[2] ) // Pointers to the first non-zero element of each row
439  , end_ ( begin_+1 ) // Pointers one past the last non-zero element of each row
440 {
441  begin_[0] = end_[0] = NULL;
442 }
443 //*************************************************************************************************
444 
445 
446 //*************************************************************************************************
454 template< typename Type // Data type of the sparse matrix
455  , bool SO > // Storage order
457  : m_ ( m ) // The current number of rows of the sparse matrix
458  , n_ ( n ) // The current number of columns of the sparse matrix
459  , capacity_( m ) // The current capacity of the pointer array
460  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
461  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
462 {
463  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
464  begin_[i] = NULL;
465 }
466 //*************************************************************************************************
467 
468 
469 //*************************************************************************************************
478 template< typename Type // Data type of the sparse matrix
479  , bool SO > // Storage order
480 inline CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
481  : m_ ( m ) // The current number of rows of the sparse matrix
482  , n_ ( n ) // The current number of columns of the sparse matrix
483  , capacity_( m ) // The current capacity of the pointer array
484  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
485  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
486 {
487  begin_[0UL] = new Element[nonzeros];
488  for( size_t i=1UL; i<(2UL*m_+1UL); ++i )
489  begin_[i] = begin_[0UL];
490  end_[m_] = begin_[0UL]+nonzeros;
491 }
492 //*************************************************************************************************
493 
494 
495 //*************************************************************************************************
504 template< typename Type // Data type of the sparse matrix
505  , bool SO > // Storage order
506 CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
507  : m_ ( m ) // The current number of rows of the sparse matrix
508  , n_ ( n ) // The current number of columns of the sparse matrix
509  , capacity_( m ) // The current capacity of the pointer array
510  , begin_( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
511  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
512 {
513  BLAZE_USER_ASSERT( nonzeros.size() == m, "Size of capacity vector and number of rows don't match" );
514 
515  size_t newCapacity( 0UL );
516  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
517  newCapacity += *it;
518 
519  begin_[0UL] = end_[0UL] = new Element[newCapacity];
520  for( size_t i=0UL; i<m_; ++i ) {
521  begin_[i+1UL] = end_[i+1UL] = begin_[i] + nonzeros[i];
522  }
523 }
524 //*************************************************************************************************
525 
526 
527 //*************************************************************************************************
532 template< typename Type // Data type of the sparse matrix
533  , bool SO > // Storage order
535  : m_ ( sm.m_ ) // The current number of rows of the sparse matrix
536  , n_ ( sm.n_ ) // The current number of columns of the sparse matrix
537  , capacity_( sm.m_ ) // The current capacity of the pointer array
538  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
539  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
540 {
541  const size_t nonzeros( sm.nonZeros() );
542 
543  begin_[0UL] = new Element[nonzeros];
544  for( size_t i=0UL; i<m_; ++i )
545  begin_[i+1UL] = end_[i] = std::copy( sm.begin(i), sm.end(i), begin_[i] );
546  end_[m_] = begin_[0UL]+nonzeros;
547 }
548 //*************************************************************************************************
549 
550 
551 //*************************************************************************************************
556 template< typename Type // Data type of the sparse matrix
557  , bool SO > // Storage order
558 template< typename MT // Type of the foreign dense matrix
559  , bool SO2 > // Storage order of the foreign dense matrix
561  : m_ ( (~dm).rows() ) // The current number of rows of the sparse matrix
562  , n_ ( (~dm).columns() ) // The current number of columns of the sparse matrix
563  , capacity_( m_ ) // The current capacity of the pointer array
564  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
565  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
566 {
567  using blaze::assign;
568 
569  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
570  begin_[i] = NULL;
571 
572  assign( *this, ~dm );
573 }
574 //*************************************************************************************************
575 
576 
577 //*************************************************************************************************
582 template< typename Type // Data type of the sparse matrix
583  , bool SO > // Storage order
584 template< typename MT // Type of the foreign sparse matrix
585  , bool SO2 > // Storage order of the foreign sparse matrix
587  : m_ ( (~sm).rows() ) // The current number of rows of the sparse matrix
588  , n_ ( (~sm).columns() ) // The current number of columns of the sparse matrix
589  , capacity_( m_ ) // The current capacity of the pointer array
590  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
591  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
592 {
593  using blaze::assign;
594 
595  const size_t nonzeros( (~sm).nonZeros() );
596 
597  begin_[0UL] = new Element[nonzeros];
598  for( size_t i=0UL; i<m_; ++i )
599  begin_[i+1UL] = end_[i] = begin_[0UL];
600  end_[m_] = begin_[0UL]+nonzeros;
601 
602  assign( *this, ~sm );
603 }
604 //*************************************************************************************************
605 
606 
607 
608 
609 //=================================================================================================
610 //
611 // DESTRUCTOR
612 //
613 //=================================================================================================
614 
615 //*************************************************************************************************
618 template< typename Type // Data type of the sparse matrix
619  , bool SO > // Storage order
621 {
622  delete [] begin_[0UL];
623  delete [] begin_;
624 }
625 //*************************************************************************************************
626 
627 
628 
629 
630 //=================================================================================================
631 //
632 // DATA ACCESS FUNCTIONS
633 //
634 //=================================================================================================
635 
636 //*************************************************************************************************
643 template< typename Type // Data type of the sparse matrix
644  , bool SO > // Storage order
647 {
648  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
649  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
650 
651  return Reference( *this, i, j );
652 }
653 //*************************************************************************************************
654 
655 
656 //*************************************************************************************************
663 template< typename Type // Data type of the sparse matrix
664  , bool SO > // Storage order
666  CompressedMatrix<Type,SO>::operator()( size_t i, size_t j ) const
667 {
668  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
669  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
670 
671  const ConstIterator pos( lowerBound( i, j ) );
672 
673  if( pos == end_[i] || pos->index_ != j )
674  return zero_;
675  else
676  return pos->value_;
677 }
678 //*************************************************************************************************
679 
680 
681 //*************************************************************************************************
692 template< typename Type // Data type of the sparse matrix
693  , bool SO > // Storage order
696 {
697  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
698  return begin_[i];
699 }
700 //*************************************************************************************************
701 
702 
703 //*************************************************************************************************
714 template< typename Type // Data type of the sparse matrix
715  , bool SO > // Storage order
718 {
719  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
720  return begin_[i];
721 }
722 //*************************************************************************************************
723 
724 
725 //*************************************************************************************************
736 template< typename Type // Data type of the sparse matrix
737  , bool SO > // Storage order
740 {
741  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
742  return begin_[i];
743 }
744 //*************************************************************************************************
745 
746 
747 //*************************************************************************************************
758 template< typename Type // Data type of the sparse matrix
759  , bool SO > // Storage order
762 {
763  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
764  return end_[i];
765 }
766 //*************************************************************************************************
767 
768 
769 //*************************************************************************************************
780 template< typename Type // Data type of the sparse matrix
781  , bool SO > // Storage order
784 {
785  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
786  return end_[i];
787 }
788 //*************************************************************************************************
789 
790 
791 //*************************************************************************************************
802 template< typename Type // Data type of the sparse matrix
803  , bool SO > // Storage order
806 {
807  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
808  return end_[i];
809 }
810 //*************************************************************************************************
811 
812 
813 
814 
815 //=================================================================================================
816 //
817 // ASSIGNMENT OPERATORS
818 //
819 //=================================================================================================
820 
821 //*************************************************************************************************
830 template< typename Type // Data type of the sparse matrix
831  , bool SO > // Storage order
834 {
835  if( &rhs == this ) return *this;
836 
837  const size_t nonzeros( rhs.nonZeros() );
838 
839  if( rhs.m_ > capacity_ || nonzeros > capacity() )
840  {
841  Iterator* newBegin( new Iterator[2UL*rhs.m_+2UL] );
842  Iterator* newEnd ( newBegin+(rhs.m_+1UL) );
843 
844  newBegin[0UL] = new Element[nonzeros];
845  for( size_t i=0UL; i<rhs.m_; ++i ) {
846  newBegin[i+1UL] = newEnd[i] = std::copy( rhs.begin_[i], rhs.end_[i], newBegin[i] );
847  }
848  newEnd[rhs.m_] = newBegin[0UL]+nonzeros;
849 
850  std::swap( begin_, newBegin );
851  end_ = newEnd;
852  delete [] newBegin[0UL];
853  delete [] newBegin;
854  capacity_ = rhs.m_;
855  }
856  else {
857  for( size_t i=0UL; i<rhs.m_; ++i ) {
858  begin_[i+1UL] = end_[i] = std::copy( rhs.begin_[i], rhs.end_[i], begin_[i] );
859  }
860  }
861 
862  m_ = rhs.m_;
863  n_ = rhs.n_;
864 
865  return *this;
866 }
867 //*************************************************************************************************
868 
869 
870 //*************************************************************************************************
879 template< typename Type // Data type of the sparse matrix
880  , bool SO > // Storage order
881 template< typename MT // Type of the right-hand side dense matrix
882  , bool SO2 > // Storage order of the right-hand side dense matrix
885 {
886  using blaze::assign;
887 
888  if( (~rhs).canAlias( this ) ) {
889  CompressedMatrix tmp( rhs );
890  swap( tmp );
891  }
892  else {
893  resize( (~rhs).rows(), (~rhs).columns(), false );
894  assign( *this, ~rhs );
895  }
896 
897  return *this;
898 }
899 //*************************************************************************************************
900 
901 
902 //*************************************************************************************************
911 template< typename Type // Data type of the sparse matrix
912  , bool SO > // Storage order
913 template< typename MT // Type of the right-hand side sparse matrix
914  , bool SO2 > // Storage order of the right-hand side sparse matrix
917 {
918  using blaze::assign;
919 
920  if( (~rhs).canAlias( this ) ||
921  (~rhs).rows() > capacity_ ||
922  (~rhs).nonZeros() > capacity() ) {
923  CompressedMatrix tmp( rhs );
924  swap( tmp );
925  }
926  else {
927  resize( (~rhs).rows(), (~rhs).columns(), false );
928  reset();
929  assign( *this, ~rhs );
930  }
931 
932  return *this;
933 }
934 //*************************************************************************************************
935 
936 
937 //*************************************************************************************************
947 template< typename Type // Data type of the sparse matrix
948  , bool SO > // Storage order
949 template< typename MT // Type of the right-hand side matrix
950  , bool SO2 > // Storage order of the right-hand side matrix
953 {
954  using blaze::addAssign;
955 
956  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
957  throw std::invalid_argument( "Matrix sizes do not match" );
958 
959  addAssign( *this, ~rhs );
960  return *this;
961 }
962 //*************************************************************************************************
963 
964 
965 //*************************************************************************************************
975 template< typename Type // Data type of the sparse matrix
976  , bool SO > // Storage order
977 template< typename MT // Type of the right-hand side matrix
978  , bool SO2 > // Storage order of the right-hand side matrix
980 {
981  using blaze::subAssign;
982 
983  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
984  throw std::invalid_argument( "Matrix sizes do not match" );
985 
986  subAssign( *this, ~rhs );
987  return *this;
988 }
989 //*************************************************************************************************
990 
991 
992 //*************************************************************************************************
1002 template< typename Type // Data type of the sparse matrix
1003  , bool SO > // Storage order
1004 template< typename MT // Type of the right-hand side matrix
1005  , bool SO2 > // Storage order of the right-hand side matrix
1008 {
1009  if( (~rhs).rows() != n_ )
1010  throw std::invalid_argument( "Matrix sizes do not match" );
1011 
1012  CompressedMatrix tmp( *this * (~rhs) );
1013  swap( tmp );
1014 
1015  return *this;
1016 }
1017 //*************************************************************************************************
1018 
1019 
1020 //*************************************************************************************************
1027 template< typename Type // Data type of the sparse matrix
1028  , bool SO > // Storage order
1029 template< typename Other > // Data type of the right-hand side scalar
1030 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,SO> >::Type&
1032 {
1033  for( size_t i=0UL; i<m_; ++i ) {
1034  const Iterator last( end(i) );
1035  for( Iterator element=begin(i); element!=last; ++element )
1036  element->value_ *= rhs;
1037  }
1038 
1039  return *this;
1040 }
1041 //*************************************************************************************************
1042 
1043 
1044 //*************************************************************************************************
1051 template< typename Type // Data type of the sparse matrix
1052  , bool SO > // Storage order
1053 template< typename Other > // Data type of the right-hand side scalar
1054 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,SO> >::Type&
1056 {
1057  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1058 
1059  typedef typename DivTrait<Type,Other>::Type DT;
1060  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
1061 
1062  // Depending on the two involved data types, an integer division is applied or a
1063  // floating point division is selected.
1065  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1066  for( size_t i=0UL; i<m_; ++i ) {
1067  const Iterator last( end(i) );
1068  for( Iterator element=begin(i); element!=last; ++element )
1069  element->value_ *= tmp;
1070  }
1071  }
1072  else {
1073  for( size_t i=0UL; i<m_; ++i ) {
1074  const Iterator last( end(i) );
1075  for( Iterator element=begin(i); element!=last; ++element )
1076  element->value_ /= rhs;
1077  }
1078  }
1079 
1080  return *this;
1081 }
1082 //*************************************************************************************************
1083 
1084 
1085 
1086 
1087 //=================================================================================================
1088 //
1089 // UTILITY FUNCTIONS
1090 //
1091 //=================================================================================================
1092 
1093 //*************************************************************************************************
1098 template< typename Type // Data type of the sparse matrix
1099  , bool SO > // Storage order
1100 inline size_t CompressedMatrix<Type,SO>::rows() const
1101 {
1102  return m_;
1103 }
1104 //*************************************************************************************************
1105 
1106 
1107 //*************************************************************************************************
1112 template< typename Type // Data type of the sparse matrix
1113  , bool SO > // Storage order
1115 {
1116  return n_;
1117 }
1118 //*************************************************************************************************
1119 
1120 
1121 //*************************************************************************************************
1126 template< typename Type // Data type of the sparse matrix
1127  , bool SO > // Storage order
1129 {
1130  return end_[m_] - begin_[0UL];
1131 }
1132 //*************************************************************************************************
1133 
1134 
1135 //*************************************************************************************************
1146 template< typename Type // Data type of the sparse matrix
1147  , bool SO > // Storage order
1148 inline size_t CompressedMatrix<Type,SO>::capacity( size_t i ) const
1149 {
1150  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1151  return begin_[i+1UL] - begin_[i];
1152 }
1153 //*************************************************************************************************
1154 
1155 
1156 //*************************************************************************************************
1161 template< typename Type // Data type of the sparse matrix
1162  , bool SO > // Storage order
1164 {
1165  size_t nonzeros( 0UL );
1166 
1167  for( size_t i=0UL; i<m_; ++i )
1168  nonzeros += nonZeros( i );
1169 
1170  return nonzeros;
1171 }
1172 //*************************************************************************************************
1173 
1174 
1175 //*************************************************************************************************
1186 template< typename Type // Data type of the sparse matrix
1187  , bool SO > // Storage order
1188 inline size_t CompressedMatrix<Type,SO>::nonZeros( size_t i ) const
1189 {
1190  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1191  return end_[i] - begin_[i];
1192 }
1193 //*************************************************************************************************
1194 
1195 
1196 //*************************************************************************************************
1201 template< typename Type // Data type of the sparse matrix
1202  , bool SO > // Storage order
1204 {
1205  for( size_t i=0UL; i<m_; ++i )
1206  end_[i] = begin_[i];
1207 }
1208 //*************************************************************************************************
1209 
1210 
1211 //*************************************************************************************************
1222 template< typename Type // Data type of the sparse matrix
1223  , bool SO > // Storage order
1224 inline void CompressedMatrix<Type,SO>::reset( size_t i )
1225 {
1226  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1227  end_[i] = begin_[i];
1228 }
1229 //*************************************************************************************************
1230 
1231 
1232 //*************************************************************************************************
1239 template< typename Type // Data type of the sparse matrix
1240  , bool SO > // Storage order
1242 {
1243  end_[0UL] = end_[m_];
1244  m_ = 0UL;
1245  n_ = 0UL;
1246 }
1247 //*************************************************************************************************
1248 
1249 
1250 //*************************************************************************************************
1263 template< typename Type // Data type of the sparse matrix
1264  , bool SO > // Storage order
1266  CompressedMatrix<Type,SO>::insert( size_t i, size_t j, const Type& value )
1267 {
1268  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1269  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1270 
1271  const Iterator pos( lowerBound( i, j ) );
1272 
1273  if( pos != end_[i] && pos->index_ == j )
1274  throw std::invalid_argument( "Bad access index" );
1275 
1276  if( begin_[i+1UL] - end_[i] != 0 ) {
1277  std::copy_backward( pos, end_[i], end_[i]+1 );
1278  pos->value_ = value;
1279  pos->index_ = j;
1280  ++end_[i];
1281 
1282  return pos;
1283  }
1284  else if( end_[m_] - begin_[m_] != 0 ) {
1285  std::copy_backward( pos, end_[m_-1UL], end_[m_-1UL]+1 );
1286 
1287  pos->value_ = value;
1288  pos->index_ = j;
1289 
1290  for( size_t k=i+1UL; k<m_+1UL; ++k ) {
1291  ++begin_[k];
1292  ++end_[k-1UL];
1293  }
1294 
1295  return pos;
1296  }
1297  else {
1298  size_t newCapacity( extendCapacity() );
1299 
1300  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1301  Iterator* newEnd = newBegin+capacity_+1UL;
1302 
1303  newBegin[0UL] = new Element[newCapacity];
1304 
1305  for( size_t k=0UL; k<i; ++k ) {
1306  const size_t nonzeros( end_[k] - begin_[k] );
1307  const size_t total( begin_[k+1UL] - begin_[k] );
1308  newEnd [k] = newBegin[k] + nonzeros;
1309  newBegin[k+1UL] = newBegin[k] + total;
1310  }
1311  newEnd [i] = newBegin[i] + ( end_[i] - begin_[i] ) + 1;
1312  newBegin[i+1UL] = newBegin[i] + ( begin_[i+1] - begin_[i] ) + 1;
1313  for( size_t k=i+1UL; k<m_; ++k ) {
1314  const size_t nonzeros( end_[k] - begin_[k] );
1315  const size_t total( begin_[k+1UL] - begin_[k] );
1316  newEnd [k] = newBegin[k] + nonzeros;
1317  newBegin[k+1UL] = newBegin[k] + total;
1318  }
1319 
1320  newEnd[m_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
1321 
1322  Iterator tmp = std::copy( begin_[0UL], pos, newBegin[0UL] );
1323  tmp->value_ = value;
1324  tmp->index_ = j;
1325  std::copy( pos, end_[m_-1UL], tmp+1UL );
1326 
1327  std::swap( newBegin, begin_ );
1328  end_ = newEnd;
1329  delete [] newBegin[0UL];
1330  delete [] newBegin;
1331 
1332  return tmp;
1333  }
1334 }
1335 //*************************************************************************************************
1336 
1337 
1338 //*************************************************************************************************
1347 template< typename Type // Data type of the sparse matrix
1348  , bool SO > // Storage order
1349 inline void CompressedMatrix<Type,SO>::erase( size_t i, size_t j )
1350 {
1351  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1352  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1353 
1354  const Iterator pos( find( i, j ) );
1355  if( pos != end_[i] )
1356  end_[i] = std::copy( pos+1, end_[i], pos );
1357 }
1358 //*************************************************************************************************
1359 
1360 
1361 //*************************************************************************************************
1372 template< typename Type // Data type of the sparse matrix
1373  , bool SO > // Storage order
1376 {
1377  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1378  BLAZE_USER_ASSERT( pos >= begin_[i] && pos <= end_[i], "Invalid compressed matrix iterator" );
1379 
1380  if( pos != end_[i] )
1381  end_[i] = std::copy( pos+1, end_[i], pos );
1382 
1383  return pos;
1384 }
1385 //*************************************************************************************************
1386 
1387 
1388 //*************************************************************************************************
1400 template< typename Type // Data type of the sparse matrix
1401  , bool SO > // Storage order
1404 {
1405  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1406  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
1407  BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i], "Invalid compressed matrix iterator" );
1408  BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i], "Invalid compressed matrix iterator" );
1409 
1410  if( first != last )
1411  end_[i] = std::copy( last, end_[i], first );
1412 
1413  return first;
1414 }
1415 //*************************************************************************************************
1416 
1417 
1418 //*************************************************************************************************
1432 template< typename Type // Data type of the sparse matrix
1433  , bool SO > // Storage order
1434 void CompressedMatrix<Type,SO>::resize( size_t m, size_t n, bool preserve )
1435 {
1436  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1437  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1438 
1439  if( m == m_ && n == n_ ) return;
1440 
1441  if( m > capacity_ )
1442  {
1443  Iterator* newBegin( new Iterator[2UL*m+2UL] );
1444  Iterator* newEnd ( newBegin+m+1UL );
1445 
1446  newBegin[0UL] = begin_[0UL];
1447 
1448  if( preserve ) {
1449  for( size_t i=0UL; i<m_; ++i ) {
1450  newEnd [i] = end_ [i];
1451  newBegin[i+1UL] = begin_[i+1UL];
1452  }
1453  for( size_t i=m_; i<m; ++i ) {
1454  newBegin[i+1UL] = newEnd[i] = begin_[m_];
1455  }
1456  }
1457  else {
1458  for( size_t i=0UL; i<m; ++i ) {
1459  newBegin[i+1UL] = newEnd[i] = begin_[0UL];
1460  }
1461  }
1462 
1463  newEnd[m] = end_[m_];
1464 
1465  std::swap( newBegin, begin_ );
1466  delete [] newBegin;
1467 
1468  end_ = newEnd;
1469  capacity_ = m;
1470  }
1471  else if( m > m_ )
1472  {
1473  end_[m] = end_[m_];
1474 
1475  if( !preserve ) {
1476  for( size_t i=0UL; i<m_; ++i )
1477  end_[i] = begin_[i];
1478  }
1479 
1480  for( size_t i=m_; i<m; ++i )
1481  begin_[i+1UL] = end_[i] = begin_[m_];
1482  }
1483  else
1484  {
1485  if( preserve ) {
1486  for( size_t i=0UL; i<m; ++i )
1487  end_[i] = lowerBound( i, n );
1488  }
1489  else {
1490  for( size_t i=0UL; i<m; ++i )
1491  end_[i] = begin_[i];
1492  }
1493 
1494  end_[m] = end_[m_];
1495  }
1496 
1497  m_ = m;
1498  n_ = n;
1499 }
1500 //*************************************************************************************************
1501 
1502 
1503 //*************************************************************************************************
1513 template< typename Type // Data type of the sparse matrix
1514  , bool SO > // Storage order
1515 inline void CompressedMatrix<Type,SO>::reserve( size_t nonzeros )
1516 {
1517  if( nonzeros > capacity() )
1518  reserveElements( nonzeros );
1519 }
1520 //*************************************************************************************************
1521 
1522 
1523 //*************************************************************************************************
1537 template< typename Type // Data type of the sparse matrix
1538  , bool SO > // Storage order
1539 void CompressedMatrix<Type,SO>::reserve( size_t i, size_t nonzeros )
1540 {
1541  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1542 
1543  const size_t current( capacity(i) );
1544 
1545  if( current >= nonzeros ) return;
1546 
1547  const ptrdiff_t additional( nonzeros - current );
1548 
1549  if( end_[m_] - begin_[m_] < additional )
1550  {
1551  const size_t newCapacity( begin_[m_] - begin_[0UL] + additional );
1552  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
1553 
1554  Iterator* newBegin( new Iterator[2UL*m_+2UL] );
1555  Iterator* newEnd ( newBegin+m_+1UL );
1556 
1557  newBegin[0UL] = new Element[newCapacity];
1558  newEnd [m_ ] = newBegin[0UL]+newCapacity;
1559 
1560  for( size_t k=0UL; k<i; ++k ) {
1561  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
1562  newBegin[k+1UL] = newBegin[k] + capacity(k);
1563  }
1564  newEnd [i ] = std::copy( begin_[i], end_[i], newBegin[i] );
1565  newBegin[i+1UL] = newBegin[i] + nonzeros;
1566  for( size_t k=i+1UL; k<m_; ++k ) {
1567  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
1568  newBegin[k+1UL] = newBegin[k] + capacity(k);
1569  }
1570 
1571  BLAZE_INTERNAL_ASSERT( newBegin[m_] == newEnd[m_], "Invalid pointer calculations" );
1572 
1573  std::swap( newBegin, begin_ );
1574  delete [] newBegin[0UL];
1575  delete [] newBegin;
1576  end_ = newEnd;
1577  }
1578  else
1579  {
1580  begin_[m_] += additional;
1581  for( size_t j=m_-1UL; j>i; --j ) {
1582  begin_[j] = std::copy_backward( begin_[j], end_[j], end_[j]+additional );
1583  end_ [j] += additional;
1584  }
1585  }
1586 }
1587 //*************************************************************************************************
1588 
1589 
1590 //*************************************************************************************************
1600 template< typename Type // Data type of the sparse matrix
1601  , bool SO > // Storage order
1603 {
1604  for( size_t i=0UL; i<m_; ++i )
1605  trim( i );
1606 }
1607 //*************************************************************************************************
1608 
1609 
1610 //*************************************************************************************************
1621 template< typename Type // Data type of the sparse matrix
1622  , bool SO > // Storage order
1624 {
1625  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1626 
1627  if( i < ( m_ - 1UL ) )
1628  end_[i+1] = std::copy( begin_[i+1], end_[i+1], end_[i] );
1629  begin_[i+1] = end_[i];
1630 }
1631 //*************************************************************************************************
1632 
1633 
1634 //*************************************************************************************************
1639 template< typename Type // Data type of the sparse matrix
1640  , bool SO > // Storage order
1642 {
1643  CompressedMatrix tmp( trans( *this ) );
1644  swap( tmp );
1645  return *this;
1646 }
1647 //*************************************************************************************************
1648 
1649 
1650 //*************************************************************************************************
1656 template< typename Type // Data type of the sparse matrix
1657  , bool SO > // Storage order
1658 template< typename Other > // Data type of the scalar value
1660 {
1661  for( size_t i=0UL; i<m_; ++i )
1662  for( Iterator element=begin_[i]; element!=end_[i]; ++element )
1663  element->value_ *= scalar;
1664 
1665  return *this;
1666 }
1667 //*************************************************************************************************
1668 
1669 
1670 //*************************************************************************************************
1676 template< typename Type // Data type of the sparse matrix
1677  , bool SO > // Storage order
1678 template< typename Other > // Data type of the scalar value
1680 {
1681  const size_t size( blaze::min( m_, n_ ) );
1682 
1683  for( size_t i=0UL; i<size; ++i ) {
1684  Iterator pos = lowerBound( i, i );
1685  if( pos != end_[i] && pos->index_ == i )
1686  pos->value_ *= scalar;
1687  }
1688 
1689  return *this;
1690 }
1691 //*************************************************************************************************
1692 
1693 
1694 //*************************************************************************************************
1701 template< typename Type // Data type of the sparse matrix
1702  , bool SO > // Storage order
1703 inline void CompressedMatrix<Type,SO>::swap( CompressedMatrix& sm ) /* throw() */
1704 {
1705  std::swap( m_, sm.m_ );
1706  std::swap( n_, sm.n_ );
1707  std::swap( capacity_, sm.capacity_ );
1708  std::swap( begin_, sm.begin_ );
1709  std::swap( end_ , sm.end_ );
1710 }
1711 //*************************************************************************************************
1712 
1713 
1714 //*************************************************************************************************
1722 template< typename Type // Data type of the sparse matrix
1723  , bool SO > // Storage order
1725 {
1726  size_t nonzeros( 2UL*capacity()+1UL );
1727  nonzeros = blaze::max( nonzeros, 7UL );
1728 
1729  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
1730 
1731  return nonzeros;
1732 }
1733 //*************************************************************************************************
1734 
1735 
1736 //*************************************************************************************************
1742 template< typename Type // Data type of the sparse matrix
1743  , bool SO > // Storage order
1745 {
1746  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1747  Iterator* newEnd = newBegin+capacity_+1UL;
1748 
1749  newBegin[0UL] = new Element[nonzeros];
1750 
1751  for( size_t k=0UL; k<m_; ++k ) {
1752  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid row pointers" );
1753  newEnd [k] = std::copy( begin_[k], end_[k], newBegin[k] );
1754  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
1755  }
1756 
1757  newEnd[m_] = newBegin[0UL]+nonzeros;
1758 
1759  std::swap( newBegin, begin_ );
1760  delete [] newBegin[0UL];
1761  delete [] newBegin;
1762  end_ = newEnd;
1763 }
1764 //*************************************************************************************************
1765 
1766 
1767 
1768 
1769 //=================================================================================================
1770 //
1771 // LOOKUP FUNCTIONS
1772 //
1773 //=================================================================================================
1774 
1775 //*************************************************************************************************
1790 template< typename Type // Data type of the sparse matrix
1791  , bool SO > // Storage order
1793  CompressedMatrix<Type,SO>::find( size_t i, size_t j )
1794 {
1795  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
1796 }
1797 //*************************************************************************************************
1798 
1799 
1800 //*************************************************************************************************
1815 template< typename Type // Data type of the sparse matrix
1816  , bool SO > // Storage order
1818  CompressedMatrix<Type,SO>::find( size_t i, size_t j ) const
1819 {
1820  const ConstIterator pos( lowerBound( i, j ) );
1821  if( pos != end_[i] && pos->index_ == j )
1822  return pos;
1823  else return end_[i];
1824 }
1825 //*************************************************************************************************
1826 
1827 
1828 //*************************************************************************************************
1843 template< typename Type // Data type of the sparse matrix
1844  , bool SO > // Storage order
1847 {
1848  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
1849 }
1850 //*************************************************************************************************
1851 
1852 
1853 //*************************************************************************************************
1868 template< typename Type // Data type of the sparse matrix
1869  , bool SO > // Storage order
1871  CompressedMatrix<Type,SO>::lowerBound( size_t i, size_t j ) const
1872 {
1873  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1874  return std::lower_bound( begin_[i], end_[i], j, FindIndex() );
1875 }
1876 //*************************************************************************************************
1877 
1878 
1879 //*************************************************************************************************
1894 template< typename Type // Data type of the sparse matrix
1895  , bool SO > // Storage order
1898 {
1899  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
1900 }
1901 //*************************************************************************************************
1902 
1903 
1904 //*************************************************************************************************
1919 template< typename Type // Data type of the sparse matrix
1920  , bool SO > // Storage order
1922  CompressedMatrix<Type,SO>::upperBound( size_t i, size_t j ) const
1923 {
1924  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1925  return std::upper_bound( begin_[i], end_[i], j, FindIndex() );
1926 }
1927 //*************************************************************************************************
1928 
1929 
1930 
1931 
1932 //=================================================================================================
1933 //
1934 // LOW-LEVEL UTILITY FUNCTIONS
1935 //
1936 //=================================================================================================
1937 
1938 //*************************************************************************************************
1981 template< typename Type // Data type of the sparse matrix
1982  , bool SO > // Storage order
1983 inline void CompressedMatrix<Type,SO>::append( size_t i, size_t j, const Type& value, bool check )
1984 {
1985  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
1986  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
1987  BLAZE_USER_ASSERT( end_[i] < end_[m_], "Not enough reserved space left" );
1988  BLAZE_USER_ASSERT( begin_[i] == end_[i] || j > ( end_[i]-1UL )->index_, "Index is not strictly increasing" );
1989 
1990  end_[i]->value_ = value;
1991 
1992  if( !check || !isDefault( end_[i]->value_ ) ) {
1993  end_[i]->index_ = j;
1994  ++end_[i];
1995  }
1996 }
1997 //*************************************************************************************************
1998 
1999 
2000 //*************************************************************************************************
2013 template< typename Type // Data type of the sparse matrix
2014  , bool SO > // Storage order
2016 {
2017  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2018 
2019  begin_[i+1UL] = end_[i];
2020  if( i != m_-1UL )
2021  end_[i+1UL] = end_[i];
2022 }
2023 //*************************************************************************************************
2024 
2025 
2026 
2027 
2028 //=================================================================================================
2029 //
2030 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2031 //
2032 //=================================================================================================
2033 
2034 //*************************************************************************************************
2044 template< typename Type // Data type of the sparse matrix
2045  , bool SO > // Storage order
2046 template< typename Other > // Data type of the foreign expression
2047 inline bool CompressedMatrix<Type,SO>::canAlias( const Other* alias ) const
2048 {
2049  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2050 }
2051 //*************************************************************************************************
2052 
2053 
2054 //*************************************************************************************************
2064 template< typename Type // Data type of the sparse matrix
2065  , bool SO > // Storage order
2066 template< typename Other > // Data type of the foreign expression
2067 inline bool CompressedMatrix<Type,SO>::isAliased( const Other* alias ) const
2068 {
2069  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2070 }
2071 //*************************************************************************************************
2072 
2073 
2074 //*************************************************************************************************
2085 template< typename Type // Data type of the sparse matrix
2086  , bool SO > // Storage order
2087 template< typename MT // Type of the right-hand side dense matrix
2088  , bool SO2 > // Storage order of the right-hand side dense matrix
2090 {
2091  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2092  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2093 
2094  size_t nonzeros( 0UL );
2095 
2096  for( size_t i=1UL; i<=m_; ++i )
2097  begin_[i] = end_[i] = end_[m_];
2098 
2099  for( size_t i=0UL; i<m_; ++i )
2100  {
2101  begin_[i] = end_[i] = begin_[0UL]+nonzeros;
2102 
2103  for( size_t j=0UL; j<n_; ++j )
2104  {
2105  if( nonzeros == capacity() ) {
2106  reserveElements( extendCapacity() );
2107  for( size_t k=i+1UL; k<=m_; ++k )
2108  begin_[k] = end_[k] = end_[m_];
2109  }
2110 
2111  end_[i]->value_ = (~rhs)(i,j);
2112 
2113  if( !isDefault( end_[i]->value_ ) ) {
2114  end_[i]->index_ = j;
2115  ++end_[i];
2116  ++nonzeros;
2117  }
2118  }
2119  }
2120 
2121  begin_[m_] = begin_[0UL]+nonzeros;
2122 }
2123 //*************************************************************************************************
2124 
2125 
2126 //*************************************************************************************************
2137 template< typename Type // Data type of the sparse matrix
2138  , bool SO > // Storage order
2139 template< typename MT > // Type of the right-hand side sparse matrix
2141 {
2142  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2143  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2144  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2145 
2146  for( size_t i=0UL; i<(~rhs).rows(); ++i ) {
2147  begin_[i+1UL] = end_[i] = std::copy( (~rhs).begin(i), (~rhs).end(i), begin_[i] );
2148  }
2149 }
2150 //*************************************************************************************************
2151 
2152 
2153 //*************************************************************************************************
2164 template< typename Type // Data type of the sparse matrix
2165  , bool SO > // Storage order
2166 template< typename MT > // Type of the right-hand side sparse matrix
2168 {
2169  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2170  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2171  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2172 
2173  typedef typename MT::ConstIterator RhsIterator;
2174 
2175  // Counting the number of elements per row
2176  std::vector<size_t> rowLengths( m_, 0UL );
2177  for( size_t j=0UL; j<n_; ++j ) {
2178  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2179  ++rowLengths[element->index()];
2180  }
2181 
2182  // Resizing the sparse matrix
2183  for( size_t i=0UL; i<m_; ++i ) {
2184  begin_[i+1UL] = end_[i+1UL] = begin_[i] + rowLengths[i];
2185  }
2186 
2187  // Appending the elements to the rows of the sparse matrix
2188  for( size_t j=0UL; j<n_; ++j ) {
2189  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2190  append( element->index(), j, element->value() );
2191  }
2192 }
2193 //*************************************************************************************************
2194 
2195 
2196 //*************************************************************************************************
2207 template< typename Type // Data type of the sparse matrix
2208  , bool SO > // Storage order
2209 template< typename MT // Type of the right-hand side dense matrix
2210  , bool SO2 > // Storage order of the right-hand side dense matrix
2212 {
2213  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2214  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2215 
2216  CompressedMatrix tmp( *this + (~rhs) );
2217  swap( tmp );
2218 }
2219 //*************************************************************************************************
2220 
2221 
2222 //*************************************************************************************************
2233 template< typename Type // Data type of the sparse matrix
2234  , bool SO > // Storage order
2235 template< typename MT // Type of the right-hand side sparse matrix
2236  , bool SO2 > // Storage order of the right-hand side sparse matrix
2238 {
2239  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2240  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2241 
2242  CompressedMatrix tmp( *this + (~rhs) );
2243  swap( tmp );
2244 }
2245 //*************************************************************************************************
2246 
2247 
2248 //*************************************************************************************************
2259 template< typename Type // Data type of the sparse matrix
2260  , bool SO > // Storage order
2261 template< typename MT // Type of the right-hand side dense matrix
2262  , bool SO2 > // Storage order of the right-hand side dense matrix
2264 {
2265  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2266  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2267 
2268  CompressedMatrix tmp( *this - (~rhs) );
2269  swap( tmp );
2270 }
2271 //*************************************************************************************************
2272 
2273 
2274 //*************************************************************************************************
2285 template< typename Type // Data type of the sparse matrix
2286  , bool SO > // Storage order
2287 template< typename MT // Type of the right-hand side sparse matrix
2288  , bool SO2 > // Storage order of the right-hand sparse matrix
2290 {
2291  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2292  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2293 
2294  CompressedMatrix tmp( *this - (~rhs) );
2295  swap( tmp );
2296 }
2297 //*************************************************************************************************
2298 
2299 
2300 
2301 
2302 
2303 
2304 
2305 
2306 //=================================================================================================
2307 //
2308 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2309 //
2310 //=================================================================================================
2311 
2312 //*************************************************************************************************
2320 template< typename Type > // Data type of the sparse matrix
2321 class CompressedMatrix<Type,true> : public SparseMatrix< CompressedMatrix<Type,true>, true >
2322 {
2323  private:
2324  //**Type definitions****************************************************************************
2326  //**********************************************************************************************
2327 
2328  //**Private class Element***********************************************************************
2332  struct Element : public ElementBase
2333  {
2334  // This operator is required due to a bug in all versions of the the MSVC compiler.
2335  // A simple 'using ElementBase::operator=;' statement results in ambiguity problems.
2336  template< typename Other >
2337  inline Element& operator=( const Other& rhs )
2338  {
2339  ElementBase::operator=( rhs );
2340  return *this;
2341  }
2342 
2343  friend class CompressedMatrix;
2344  };
2346  //**********************************************************************************************
2347 
2348  //**Private class FindIndex*********************************************************************
2352  struct FindIndex : public std::binary_function<Element,size_t,bool>
2353  {
2354  inline bool operator()( const Element& element, size_t index ) const {
2355  return element.index() < index;
2356  }
2357  inline bool operator()( size_t index, const Element& element ) const {
2358  return index < element.index();
2359  }
2360  inline bool operator()( const Element& element1, const Element& element2 ) const {
2361  return element1.index() < element2.index();
2362  }
2363  };
2365  //**********************************************************************************************
2366 
2367  public:
2368  //**Type definitions****************************************************************************
2370  typedef This ResultType;
2373  typedef Type ElementType;
2374  typedef const Type& ReturnType;
2375  typedef const This& CompositeType;
2377  typedef const Type& ConstReference;
2378  typedef Element* Iterator;
2379  typedef const Element* ConstIterator;
2380  //**********************************************************************************************
2381 
2382  //**Constructors********************************************************************************
2385  explicit inline CompressedMatrix();
2386  explicit inline CompressedMatrix( size_t m, size_t n );
2387  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
2388  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
2389  inline CompressedMatrix( const CompressedMatrix& sm );
2390  template< typename MT, bool SO > inline CompressedMatrix( const DenseMatrix<MT,SO>& dm );
2391  template< typename MT, bool SO > inline CompressedMatrix( const SparseMatrix<MT,SO>& sm );
2393  //**********************************************************************************************
2394 
2395  //**Destructor**********************************************************************************
2398  inline ~CompressedMatrix();
2400  //**********************************************************************************************
2401 
2402  //**Data access functions***********************************************************************
2405  inline Reference operator()( size_t i, size_t j );
2406  inline ConstReference operator()( size_t i, size_t j ) const;
2407  inline Iterator begin ( size_t i );
2408  inline ConstIterator begin ( size_t i ) const;
2409  inline ConstIterator cbegin( size_t i ) const;
2410  inline Iterator end ( size_t i );
2411  inline ConstIterator end ( size_t i ) const;
2412  inline ConstIterator cend ( size_t i ) const;
2414  //**********************************************************************************************
2415 
2416  //**Assignment operators************************************************************************
2419  inline CompressedMatrix& operator= ( const CompressedMatrix& rhs );
2420  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO>& rhs );
2421  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO>& rhs );
2422  template< typename MT, bool SO > inline CompressedMatrix& operator+=( const Matrix<MT,SO>& rhs );
2423  template< typename MT, bool SO > inline CompressedMatrix& operator-=( const Matrix<MT,SO>& rhs );
2424  template< typename MT, bool SO > inline CompressedMatrix& operator*=( const Matrix<MT,SO>& rhs );
2425 
2426  template< typename Other >
2427  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
2428  operator*=( Other rhs );
2429 
2430  template< typename Other >
2431  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
2432  operator/=( Other rhs );
2434  //**********************************************************************************************
2435 
2436  //**Utility functions***************************************************************************
2439  inline size_t rows() const;
2440  inline size_t columns() const;
2441  inline size_t capacity() const;
2442  inline size_t capacity( size_t j ) const;
2443  inline size_t nonZeros() const;
2444  inline size_t nonZeros( size_t j ) const;
2445  inline void reset();
2446  inline void reset( size_t j );
2447  inline void clear();
2448  Iterator insert ( size_t i, size_t j, const Type& value );
2449  inline void erase ( size_t i, size_t j );
2450  inline Iterator erase ( size_t j, Iterator pos );
2451  inline Iterator erase ( size_t j, Iterator first, Iterator last );
2452  void resize ( size_t m, size_t n, bool preserve=true );
2453  inline void reserve( size_t nonzeros );
2454  void reserve( size_t j, size_t nonzeros );
2455  inline void trim ();
2456  inline void trim ( size_t j );
2457  inline CompressedMatrix& transpose();
2458  template< typename Other > inline CompressedMatrix& scale( Other scalar );
2459  template< typename Other > inline CompressedMatrix& scaleDiagonal( Other scalar );
2460  inline void swap( CompressedMatrix& sm ) /* throw() */;
2462  //**********************************************************************************************
2463 
2464  //**Lookup functions****************************************************************************
2467  inline Iterator find ( size_t i, size_t j );
2468  inline ConstIterator find ( size_t i, size_t j ) const;
2469  inline Iterator lowerBound( size_t i, size_t j );
2470  inline ConstIterator lowerBound( size_t i, size_t j ) const;
2471  inline Iterator upperBound( size_t i, size_t j );
2472  inline ConstIterator upperBound( size_t i, size_t j ) const;
2474  //**********************************************************************************************
2475 
2476  //**Low-level utility functions*****************************************************************
2479  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
2480  inline void finalize( size_t j );
2482  //**********************************************************************************************
2483 
2484  //**Expression template evaluation functions****************************************************
2487  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2488  template< typename Other > inline bool isAliased( const Other* alias ) const;
2489  template< typename MT, bool SO > inline void assign ( const DenseMatrix<MT,SO>& rhs );
2490  template< typename MT > inline void assign ( const SparseMatrix<MT,true>& rhs );
2491  template< typename MT > inline void assign ( const SparseMatrix<MT,false>& rhs );
2492  template< typename MT, bool SO > inline void addAssign( const DenseMatrix<MT,SO>& rhs );
2493  template< typename MT, bool SO > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
2494  template< typename MT, bool SO > inline void subAssign( const DenseMatrix<MT,SO>& rhs );
2495  template< typename MT, bool SO > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
2497  //**********************************************************************************************
2498 
2499  private:
2500  //**Utility functions***************************************************************************
2503  inline size_t extendCapacity() const;
2504  void reserveElements( size_t nonzeros );
2506  //**********************************************************************************************
2507 
2508  //**Member variables****************************************************************************
2511  size_t m_;
2512  size_t n_;
2513  size_t capacity_;
2516 
2517  static const Type zero_;
2518 
2519  //**********************************************************************************************
2520 
2521  //**Compile time checks*************************************************************************
2529  //**********************************************************************************************
2530 };
2532 //*************************************************************************************************
2533 
2534 
2535 
2536 
2537 //=================================================================================================
2538 //
2539 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
2540 //
2541 //=================================================================================================
2542 
2543 template< typename Type >
2544 const Type CompressedMatrix<Type,true>::zero_ = Type();
2545 
2546 
2547 
2548 
2549 //=================================================================================================
2550 //
2551 // CONSTRUCTORS
2552 //
2553 //=================================================================================================
2554 
2555 //*************************************************************************************************
2559 template< typename Type > // Data type of the sparse matrix
2561  : m_ ( 0UL ) // The current number of rows of the sparse matrix
2562  , n_ ( 0UL ) // The current number of columns of the sparse matrix
2563  , capacity_( 0UL ) // The current capacity of the pointer array
2564  , begin_( new Iterator[2UL] ) // Pointers to the first non-zero element of each column
2565  , end_ ( begin_+1UL ) // Pointers one past the last non-zero element of each column
2566 {
2567  begin_[0UL] = end_[0UL] = NULL;
2568 }
2570 //*************************************************************************************************
2571 
2572 
2573 //*************************************************************************************************
2582 template< typename Type > // Data type of the sparse matrix
2583 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n )
2584  : m_ ( m ) // The current number of rows of the sparse matrix
2585  , n_ ( n ) // The current number of columns of the sparse matrix
2586  , capacity_( n ) // The current capacity of the pointer array
2587  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
2588  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
2589 {
2590  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
2591  begin_[j] = NULL;
2592 }
2594 //*************************************************************************************************
2595 
2596 
2597 //*************************************************************************************************
2607 template< typename Type > // Data type of the sparse matrix
2608 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
2609  : m_ ( m ) // The current number of rows of the sparse matrix
2610  , n_ ( n ) // The current number of columns of the sparse matrix
2611  , capacity_( n ) // The current capacity of the pointer array
2612  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
2613  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
2614 {
2615  begin_[0UL] = new Element[nonzeros];
2616  for( size_t j=1UL; j<(2UL*n_+1UL); ++j )
2617  begin_[j] = begin_[0UL];
2618  end_[n_] = begin_[0UL]+nonzeros;
2619 }
2621 //*************************************************************************************************
2622 
2623 
2624 //*************************************************************************************************
2634 template< typename Type > // Data type of the sparse matrix
2635 CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
2636  : m_ ( m ) // The current number of rows of the sparse matrix
2637  , n_ ( n ) // The current number of columns of the sparse matrix
2638  , capacity_( n ) // The current capacity of the pointer array
2639  , begin_( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2640  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2641 {
2642  BLAZE_USER_ASSERT( nonzeros.size() == n, "Size of capacity vector and number of columns don't match" );
2643 
2644  size_t newCapacity( 0UL );
2645  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
2646  newCapacity += *it;
2647 
2648  begin_[0UL] = end_[0UL] = new Element[newCapacity];
2649  for( size_t j=0UL; j<n_; ++j ) {
2650  begin_[j+1UL] = end_[j+1UL] = begin_[j] + nonzeros[j];
2651  }
2652 }
2654 //*************************************************************************************************
2655 
2656 
2657 //*************************************************************************************************
2663 template< typename Type > // Data type of the sparse matrix
2664 inline CompressedMatrix<Type,true>::CompressedMatrix( const CompressedMatrix& sm )
2665  : m_ ( sm.m_ ) // The current number of rows of the sparse matrix
2666  , n_ ( sm.n_ ) // The current number of columns of the sparse matrix
2667  , capacity_( sm.n_ ) // The current capacity of the pointer array
2668  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2669  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2670 {
2671  const size_t nonzeros( sm.nonZeros() );
2672 
2673  begin_[0UL] = new Element[nonzeros];
2674  for( size_t j=0UL; j<n_; ++j )
2675  begin_[j+1UL] = end_[j] = std::copy( sm.begin(j), sm.end(j), begin_[j] );
2676  end_[n_] = begin_[0UL]+nonzeros;
2677 }
2679 //*************************************************************************************************
2680 
2681 
2682 //*************************************************************************************************
2688 template< typename Type > // Data type of the sparse matrix
2689 template< typename MT // Type of the foreign dense matrix
2690  , bool SO > // Storage order of the foreign dense matrix
2691 inline CompressedMatrix<Type,true>::CompressedMatrix( const DenseMatrix<MT,SO>& dm )
2692  : m_ ( (~dm).rows() ) // The current number of rows of the sparse matrix
2693  , n_ ( (~dm).columns() ) // The current number of columns of the sparse matrix
2694  , capacity_( n_ ) // The current capacity of the pointer array
2695  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2696  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2697 {
2698  using blaze::assign;
2699 
2700  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
2701  begin_[j] = NULL;
2702 
2703  assign( *this, ~dm );
2704 }
2706 //*************************************************************************************************
2707 
2708 
2709 //*************************************************************************************************
2715 template< typename Type > // Data type of the sparse matrix
2716 template< typename MT // Type of the foreign sparse matrix
2717  , bool SO > // Storage order of the foreign sparse matrix
2718 inline CompressedMatrix<Type,true>::CompressedMatrix( const SparseMatrix<MT,SO>& sm )
2719  : m_ ( (~sm).rows() ) // The current number of rows of the sparse matrix
2720  , n_ ( (~sm).columns() ) // The current number of columns of the sparse matrix
2721  , capacity_( n_ ) // The current capacity of the pointer array
2722  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2723  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2724 {
2725  using blaze::assign;
2726 
2727  const size_t nonzeros( (~sm).nonZeros() );
2728 
2729  begin_[0UL] = new Element[nonzeros];
2730  for( size_t j=0UL; j<n_; ++j )
2731  begin_[j+1UL] = end_[j] = begin_[0UL];
2732  end_[n_] = begin_[0UL]+nonzeros;
2733 
2734  assign( *this, ~sm );
2735 }
2737 //*************************************************************************************************
2738 
2739 
2740 
2741 
2742 //=================================================================================================
2743 //
2744 // DESTRUCTOR
2745 //
2746 //=================================================================================================
2747 
2748 //*************************************************************************************************
2752 template< typename Type > // Data type of the sparse matrix
2753 inline CompressedMatrix<Type,true>::~CompressedMatrix()
2754 {
2755  delete [] begin_[0UL];
2756  delete [] begin_;
2757 }
2759 //*************************************************************************************************
2760 
2761 
2762 
2763 
2764 //=================================================================================================
2765 //
2766 // DATA ACCESS FUNCTIONS
2767 //
2768 //=================================================================================================
2769 
2770 //*************************************************************************************************
2778 template< typename Type > // Data type of the sparse matrix
2780  CompressedMatrix<Type,true>::operator()( size_t i, size_t j )
2781 {
2782  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2783  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2784 
2785  return Reference( *this, i, j );
2786 }
2788 //*************************************************************************************************
2789 
2790 
2791 //*************************************************************************************************
2799 template< typename Type > // Data type of the sparse matrix
2801  CompressedMatrix<Type,true>::operator()( size_t i, size_t j ) const
2802 {
2803  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2804  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2805 
2806  const ConstIterator pos( lowerBound( i, j ) );
2807 
2808  if( pos == end_[j] || pos->index_ != i )
2809  return zero_;
2810  else
2811  return pos->value_;
2812 }
2814 //*************************************************************************************************
2815 
2816 
2817 //*************************************************************************************************
2824 template< typename Type > // Data type of the sparse matrix
2826  CompressedMatrix<Type,true>::begin( size_t j )
2827 {
2828  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2829  return begin_[j];
2830 }
2832 //*************************************************************************************************
2833 
2834 
2835 //*************************************************************************************************
2842 template< typename Type > // Data type of the sparse matrix
2844  CompressedMatrix<Type,true>::begin( size_t j ) const
2845 {
2846  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2847  return begin_[j];
2848 }
2850 //*************************************************************************************************
2851 
2852 
2853 //*************************************************************************************************
2860 template< typename Type > // Data type of the sparse matrix
2862  CompressedMatrix<Type,true>::cbegin( size_t j ) const
2863 {
2864  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2865  return begin_[j];
2866 }
2868 //*************************************************************************************************
2869 
2870 
2871 //*************************************************************************************************
2878 template< typename Type > // Data type of the sparse matrix
2880  CompressedMatrix<Type,true>::end( size_t j )
2881 {
2882  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2883  return end_[j];
2884 }
2886 //*************************************************************************************************
2887 
2888 
2889 //*************************************************************************************************
2896 template< typename Type > // Data type of the sparse matrix
2898  CompressedMatrix<Type,true>::end( size_t j ) const
2899 {
2900  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2901  return end_[j];
2902 }
2904 //*************************************************************************************************
2905 
2906 
2907 //*************************************************************************************************
2914 template< typename Type > // Data type of the sparse matrix
2916  CompressedMatrix<Type,true>::cend( size_t j ) const
2917 {
2918  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2919  return end_[j];
2920 }
2922 //*************************************************************************************************
2923 
2924 
2925 
2926 
2927 //=================================================================================================
2928 //
2929 // ASSIGNMENT OPERATORS
2930 //
2931 //=================================================================================================
2932 
2933 //*************************************************************************************************
2943 template< typename Type > // Data type of the sparse matrix
2944 inline CompressedMatrix<Type,true>&
2945  CompressedMatrix<Type,true>::operator=( const CompressedMatrix& rhs )
2946 {
2947  if( &rhs == this ) return *this;
2948 
2949  const size_t nonzeros( rhs.nonZeros() );
2950 
2951  if( rhs.n_ > capacity_ || nonzeros > capacity() )
2952  {
2953  Iterator* newBegin( new Iterator[2UL*rhs.n_+2UL] );
2954  Iterator* newEnd ( newBegin+(rhs.n_+1UL) );
2955 
2956  newBegin[0UL] = new Element[nonzeros];
2957  for( size_t j=0UL; j<rhs.n_; ++j ) {
2958  newBegin[j+1UL] = newEnd[j] = std::copy( rhs.begin_[j], rhs.end_[j], newBegin[j] );
2959  }
2960  newEnd[rhs.n_] = newBegin[0UL]+nonzeros;
2961 
2962  std::swap( begin_, newBegin );
2963  end_ = newEnd;
2964  delete [] newBegin[0UL];
2965  delete [] newBegin;
2966  capacity_ = rhs.n_;
2967  }
2968  else {
2969  for( size_t j=0UL; j<rhs.n_; ++j ) {
2970  begin_[j+1UL] = end_[j] = std::copy( rhs.begin_[j], rhs.end_[j], begin_[j] );
2971  }
2972  }
2973 
2974  m_ = rhs.m_;
2975  n_ = rhs.n_;
2976 
2977  return *this;
2978 }
2980 //*************************************************************************************************
2981 
2982 
2983 //*************************************************************************************************
2993 template< typename Type > // Data type of the sparse matrix
2994 template< typename MT // Type of the right-hand side dense matrix
2995  , bool SO > // Storage order of the right-hand side dense matrix
2996 inline CompressedMatrix<Type,true>&
2997  CompressedMatrix<Type,true>::operator=( const DenseMatrix<MT,SO>& rhs )
2998 {
2999  using blaze::assign;
3000 
3001  if( (~rhs).canAlias( this ) ) {
3002  CompressedMatrix tmp( rhs );
3003  swap( tmp );
3004  }
3005  else {
3006  resize( (~rhs).rows(), (~rhs).columns(), false );
3007  assign( *this, ~rhs );
3008  }
3009 
3010  return *this;
3011 }
3013 //*************************************************************************************************
3014 
3015 
3016 //*************************************************************************************************
3026 template< typename Type > // Data type of the sparse matrix
3027 template< typename MT // Type of the right-hand side sparse matrix
3028  , bool SO > // Storage order of the right-hand side sparse matrix
3029 inline CompressedMatrix<Type,true>&
3030  CompressedMatrix<Type,true>::operator=( const SparseMatrix<MT,SO>& rhs )
3031 {
3032  using blaze::assign;
3033 
3034  if( (~rhs).canAlias( this ) ||
3035  (~rhs).columns() > capacity_ ||
3036  (~rhs).nonZeros() > capacity() ) {
3037  CompressedMatrix tmp( rhs );
3038  swap( tmp );
3039  }
3040  else {
3041  resize( (~rhs).rows(), (~rhs).columns(), false );
3042  reset();
3043  assign( *this, ~rhs );
3044  }
3045 
3046  return *this;
3047 }
3049 //*************************************************************************************************
3050 
3051 
3052 //*************************************************************************************************
3063 template< typename Type > // Data type of the sparse matrix
3064 template< typename MT // Type of the right-hand side matrix
3065  , bool SO > // Storage order of the right-hand side matrix
3066 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator+=( const Matrix<MT,SO>& rhs )
3067 {
3068  using blaze::addAssign;
3069 
3070  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
3071  throw std::invalid_argument( "Matrix sizes do not match" );
3072 
3073  addAssign( *this, ~rhs );
3074  return *this;
3075 }
3077 //*************************************************************************************************
3078 
3079 
3080 //*************************************************************************************************
3091 template< typename Type > // Data type of the sparse matrix
3092 template< typename MT // Type of the right-hand side matrix
3093  , bool SO > // Storage order of the right-hand side matrix
3094 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator-=( const Matrix<MT,SO>& rhs )
3095 {
3096  using blaze::subAssign;
3097 
3098  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
3099  throw std::invalid_argument( "Matrix sizes do not match" );
3100 
3101  subAssign( *this, ~rhs );
3102  return *this;
3103 }
3105 //*************************************************************************************************
3106 
3107 
3108 //*************************************************************************************************
3119 template< typename Type > // Data type of the sparse matrix
3120 template< typename MT // Type of the right-hand side matrix
3121  , bool SO > // Storage order of the right-hand side matrix
3122 inline CompressedMatrix<Type,true>&
3123  CompressedMatrix<Type,true>::operator*=( const Matrix<MT,SO>& rhs )
3124 {
3125  if( (~rhs).rows() != n_ )
3126  throw std::invalid_argument( "Matrix sizes do not match" );
3127 
3128  CompressedMatrix tmp( *this * (~rhs) );
3129  swap( tmp );
3130 
3131  return *this;
3132 }
3134 //*************************************************************************************************
3135 
3136 
3137 //*************************************************************************************************
3145 template< typename Type > // Data type of the sparse matrix
3146 template< typename Other > // Data type of the right-hand side scalar
3147 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,true> >::Type&
3148  CompressedMatrix<Type,true>::operator*=( Other rhs )
3149 {
3150  for( size_t j=0UL; j<n_; ++j ) {
3151  const Iterator last( end(j) );
3152  for( Iterator element=begin(j); element!=last; ++element )
3153  element->value_ *= rhs;
3154  }
3155 
3156  return *this;
3157 }
3159 //*************************************************************************************************
3160 
3161 
3162 //*************************************************************************************************
3170 template< typename Type > // Data type of the sparse matrix
3171 template< typename Other > // Data type of the right-hand side scalar
3172 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,true> >::Type&
3173  CompressedMatrix<Type,true>::operator/=( Other rhs )
3174 {
3175  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3176 
3177  typedef typename DivTrait<Type,Other>::Type DT;
3178  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
3179 
3180  // Depending on the two involved data types, an integer division is applied or a
3181  // floating point division is selected.
3182  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
3183  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
3184  for( size_t j=0UL; j<n_; ++j ) {
3185  const Iterator last( end(j) );
3186  for( Iterator element=begin(j); element!=last; ++element )
3187  element->value_ *= tmp;
3188  }
3189  }
3190  else {
3191  for( size_t j=0UL; j<n_; ++j ) {
3192  const Iterator last( end(j) );
3193  for( Iterator element=begin(j); element!=last; ++element )
3194  element->value_ /= rhs;
3195  }
3196  }
3197 
3198  return *this;
3199 }
3201 //*************************************************************************************************
3202 
3203 
3204 
3205 
3206 //=================================================================================================
3207 //
3208 // UTILITY FUNCTIONS
3209 //
3210 //=================================================================================================
3211 
3212 //*************************************************************************************************
3218 template< typename Type > // Data type of the sparse matrix
3219 inline size_t CompressedMatrix<Type,true>::rows() const
3220 {
3221  return m_;
3222 }
3224 //*************************************************************************************************
3225 
3226 
3227 //*************************************************************************************************
3233 template< typename Type > // Data type of the sparse matrix
3234 inline size_t CompressedMatrix<Type,true>::columns() const
3235 {
3236  return n_;
3237 }
3239 //*************************************************************************************************
3240 
3241 
3242 //*************************************************************************************************
3248 template< typename Type > // Data type of the sparse matrix
3249 inline size_t CompressedMatrix<Type,true>::capacity() const
3250 {
3251  return end_[n_] - begin_[0UL];
3252 }
3254 //*************************************************************************************************
3255 
3256 
3257 //*************************************************************************************************
3264 template< typename Type > // Data type of the sparse matrix
3265 inline size_t CompressedMatrix<Type,true>::capacity( size_t j ) const
3266 {
3267  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3268  return begin_[j+1UL] - begin_[j];
3269 }
3271 //*************************************************************************************************
3272 
3273 
3274 //*************************************************************************************************
3280 template< typename Type > // Data type of the sparse matrix
3281 inline size_t CompressedMatrix<Type,true>::nonZeros() const
3282 {
3283  size_t nonzeros( 0UL );
3284 
3285  for( size_t j=0UL; j<n_; ++j )
3286  nonzeros += nonZeros( j );
3287 
3288  return nonzeros;
3289 }
3291 //*************************************************************************************************
3292 
3293 
3294 //*************************************************************************************************
3301 template< typename Type > // Data type of the sparse matrix
3302 inline size_t CompressedMatrix<Type,true>::nonZeros( size_t j ) const
3303 {
3304  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3305  return end_[j] - begin_[j];
3306 }
3308 //*************************************************************************************************
3309 
3310 
3311 //*************************************************************************************************
3317 template< typename Type > // Data type of the sparse matrix
3319 {
3320  for( size_t j=0UL; j<n_; ++j )
3321  end_[j] = begin_[j];
3322 }
3324 //*************************************************************************************************
3325 
3326 
3327 //*************************************************************************************************
3337 template< typename Type > // Data type of the sparse matrix
3338 inline void CompressedMatrix<Type,true>::reset( size_t j )
3339 {
3340  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3341  end_[j] = begin_[j];
3342 }
3344 //*************************************************************************************************
3345 
3346 
3347 //*************************************************************************************************
3355 template< typename Type > // Data type of the sparse matrix
3357 {
3358  end_[0UL] = end_[n_];
3359  m_ = 0UL;
3360  n_ = 0UL;
3361 }
3363 //*************************************************************************************************
3364 
3365 
3366 //*************************************************************************************************
3380 template< typename Type > // Data type of the sparse matrix
3382  CompressedMatrix<Type,true>::insert( size_t i, size_t j, const Type& value )
3383 {
3384  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3385  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3386 
3387  const Iterator pos( lowerBound( i, j ) );
3388 
3389  if( pos != end_[j] && pos->index_ == i )
3390  throw std::invalid_argument( "Bad access index" );
3391 
3392  if( begin_[j+1UL] - end_[j] != 0 ) {
3393  std::copy_backward( pos, end_[j], end_[j]+1 );
3394  pos->value_ = value;
3395  pos->index_ = i;
3396  ++end_[j];
3397 
3398  return pos;
3399  }
3400  else if( end_[n_] - begin_[n_] != 0 ) {
3401  std::copy_backward( pos, end_[n_-1UL], end_[n_-1]+1 );
3402 
3403  pos->value_ = value;
3404  pos->index_ = i;
3405 
3406  for( size_t k=j+1UL; k<n_+1UL; ++k ) {
3407  ++begin_[k];
3408  ++end_[k-1UL];
3409  }
3410 
3411  return pos;
3412  }
3413  else {
3414  size_t newCapacity( extendCapacity() );
3415 
3416  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
3417  Iterator* newEnd = newBegin+capacity_+1UL;
3418 
3419  newBegin[0UL] = new Element[newCapacity];
3420 
3421  for( size_t k=0UL; k<j; ++k ) {
3422  const size_t nonzeros( end_[k] - begin_[k] );
3423  const size_t total( begin_[k+1UL] - begin_[k] );
3424  newEnd [k] = newBegin[k] + nonzeros;
3425  newBegin[k+1UL] = newBegin[k] + total;
3426  }
3427  newEnd [j] = newBegin[j] + ( end_[j] - begin_[j] ) + 1;
3428  newBegin[j+1UL] = newBegin[j] + ( begin_[j+1UL] - begin_[j] ) + 1;
3429  for( size_t k=j+1UL; k<n_; ++k ) {
3430  const size_t nonzeros( end_[k] - begin_[k] );
3431  const size_t total( begin_[k+1UL] - begin_[k] );
3432  newEnd [k] = newBegin[k] + nonzeros;
3433  newBegin[k+1UL] = newBegin[k] + total;
3434  }
3435 
3436  newEnd[n_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
3437 
3438  Iterator tmp = std::copy( begin_[0UL], pos, newBegin[0UL] );
3439  tmp->value_ = value;
3440  tmp->index_ = i;
3441  std::copy( pos, end_[n_-1UL], tmp+1UL );
3442 
3443  std::swap( newBegin, begin_ );
3444  end_ = newEnd;
3445  delete [] newBegin[0UL];
3446  delete [] newBegin;
3447 
3448  return tmp;
3449  }
3450 }
3452 //*************************************************************************************************
3453 
3454 
3455 //*************************************************************************************************
3465 template< typename Type > // Data type of the sparse matrix
3466 inline void CompressedMatrix<Type,true>::erase( size_t i, size_t j )
3467 {
3468  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3469  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3470 
3471  const Iterator pos( find( i, j ) );
3472  if( pos != end_[j] )
3473  end_[j] = std::copy( pos+1, end_[j], pos );
3474 }
3476 //*************************************************************************************************
3477 
3478 
3479 //*************************************************************************************************
3489 template< typename Type > // Data type of the sparse matrix
3491  CompressedMatrix<Type,true>::erase( size_t j, Iterator pos )
3492 {
3493  BLAZE_USER_ASSERT( j < columns() , "Invalid row access index" );
3494  BLAZE_USER_ASSERT( pos >= begin_[j] && pos <= end_[j], "Invalid compressed matrix iterator" );
3495 
3496  if( pos != end_[j] )
3497  end_[j] = std::copy( pos+1, end_[j], pos );
3498 
3499  return pos;
3500 }
3502 //*************************************************************************************************
3503 
3504 
3505 //*************************************************************************************************
3516 template< typename Type > // Data type of the sparse matrix
3518  CompressedMatrix<Type,true>::erase( size_t j, Iterator first, Iterator last )
3519 {
3520  BLAZE_USER_ASSERT( j < columns(), "Invalid row access index" );
3521  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
3522  BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j], "Invalid compressed matrix iterator" );
3523  BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j], "Invalid compressed matrix iterator" );
3524 
3525  if( first != last )
3526  end_[j] = std::copy( last, end_[j], first );
3527 
3528  return first;
3529 }
3531 //*************************************************************************************************
3532 
3533 
3534 //*************************************************************************************************
3549 template< typename Type > // Data type of the sparse matrix
3550 void CompressedMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
3551 {
3552  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
3553  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
3554 
3555  if( m == m_ && n == n_ ) return;
3556 
3557  if( n > capacity_ )
3558  {
3559  Iterator* newBegin( new Iterator[2UL*n+2UL] );
3560  Iterator* newEnd ( newBegin+n+1UL );
3561 
3562  newBegin[0UL] = begin_[0UL];
3563 
3564  if( preserve ) {
3565  for( size_t j=0UL; j<n_; ++j ) {
3566  newEnd [j] = end_ [j];
3567  newBegin[j+1UL] = begin_[j+1UL];
3568  }
3569  for( size_t j=n_; j<n; ++j ) {
3570  newBegin[j+1UL] = newEnd[j] = begin_[n_];
3571  }
3572  }
3573  else {
3574  for( size_t j=0UL; j<n; ++j ) {
3575  newBegin[j+1UL] = newEnd[j] = begin_[0UL];
3576  }
3577  }
3578 
3579  newEnd[n] = end_[n_];
3580 
3581  std::swap( newBegin, begin_ );
3582  delete [] newBegin;
3583 
3584  end_ = newEnd;
3585  capacity_ = n;
3586  }
3587  else if( n > n_ )
3588  {
3589  end_[n] = end_[n_];
3590 
3591  if( !preserve ) {
3592  for( size_t j=0UL; j<n_; ++j )
3593  end_[j] = begin_[j];
3594  }
3595 
3596  for( size_t j=n_; j<n; ++j )
3597  begin_[j+1UL] = end_[j] = begin_[n_];
3598  }
3599  else
3600  {
3601  if( preserve ) {
3602  for( size_t j=0UL; j<n; ++j )
3603  end_[j] = lowerBound( m, j );
3604  }
3605  else {
3606  for( size_t j=0UL; j<n; ++j )
3607  end_[j] = begin_[j];
3608  }
3609 
3610  end_[n] = end_[n_];
3611  }
3612 
3613  m_ = m;
3614  n_ = n;
3615 }
3617 //*************************************************************************************************
3618 
3619 
3620 //*************************************************************************************************
3631 template< typename Type > // Data type of the sparse matrix
3632 inline void CompressedMatrix<Type,true>::reserve( size_t nonzeros )
3633 {
3634  if( nonzeros > capacity() )
3635  reserveElements( nonzeros );
3636 }
3638 //*************************************************************************************************
3639 
3640 
3641 //*************************************************************************************************
3653 template< typename Type > // Data type of the sparse matrix
3654 void CompressedMatrix<Type,true>::reserve( size_t j, size_t nonzeros )
3655 {
3656  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3657 
3658  const size_t current( capacity(j) );
3659 
3660  if( current >= nonzeros ) return;
3661 
3662  const ptrdiff_t additional( nonzeros - current );
3663 
3664  if( end_[n_] - begin_[n_] < additional )
3665  {
3666  const size_t newCapacity( begin_[n_] - begin_[0UL] + additional );
3667  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
3668 
3669  Iterator* newBegin( new Iterator[2UL*n_+2UL] );
3670  Iterator* newEnd ( newBegin+n_+1UL );
3671 
3672  newBegin[0UL] = new Element[newCapacity];
3673  newEnd [n_ ] = newBegin[0UL]+newCapacity;
3674 
3675  for( size_t k=0UL; k<j; ++k ) {
3676  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
3677  newBegin[k+1UL] = newBegin[k] + capacity(k);
3678  }
3679  newEnd [j ] = std::copy( begin_[j], end_[j], newBegin[j] );
3680  newBegin[j+1UL] = newBegin[j] + nonzeros;
3681  for( size_t k=j+1UL; k<n_; ++k ) {
3682  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
3683  newBegin[k+1UL] = newBegin[k] + capacity(k);
3684  }
3685 
3686  BLAZE_INTERNAL_ASSERT( newBegin[n_] == newEnd[n_], "Invalid pointer calculations" );
3687 
3688  std::swap( newBegin, begin_ );
3689  delete [] newBegin[0UL];
3690  delete [] newBegin;
3691  end_ = newEnd;
3692  }
3693  else
3694  {
3695  begin_[n_] += additional;
3696  for( size_t k=n_-1UL; k>j; --k ) {
3697  begin_[k] = std::copy_backward( begin_[k], end_[k], end_[k]+additional );
3698  end_ [k] += additional;
3699  }
3700  }
3701 }
3703 //*************************************************************************************************
3704 
3705 
3706 //*************************************************************************************************
3716 template< typename Type > // Data type of the sparse matrix
3717 void CompressedMatrix<Type,true>::trim()
3718 {
3719  for( size_t j=0UL; j<n_; ++j )
3720  trim( j );
3721 }
3723 //*************************************************************************************************
3724 
3725 
3726 //*************************************************************************************************
3737 template< typename Type > // Data type of the sparse matrix
3738 void CompressedMatrix<Type,true>::trim( size_t j )
3739 {
3740  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3741 
3742  if( j < ( n_ - 1UL ) )
3743  end_[j+1] = std::copy( begin_[j+1], end_[j+1], end_[j] );
3744  begin_[j+1] = end_[j];
3745 }
3747 //*************************************************************************************************
3748 
3749 
3750 //*************************************************************************************************
3756 template< typename Type > // Data type of the sparse matrix
3757 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::transpose()
3758 {
3759  CompressedMatrix tmp( trans( *this ) );
3760  swap( tmp );
3761  return *this;
3762 }
3764 //*************************************************************************************************
3765 
3766 
3767 //*************************************************************************************************
3774 template< typename Type > // Data type of the sparse matrix
3775 template< typename Other > // Data type of the scalar value
3776 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scale( Other scalar )
3777 {
3778  for( size_t j=0UL; j<n_; ++j )
3779  for( Iterator element=begin_[j]; element!=end_[j]; ++element )
3780  element->value_ *= scalar;
3781 
3782  return *this;
3783 }
3785 //*************************************************************************************************
3786 
3787 
3788 //*************************************************************************************************
3795 template< typename Type > // Data type of the sparse matrix
3796 template< typename Other > // Data type of the scalar value
3797 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scaleDiagonal( Other scalar )
3798 {
3799  const size_t size( blaze::min( m_, n_ ) );
3800 
3801  for( size_t j=0UL; j<size; ++j ) {
3802  Iterator pos = lowerBound( j, j );
3803  if( pos != end_[j] && pos->index_ == j )
3804  pos->value_ *= scalar;
3805  }
3806 
3807  return *this;
3808 }
3810 //*************************************************************************************************
3811 
3812 
3813 //*************************************************************************************************
3821 template< typename Type > // Data type of the sparse matrix
3822 inline void CompressedMatrix<Type,true>::swap( CompressedMatrix& sm ) /* throw() */
3823 {
3824  std::swap( m_, sm.m_ );
3825  std::swap( n_, sm.n_ );
3826  std::swap( capacity_, sm.capacity_ );
3827  std::swap( begin_, sm.begin_ );
3828  std::swap( end_ , sm.end_ );
3829 }
3831 //*************************************************************************************************
3832 
3833 
3834 //*************************************************************************************************
3843 template< typename Type > // Data type of the sparse matrix
3844 inline size_t CompressedMatrix<Type,true>::extendCapacity() const
3845 {
3846  size_t nonzeros( 2UL*capacity()+1UL );
3847  nonzeros = blaze::max( nonzeros, 7UL );
3848 
3849  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
3850 
3851  return nonzeros;
3852 }
3854 //*************************************************************************************************
3855 
3856 
3857 //*************************************************************************************************
3864 template< typename Type > // Data type of the sparse matrix
3865 void CompressedMatrix<Type,true>::reserveElements( size_t nonzeros )
3866 {
3867  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
3868  Iterator* newEnd = newBegin+capacity_+1UL;
3869 
3870  newBegin[0UL] = new Element[nonzeros];
3871 
3872  for( size_t k=0UL; k<n_; ++k ) {
3873  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid column pointers" );
3874  newEnd [k] = std::copy( begin_[k], end_[k], newBegin[k] );
3875  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
3876  }
3877 
3878  newEnd[n_] = newBegin[0UL]+nonzeros;
3879 
3880  std::swap( newBegin, begin_ );
3881  delete [] newBegin[0UL];
3882  delete [] newBegin;
3883  end_ = newEnd;
3884 }
3886 //*************************************************************************************************
3887 
3888 
3889 
3890 
3891 //=================================================================================================
3892 //
3893 // LOOKUP FUNCTIONS
3894 //
3895 //=================================================================================================
3896 
3897 //*************************************************************************************************
3912 template< typename Type > // Data type of the sparse matrix
3914  CompressedMatrix<Type,true>::find( size_t i, size_t j )
3915 {
3916  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
3917 }
3919 //*************************************************************************************************
3920 
3921 
3922 //*************************************************************************************************
3937 template< typename Type > // Data type of the sparse matrix
3939  CompressedMatrix<Type,true>::find( size_t i, size_t j ) const
3940 {
3941  const ConstIterator pos( lowerBound( i, j ) );
3942  if( pos != end_[j] && pos->index_ == i )
3943  return pos;
3944  else return end_[j];
3945 }
3947 //*************************************************************************************************
3948 
3949 
3950 //*************************************************************************************************
3964 template< typename Type > // Data type of the sparse matrix
3966  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j )
3967 {
3968  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
3969 }
3971 //*************************************************************************************************
3972 
3973 
3974 //*************************************************************************************************
3988 template< typename Type > // Data type of the sparse matrix
3990  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j ) const
3991 {
3992  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3993  return std::lower_bound( begin_[j], end_[j], i, FindIndex() );
3994 }
3996 //*************************************************************************************************
3997 
3998 
3999 //*************************************************************************************************
4013 template< typename Type > // Data type of the sparse matrix
4015  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j )
4016 {
4017  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
4018 }
4020 //*************************************************************************************************
4021 
4022 
4023 //*************************************************************************************************
4037 template< typename Type > // Data type of the sparse matrix
4039  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j ) const
4040 {
4041  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4042  return std::upper_bound( begin_[j], end_[j], i, FindIndex() );
4043 }
4045 //*************************************************************************************************
4046 
4047 
4048 
4049 
4050 //=================================================================================================
4051 //
4052 // LOW-LEVEL UTILITY FUNCTIONS
4053 //
4054 //=================================================================================================
4055 
4056 //*************************************************************************************************
4097 template< typename Type > // Data type of the sparse matrix
4098 inline void CompressedMatrix<Type,true>::append( size_t i, size_t j, const Type& value, bool check )
4099 {
4100  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
4101  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
4102  BLAZE_USER_ASSERT( end_[j] < end_[n_], "Not enough reserved space left" );
4103  BLAZE_USER_ASSERT( begin_[j] == end_[j] || i > ( end_[j]-1UL )->index_, "Index is not strictly increasing" );
4104 
4105  end_[j]->value_ = value;
4106 
4107  if( !check || !isDefault( end_[j]->value_ ) ) {
4108  end_[j]->index_ = i;
4109  ++end_[j];
4110  }
4111 }
4113 //*************************************************************************************************
4114 
4115 
4116 //*************************************************************************************************
4130 template< typename Type > // Data type of the sparse matrix
4131 inline void CompressedMatrix<Type,true>::finalize( size_t j )
4132 {
4133  BLAZE_USER_ASSERT( j < n_, "Invalid row access index" );
4134 
4135  begin_[j+1UL] = end_[j];
4136  if( j != n_-1UL )
4137  end_[j+1UL] = end_[j];
4138 }
4140 //*************************************************************************************************
4141 
4142 
4143 
4144 
4145 //=================================================================================================
4146 //
4147 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4148 //
4149 //=================================================================================================
4150 
4151 //*************************************************************************************************
4162 template< typename Type > // Data type of the sparse matrix
4163 template< typename Other > // Data type of the foreign expression
4164 inline bool CompressedMatrix<Type,true>::canAlias( const Other* alias ) const
4165 {
4166  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4167 }
4169 //*************************************************************************************************
4170 
4171 
4172 //*************************************************************************************************
4183 template< typename Type > // Data type of the sparse matrix
4184 template< typename Other > // Data type of the foreign expression
4185 inline bool CompressedMatrix<Type,true>::isAliased( const Other* alias ) const
4186 {
4187  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4188 }
4190 //*************************************************************************************************
4191 
4192 
4193 //*************************************************************************************************
4205 template< typename Type > // Data type of the sparse matrix
4206 template< typename MT // Type of the right-hand side dense matrix
4207  , bool SO > // Storage order of the right-hand side dense matrix
4208 inline void CompressedMatrix<Type,true>::assign( const DenseMatrix<MT,SO>& rhs )
4209 {
4210  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4211  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4212 
4213  size_t nonzeros( 0UL );
4214 
4215  for( size_t j=1UL; j<=n_; ++j )
4216  begin_[j] = end_[j] = end_[n_];
4217 
4218  for( size_t j=0UL; j<n_; ++j )
4219  {
4220  begin_[j] = end_[j] = begin_[0UL]+nonzeros;
4221 
4222  for( size_t i=0UL; i<m_; ++i )
4223  {
4224  if( nonzeros == capacity() ) {
4225  reserveElements( extendCapacity() );
4226  for( size_t k=j+1UL; k<=n_; ++k )
4227  begin_[k] = end_[k] = end_[n_];
4228  }
4229 
4230  end_[j]->value_ = (~rhs)(i,j);
4231 
4232  if( !isDefault( end_[j]->value_ ) ) {
4233  end_[j]->index_ = i;
4234  ++end_[j];
4235  ++nonzeros;
4236  }
4237  }
4238  }
4239 
4240  begin_[n_] = begin_[0UL]+nonzeros;
4241 }
4243 //*************************************************************************************************
4244 
4245 
4246 //*************************************************************************************************
4258 template< typename Type > // Data type of the sparse matrix
4259 template< typename MT > // Type of the right-hand side sparse matrix
4260 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,true>& rhs )
4261 {
4262  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4263  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4264  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4265 
4266  for( size_t j=0UL; j<(~rhs).columns(); ++j ) {
4267  begin_[j+1UL] = end_[j] = std::copy( (~rhs).begin(j), (~rhs).end(j), begin_[j] );
4268  }
4269 }
4271 //*************************************************************************************************
4272 
4273 
4274 //*************************************************************************************************
4286 template< typename Type > // Data type of the sparse matrix
4287 template< typename MT > // Type of the right-hand side sparse matrix
4288 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,false>& rhs )
4289 {
4290  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4291  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4292  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4293 
4294  typedef typename MT::ConstIterator RhsIterator;
4295 
4296  // Counting the number of elements per column
4297  std::vector<size_t> columnLengths( n_, 0UL );
4298  for( size_t i=0UL; i<m_; ++i ) {
4299  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4300  ++columnLengths[element->index()];
4301  }
4302 
4303  // Resizing the sparse matrix
4304  for( size_t j=0UL; j<n_; ++j ) {
4305  begin_[j+1UL] = end_[j+1UL] = begin_[j] + columnLengths[j];
4306  }
4307 
4308  // Appending the elements to the columns of the sparse matrix
4309  for( size_t i=0UL; i<m_; ++i ) {
4310  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4311  append( i, element->index(), element->value() );
4312  }
4313 }
4315 //*************************************************************************************************
4316 
4317 
4318 //*************************************************************************************************
4330 template< typename Type > // Data type of the sparse matrix
4331 template< typename MT // Type of the right-hand side dense matrix
4332  , bool SO > // Storage order of the right-hand side dense matrix
4333 inline void CompressedMatrix<Type,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
4334 {
4335  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4336  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4337 
4338  CompressedMatrix tmp( *this + (~rhs) );
4339  swap( tmp );
4340 }
4342 //*************************************************************************************************
4343 
4344 
4345 //*************************************************************************************************
4357 template< typename Type > // Data type of the sparse matrix
4358 template< typename MT // Type of the right-hand side sparse matrix
4359  , bool SO > // Storage order of the right-hand side sparse matrix
4360 inline void CompressedMatrix<Type,true>::addAssign( const SparseMatrix<MT,SO>& rhs )
4361 {
4362  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4363  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4364 
4365  CompressedMatrix tmp( *this + (~rhs) );
4366  swap( tmp );
4367 }
4369 //*************************************************************************************************
4370 
4371 
4372 //*************************************************************************************************
4384 template< typename Type > // Data type of the sparse matrix
4385 template< typename MT // Type of the right-hand side dense matrix
4386  , bool SO > // Storage order of the right-hand side dense matrix
4387 inline void CompressedMatrix<Type,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
4388 {
4389  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4390  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4391 
4392  CompressedMatrix tmp( *this - (~rhs) );
4393  swap( tmp );
4394 }
4396 //*************************************************************************************************
4397 
4398 
4399 //*************************************************************************************************
4411 template< typename Type > // Data type of the sparse matrix
4412 template< typename MT // Type of the right-hand side sparse matrix
4413  , bool SO > // Storage order of the right-hand side sparse matrix
4414 inline void CompressedMatrix<Type,true>::subAssign( const SparseMatrix<MT,SO>& rhs )
4415 {
4416  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4417  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4418 
4419  CompressedMatrix tmp( *this - (~rhs) );
4420  swap( tmp );
4421 }
4423 //*************************************************************************************************
4424 
4425 
4426 
4427 
4428 
4429 
4430 
4431 
4432 //=================================================================================================
4433 //
4434 // COMPRESSEDMATRIX OPERATORS
4435 //
4436 //=================================================================================================
4437 
4438 //*************************************************************************************************
4441 template< typename Type, bool SO >
4442 inline void reset( CompressedMatrix<Type,SO>& m );
4443 
4444 template< typename Type, bool SO >
4445 inline void clear( CompressedMatrix<Type,SO>& m );
4446 
4447 template< typename Type, bool SO >
4448 inline bool isDefault( const CompressedMatrix<Type,SO>& m );
4449 
4450 template< typename Type, bool SO >
4451 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) /* throw() */;
4453 //*************************************************************************************************
4454 
4455 
4456 //*************************************************************************************************
4463 template< typename Type // Data type of the sparse matrix
4464  , bool SO > // Storage order
4465 inline void reset( CompressedMatrix<Type,SO>& m )
4466 {
4467  m.reset();
4468 }
4469 //*************************************************************************************************
4470 
4471 
4472 //*************************************************************************************************
4479 template< typename Type // Data type of the sparse matrix
4480  , bool SO > // Storage order
4481 inline void clear( CompressedMatrix<Type,SO>& m )
4482 {
4483  m.clear();
4484 }
4485 //*************************************************************************************************
4486 
4487 
4488 //*************************************************************************************************
4506 template< typename Type // Data type of the sparse matrix
4507  , bool SO > // Storage order
4508 inline bool isDefault( const CompressedMatrix<Type,SO>& m )
4509 {
4511 
4512  if( SO == rowMajor ) {
4513  for( size_t i=0UL; i<m.rows(); ++i ) {
4514  for( ConstIterator element=m.begin(i); element!=m.end(i); ++element )
4515  if( !isDefault( element->value() ) ) return false;
4516  }
4517  }
4518  else {
4519  for( size_t j=0UL; j<m.columns(); ++j ) {
4520  for( ConstIterator element=m.begin(j); element!=m.end(j); ++element )
4521  if( !isDefault( element->value() ) ) return false;
4522  }
4523  }
4524 
4525  return true;
4526 }
4527 //*************************************************************************************************
4528 
4529 
4530 //*************************************************************************************************
4539 template< typename Type // Data type of the sparse matrix
4540  , bool SO > // Storage order
4541 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) /* throw() */
4542 {
4543  a.swap( b );
4544 }
4545 //*************************************************************************************************
4546 
4547 
4548 
4549 
4550 //=================================================================================================
4551 //
4552 // ISRESIZABLE SPECIALIZATIONS
4553 //
4554 //=================================================================================================
4555 
4556 //*************************************************************************************************
4558 template< typename T, bool SO >
4559 struct IsResizable< CompressedMatrix<T,SO> > : public TrueType
4560 {
4561  enum { value = 1 };
4562  typedef TrueType Type;
4563 };
4564 
4565 template< typename T, bool SO >
4566 struct IsResizable< const CompressedMatrix<T,SO> > : public TrueType
4567 {
4568  enum { value = 1 };
4569  typedef TrueType Type;
4570 };
4571 
4572 template< typename T, bool SO >
4573 struct IsResizable< volatile CompressedMatrix<T,SO> > : public TrueType
4574 {
4575  enum { value = 1 };
4576  typedef TrueType Type;
4577 };
4578 
4579 template< typename T, bool SO >
4580 struct IsResizable< const volatile CompressedMatrix<T,SO> > : public TrueType
4581 {
4582  enum { value = 1 };
4583  typedef TrueType Type;
4584 };
4586 //*************************************************************************************************
4587 
4588 
4589 
4590 
4591 //=================================================================================================
4592 //
4593 // ADDTRAIT SPECIALIZATIONS
4594 //
4595 //=================================================================================================
4596 
4597 //*************************************************************************************************
4599 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4600 struct AddTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4601 {
4602  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4603 };
4604 
4605 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4606 struct AddTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4607 {
4608  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
4609 };
4610 
4611 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4612 struct AddTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4613 {
4614  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4615 };
4616 
4617 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4618 struct AddTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4619 {
4620  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
4621 };
4622 
4623 template< typename T1, bool SO, typename T2 >
4624 struct AddTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4625 {
4626  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4627 };
4628 
4629 template< typename T1, bool SO1, typename T2, bool SO2 >
4630 struct AddTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4631 {
4632  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4633 };
4634 
4635 template< typename T1, bool SO, typename T2 >
4636 struct AddTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4637 {
4638  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4639 };
4640 
4641 template< typename T1, bool SO1, typename T2, bool SO2 >
4642 struct AddTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4643 {
4644  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4645 };
4646 
4647 template< typename T1, bool SO, typename T2 >
4648 struct AddTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4649 {
4650  typedef CompressedMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4651 };
4652 
4653 template< typename T1, bool SO1, typename T2, bool SO2 >
4654 struct AddTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4655 {
4656  typedef CompressedMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4657 };
4659 //*************************************************************************************************
4660 
4661 
4662 
4663 
4664 //=================================================================================================
4665 //
4666 // SUBTRAIT SPECIALIZATIONS
4667 //
4668 //=================================================================================================
4669 
4670 //*************************************************************************************************
4672 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4673 struct SubTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4674 {
4675  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4676 };
4677 
4678 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4679 struct SubTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4680 {
4681  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
4682 };
4683 
4684 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4685 struct SubTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4686 {
4687  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4688 };
4689 
4690 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4691 struct SubTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4692 {
4693  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
4694 };
4695 
4696 template< typename T1, bool SO, typename T2 >
4697 struct SubTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4698 {
4699  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4700 };
4701 
4702 template< typename T1, bool SO1, typename T2, bool SO2 >
4703 struct SubTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4704 {
4705  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , false > Type;
4706 };
4707 
4708 template< typename T1, bool SO, typename T2 >
4709 struct SubTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4710 {
4711  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4712 };
4713 
4714 template< typename T1, bool SO1, typename T2, bool SO2 >
4715 struct SubTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4716 {
4717  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , false > Type;
4718 };
4719 
4720 template< typename T1, bool SO, typename T2 >
4721 struct SubTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4722 {
4723  typedef CompressedMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4724 };
4725 
4726 template< typename T1, bool SO1, typename T2, bool SO2 >
4727 struct SubTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4728 {
4729  typedef CompressedMatrix< typename SubTrait<T1,T2>::Type , false > Type;
4730 };
4732 //*************************************************************************************************
4733 
4734 
4735 
4736 
4737 //=================================================================================================
4738 //
4739 // MULTTRAIT SPECIALIZATIONS
4740 //
4741 //=================================================================================================
4742 
4743 //*************************************************************************************************
4745 template< typename T1, bool SO, typename T2 >
4746 struct MultTrait< CompressedMatrix<T1,SO>, T2 >
4747 {
4748  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
4750 };
4751 
4752 template< typename T1, typename T2, bool SO >
4753 struct MultTrait< T1, CompressedMatrix<T2,SO> >
4754 {
4755  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
4757 };
4758 
4759 template< typename T1, bool SO, typename T2, size_t N >
4760 struct MultTrait< CompressedMatrix<T1,SO>, StaticVector<T2,N,false> >
4761 {
4762  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4763 };
4764 
4765 template< typename T1, size_t N, typename T2, bool SO >
4766 struct MultTrait< StaticVector<T1,N,true>, CompressedMatrix<T2,SO> >
4767 {
4768  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4769 };
4770 
4771 template< typename T1, bool SO, typename T2, size_t N >
4772 struct MultTrait< CompressedMatrix<T1,SO>, HybridVector<T2,N,false> >
4773 {
4774  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4775 };
4776 
4777 template< typename T1, size_t N, typename T2, bool SO >
4778 struct MultTrait< HybridVector<T1,N,true>, CompressedMatrix<T2,SO> >
4779 {
4780  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4781 };
4782 
4783 template< typename T1, bool SO, typename T2 >
4784 struct MultTrait< CompressedMatrix<T1,SO>, DynamicVector<T2,false> >
4785 {
4786  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4787 };
4788 
4789 template< typename T1, typename T2, bool SO >
4790 struct MultTrait< DynamicVector<T1,true>, CompressedMatrix<T2,SO> >
4791 {
4792  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4793 };
4794 
4795 template< typename T1, bool SO, typename T2 >
4796 struct MultTrait< CompressedMatrix<T1,SO>, CompressedVector<T2,false> >
4797 {
4798  typedef CompressedVector< typename MultTrait<T1,T2>::Type, false > Type;
4799 };
4800 
4801 template< typename T1, typename T2, bool SO >
4802 struct MultTrait< CompressedVector<T1,true>, CompressedMatrix<T2,SO> >
4803 {
4804  typedef CompressedVector< typename MultTrait<T1,T2>::Type, true > Type;
4805 };
4806 
4807 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4808 struct MultTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4809 {
4810  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4811 };
4812 
4813 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4814 struct MultTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4815 {
4816  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4817 };
4818 
4819 template< typename T1, bool SO1, typename T2, bool SO2 >
4820 struct MultTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4821 {
4822  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4823 };
4824 
4825 template< typename T1, bool SO1, typename T2, bool SO2 >
4826 struct MultTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4827 {
4828  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4829 };
4830 
4831 template< typename T1, bool SO1, typename T2, bool SO2 >
4832 struct MultTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4833 {
4834  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4835 };
4837 //*************************************************************************************************
4838 
4839 
4840 
4841 
4842 //=================================================================================================
4843 //
4844 // DIVTRAIT SPECIALIZATIONS
4845 //
4846 //=================================================================================================
4847 
4848 //*************************************************************************************************
4850 template< typename T1, bool SO, typename T2 >
4851 struct DivTrait< CompressedMatrix<T1,SO>, T2 >
4852 {
4853  typedef CompressedMatrix< typename DivTrait<T1,T2>::Type, SO > Type;
4855 };
4857 //*************************************************************************************************
4858 
4859 
4860 
4861 
4862 //=================================================================================================
4863 //
4864 // MATHTRAIT SPECIALIZATIONS
4865 //
4866 //=================================================================================================
4867 
4868 //*************************************************************************************************
4870 template< typename T1, bool SO, typename T2 >
4871 struct MathTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4872 {
4873  typedef CompressedMatrix< typename MathTrait<T1,T2>::HighType, SO > HighType;
4874  typedef CompressedMatrix< typename MathTrait<T1,T2>::LowType , SO > LowType;
4875 };
4877 //*************************************************************************************************
4878 
4879 
4880 
4881 
4882 //=================================================================================================
4883 //
4884 // SUBMATRIXTRAIT SPECIALIZATIONS
4885 //
4886 //=================================================================================================
4887 
4888 //*************************************************************************************************
4890 template< typename T1, bool SO >
4891 struct SubmatrixTrait< CompressedMatrix<T1,SO> >
4892 {
4893  typedef CompressedMatrix<T1,SO> Type;
4894 };
4896 //*************************************************************************************************
4897 
4898 
4899 
4900 
4901 //=================================================================================================
4902 //
4903 // ROWTRAIT SPECIALIZATIONS
4904 //
4905 //=================================================================================================
4906 
4907 //*************************************************************************************************
4909 template< typename T1, bool SO >
4910 struct RowTrait< CompressedMatrix<T1,SO> >
4911 {
4912  typedef CompressedVector<T1,true> Type;
4913 };
4915 //*************************************************************************************************
4916 
4917 
4918 
4919 
4920 //=================================================================================================
4921 //
4922 // COLUMNTRAIT SPECIALIZATIONS
4923 //
4924 //=================================================================================================
4925 
4926 //*************************************************************************************************
4928 template< typename T1, bool SO >
4929 struct ColumnTrait< CompressedMatrix<T1,SO> >
4930 {
4931  typedef CompressedVector<T1,false> Type;
4932 };
4934 //*************************************************************************************************
4935 
4936 } // namespace blaze
4937 
4938 #endif
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
Definition: Const.h:116
Pointer difference type of the Blaze library.
size_t rows() const
Returns the current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:1100
void reserveElements(size_t nonzeros)
Reserving the specified number of sparse matrix elements.
Definition: CompressedMatrix.h:1744
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:98
Constraint on the data type.
Iterator * end_
Pointers one past the last non-zero element of each row.
Definition: CompressedMatrix.h:390
Header file for mathematical functions.
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4512
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
MatrixAccessProxy< This > Reference
Reference to a sparse matrix value.
Definition: CompressedMatrix.h:251
Compile time type selection.The If class template selects one of the two given types T2 and T3 depend...
Definition: If.h:112
Header file for the subtraction trait.
const Type & ConstReference
Reference to a constant sparse matrix value.
Definition: CompressedMatrix.h:252
const bool defaultStorageOrder
The default storage order for all matrices of the Blaze library.This value specifies the default stor...
Definition: StorageOrder.h:56
Header file for the row trait.
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:446
Header file for the IsSparseMatrix type trait.
CompressedMatrix()
The default constructor for CompressedMatrix.
Definition: CompressedMatrix.h:434
bool isDefault(const DynamicMatrix< Type, SO > &m)
Returns whether the given dense matrix is in default state.
Definition: DynamicMatrix.h:4555
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:196
size_t extendCapacity() const
Calculating a new matrix capacity.
Definition: CompressedMatrix.h:1724
const blaze::Null NULL
Global NULL pointer.This instance of the Null class replaces the NULL macro to ensure a type-safe NUL...
Definition: Null.h:300
void clear()
Clearing the sparse matrix.
Definition: CompressedMatrix.h:1241
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:248
Header file for a safe C++ NULL pointer implementation.
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2369
CompressedMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:246
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.In case the given data type is a volatile-qualified type, a compilation error is created.
Definition: Volatile.h:116
~CompressedMatrix()
The destructor for CompressedMatrix.
Definition: CompressedMatrix.h:620
Access proxy for sparse, matrices.The MatrixAccessProxy provides safe access to the elements of a no...
Definition: MatrixAccessProxy.h:86
bool isAliased(const Other *alias) const
Returns whether the matrix is aliased with the given address alias.
Definition: CompressedMatrix.h:2067
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:392
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:249
void clear(DynamicMatrix< Type, SO > &m)
Clearing the given dense matrix.
Definition: DynamicMatrix.h:4528
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:104
Constraint on the data type.
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: CompressedMatrix.h:1163
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:2513
Header file for the SparseMatrix base class.
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:388
Header file for the floating point precision of the Blaze library.
void reserve(size_t nonzeros)
Setting the minimum capacity of the sparse matrix.
Definition: CompressedMatrix.h:1515
void reset()
Reset to the default initial values.
Definition: CompressedMatrix.h:1203
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:250
Header file for the ValueIndexPair class.
Header file for the multiplication trait.
Header file for the If class template.
Header file for the IsFloatingPoint type trait.
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b)
Swapping the contents of two sparse matrices.
Definition: CompressedMatrix.h:4541
Header file for the MatrixAccessProxy class.
Header file for all forward declarations of the math module.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2379
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:116
void erase(size_t i, size_t j)
Erasing an element from the sparse matrix.
Definition: CompressedMatrix.h:1349
Iterator * end_
Pointers one past the last non-zero element of each column.
Definition: CompressedMatrix.h:2515
#define BLAZE_CONSTRAINT_MUST_HAVE_SAME_SIZE(T1, T2)
Constraint on the size of two data types.In case the types T1 and T2 don&#39;t have the same size...
Definition: SameSize.h:78
ValueIndexPair< Type > ElementBase
Base class for the sparse matrix element.
Definition: CompressedMatrix.h:200
void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:179
Constraint on the data type.
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2512
Header file for the default storage order for all vectors of the Blaze library.
Iterator insert(size_t i, size_t j, const Type &value)
Inserting an element into the sparse matrix.
Definition: CompressedMatrix.h:1266
Compile time check for floating point data types.This type trait tests whether or not the given templ...
Definition: IsFloatingPoint.h:94
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2377
void subAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the subtraction assignment of a dense matrix.
Definition: CompressedMatrix.h:2263
const size_t m_
The number of rows of the submatrix.
Definition: SparseSubmatrix.h:2655
Header file for the EnableIf class template.
void swap(CompressedMatrix &sm)
Swapping the contents of two sparse matrices.
Definition: CompressedMatrix.h:1703
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:254
Header file for the equal shim.
ColumnIterator< const MT > ConstIterator
Iterator over constant elements.
Definition: DenseColumn.h:1972
size_t capacity() const
Returns the maximum capacity of the sparse matrix.
Definition: CompressedMatrix.h:1128
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the sparse matrix.
Definition: CompressedMatrix.h:1434
Header file for the IsNumeric type trait.
CompressedMatrix & operator=(const CompressedMatrix &rhs)
Copy assignment operator for CompressedMatrix.
Definition: CompressedMatrix.h:833
Reference operator()(size_t i, size_t j)
2D-access to the sparse matrix elements.
Definition: CompressedMatrix.h:646
Header file for run time assertion macros.
Header file for the addition trait.
Iterator end(size_t i)
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:761
CompressedMatrix & transpose()
Transposing the matrix.
Definition: CompressedMatrix.h:1641
Header file for the division trait.
void swap(DynamicMatrix< Type, SO > &a, DynamicMatrix< Type, SO > &b)
Swapping the contents of two matrices.
Definition: DynamicMatrix.h:4584
void addAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a matrix to a matrix.
Definition: Matrix.h:209
void trim()
Removing all excessive capacity from all rows/columns.
Definition: CompressedMatrix.h:1602
Header file for the submatrix trait.
Constraint on the data type.
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
#define BLAZE_CONSTRAINT_MUST_BE_NUMERIC_TYPE(T)
Constraint on the data type.In case the given data type T is not a numeric (integral or floating poin...
Definition: Numeric.h:79
void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:239
const VT::ElementType max(const SparseVector< VT, TF > &sv)
Returns the largest element of the sparse vector.
Definition: SparseVector.h:405
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:116
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2378
Header file for the column trait.
Header file for the isDefault shim.
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:85
size_t columns() const
Returns the current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:1114
Constraint on the data type.
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:245
Iterator * begin_
Pointers to the first non-zero element of each column.
Definition: CompressedMatrix.h:2514
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2511
void assign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the assignment of a row-major dense matrix.
Definition: CompressedMatrix.h:2089
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:253
void append(size_t i, size_t j, const Type &value, bool check=false)
Appending an element to the specified row/column of the sparse matrix.
Definition: CompressedMatrix.h:1983
void finalize(size_t i)
Finalizing the element insertion of a row/column.
Definition: CompressedMatrix.h:2015
bool canAlias(const Other *alias) const
Returns whether the matrix can alias with the given address alias.
Definition: CompressedMatrix.h:2047
Base template for the DivTrait class.
Definition: DivTrait.h:141
CompressedMatrix< Type, SO > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:244
Iterator find(size_t i, size_t j)
Searches for a specific matrix element.
Definition: CompressedMatrix.h:1793
Header file for the mathematical trait.
Iterator * begin_
Pointers to the first non-zero element of each row.
Definition: CompressedMatrix.h:389
Index-value-pair for sparse vectors and matrices.The ValueIndexPair class represents a single index-v...
Definition: ValueIndexPair.h:69
Constraint on the size of two data types.
void addAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the addition assignment of a dense matrix.
Definition: CompressedMatrix.h:2211
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:247
Iterator lowerBound(size_t i, size_t j)
Returns an iterator to the first index not less then the given index.
Definition: CompressedMatrix.h:1846
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:2517
Iterator upperBound(size_t i, size_t j)
Returns an iterator to the first index greater then the given index.
Definition: CompressedMatrix.h:1897
const size_t n_
The number of columns of the submatrix.
Definition: SparseSubmatrix.h:2656
size_t columns(const Matrix< MT, SO > &m)
Returns the current number of columns of the matrix.
Definition: Matrix.h:154
Header file for basic type definitions.
ConstIterator cbegin(size_t i) const
Returns an iterator to the first non-zero element of row/column i.
Definition: CompressedMatrix.h:739
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2376
const VT::ElementType min(const SparseVector< VT, TF > &sv)
Returns the smallest element of the sparse vector.
Definition: SparseVector.h:348
SelectType< useConst, ConstIterator, ColumnIterator< MT > >::Type Iterator
Iterator over non-constant elements.
Definition: DenseColumn.h:1980
boost::true_type TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:387
ConstIterator cend(size_t i) const
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:805
Header file for the IsResizable type trait.
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:386
size_t rows(const Matrix< MT, SO > &m)
Returns the current number of rows of the matrix.
Definition: Matrix.h:138
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Iterator begin(size_t i)
Returns an iterator to the first non-zero element of row/column i.
Definition: CompressedMatrix.h:695