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>
49 #include <blaze/math/Forward.h>
50 #include <blaze/math/Functions.h>
51 #include <blaze/math/shims/Equal.h>
69 #include <blaze/util/Assert.h>
76 #include <blaze/util/EnableIf.h>
77 #include <blaze/util/Memory.h>
78 #include <blaze/util/mpl/If.h>
79 #include <blaze/util/Null.h>
80 #include <blaze/util/Types.h>
83 
84 
85 namespace blaze {
86 
87 //=================================================================================================
88 //
89 // CLASS DEFINITION
90 //
91 //=================================================================================================
92 
93 //*************************************************************************************************
203 template< typename Type // Data type of the sparse matrix
204  , bool SO = defaultStorageOrder > // Storage order
205 class CompressedMatrix : public SparseMatrix< CompressedMatrix<Type,SO>, SO >
206 {
207  private:
208  //**Type definitions****************************************************************************
210  //**********************************************************************************************
211 
212  //**Private class Element***********************************************************************
216  struct Element : public ElementBase
217  {
218  // This operator is required due to a bug in all versions of the the MSVC compiler.
219  // A simple 'using ElementBase::operator=;' statement results in ambiguity problems.
220  template< typename Other >
221  inline Element& operator=( const Other& rhs )
222  {
223  ElementBase::operator=( rhs );
224  return *this;
225  }
226 
227  friend class CompressedMatrix;
228  };
230  //**********************************************************************************************
231 
232  //**Private class FindIndex*********************************************************************
236  struct FindIndex : public std::binary_function<Element,size_t,bool>
237  {
238  inline bool operator()( const Element& element, size_t index ) const {
239  return element.index() < index;
240  }
241  inline bool operator()( size_t index, const Element& element ) const {
242  return index < element.index();
243  }
244  inline bool operator()( const Element& element1, const Element& element2 ) const {
245  return element1.index() < element2.index();
246  }
247  };
249  //**********************************************************************************************
250 
251  public:
252  //**Type definitions****************************************************************************
254  typedef This ResultType;
257  typedef Type ElementType;
258  typedef const Type& ReturnType;
259  typedef const This& CompositeType;
261  typedef const Type& ConstReference;
262  typedef Element* Iterator;
263  typedef const Element* ConstIterator;
264  //**********************************************************************************************
265 
266  //**Rebind struct definition********************************************************************
269  template< typename ET > // Data type of the other matrix
270  struct Rebind {
272  };
273  //**********************************************************************************************
274 
275  //**Compilation flags***************************************************************************
277 
280  enum { smpAssignable = !IsSMPAssignable<Type>::value };
281  //**********************************************************************************************
282 
283  //**Constructors********************************************************************************
286  explicit inline CompressedMatrix();
287  explicit inline CompressedMatrix( size_t m, size_t n );
288  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
289  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
290  inline CompressedMatrix( const CompressedMatrix& sm );
291  template< typename MT, bool SO2 > inline CompressedMatrix( const DenseMatrix<MT,SO2>& dm );
292  template< typename MT, bool SO2 > inline CompressedMatrix( const SparseMatrix<MT,SO2>& sm );
294  //**********************************************************************************************
295 
296  //**Destructor**********************************************************************************
299  inline ~CompressedMatrix();
301  //**********************************************************************************************
302 
303  //**Data access functions***********************************************************************
306  inline Reference operator()( size_t i, size_t j );
307  inline ConstReference operator()( size_t i, size_t j ) const;
308  inline Iterator begin ( size_t i );
309  inline ConstIterator begin ( size_t i ) const;
310  inline ConstIterator cbegin( size_t i ) const;
311  inline Iterator end ( size_t i );
312  inline ConstIterator end ( size_t i ) const;
313  inline ConstIterator cend ( size_t i ) const;
315  //**********************************************************************************************
316 
317  //**Assignment operators************************************************************************
320  inline CompressedMatrix& operator= ( const CompressedMatrix& rhs );
321  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO2>& rhs );
322  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO2>& rhs );
323  template< typename MT, bool SO2 > inline CompressedMatrix& operator+=( const Matrix<MT,SO2>& rhs );
324  template< typename MT, bool SO2 > inline CompressedMatrix& operator-=( const Matrix<MT,SO2>& rhs );
325  template< typename MT, bool SO2 > inline CompressedMatrix& operator*=( const Matrix<MT,SO2>& rhs );
326 
327  template< typename Other >
328  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
329  operator*=( Other rhs );
330 
331  template< typename Other >
332  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
333  operator/=( Other rhs );
335  //**********************************************************************************************
336 
337  //**Utility functions***************************************************************************
340  inline size_t rows() const;
341  inline size_t columns() const;
342  inline size_t capacity() const;
343  inline size_t capacity( size_t i ) const;
344  inline size_t nonZeros() const;
345  inline size_t nonZeros( size_t i ) const;
346  inline void reset();
347  inline void reset( size_t i );
348  inline void clear();
349  inline Iterator set ( size_t i, size_t j, const Type& value );
350  inline Iterator insert ( size_t i, size_t j, const Type& value );
351  inline void erase ( size_t i, size_t j );
352  inline Iterator erase ( size_t i, Iterator pos );
353  inline Iterator erase ( size_t i, Iterator first, Iterator last );
354  void resize ( size_t m, size_t n, bool preserve=true );
355  inline void reserve( size_t nonzeros );
356  void reserve( size_t i, size_t nonzeros );
357  inline void trim ();
358  inline void trim ( size_t i );
359  inline CompressedMatrix& transpose();
360  template< typename Other > inline CompressedMatrix& scale( const Other& scalar );
361  template< typename Other > inline CompressedMatrix& scaleDiagonal( Other scalar );
362  inline void swap( CompressedMatrix& sm ) /* throw() */;
364  //**********************************************************************************************
365 
366  //**Lookup functions****************************************************************************
369  inline Iterator find ( size_t i, size_t j );
370  inline ConstIterator find ( size_t i, size_t j ) const;
371  inline Iterator lowerBound( size_t i, size_t j );
372  inline ConstIterator lowerBound( size_t i, size_t j ) const;
373  inline Iterator upperBound( size_t i, size_t j );
374  inline ConstIterator upperBound( size_t i, size_t j ) const;
376  //**********************************************************************************************
377 
378  //**Low-level utility functions*****************************************************************
381  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
382  inline void finalize( size_t i );
384  //**********************************************************************************************
385 
386  //**Expression template evaluation functions****************************************************
389  template< typename Other > inline bool canAlias ( const Other* alias ) const;
390  template< typename Other > inline bool isAliased( const Other* alias ) const;
391 
392  inline bool canSMPAssign() const;
393 
394  template< typename MT, bool SO2 > inline void assign ( const DenseMatrix<MT,SO2>& rhs );
395  template< typename MT > inline void assign ( const SparseMatrix<MT,SO>& rhs );
396  template< typename MT > inline void assign ( const SparseMatrix<MT,!SO>& rhs );
397  template< typename MT, bool SO2 > inline void addAssign( const DenseMatrix<MT,SO2>& rhs );
398  template< typename MT, bool SO2 > inline void addAssign( const SparseMatrix<MT,SO2>& rhs );
399  template< typename MT, bool SO2 > inline void subAssign( const DenseMatrix<MT,SO2>& rhs );
400  template< typename MT, bool SO2 > inline void subAssign( const SparseMatrix<MT,SO2>& rhs );
402  //**********************************************************************************************
403 
404  private:
405  //**Utility functions***************************************************************************
408  Iterator insert( Iterator pos, size_t i, size_t j, const Type& value );
409  inline size_t extendCapacity() const;
410  void reserveElements( size_t nonzeros );
412  //**********************************************************************************************
413 
414  //**Member variables****************************************************************************
417  size_t m_;
418  size_t n_;
419  size_t capacity_;
422 
423  static const Type zero_;
424 
425  //**********************************************************************************************
426 
427  //**Compile time checks*************************************************************************
435  //**********************************************************************************************
436 };
437 //*************************************************************************************************
438 
439 
440 
441 
442 //=================================================================================================
443 //
444 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
445 //
446 //=================================================================================================
447 
448 template< typename Type, bool SO >
449 const Type CompressedMatrix<Type,SO>::zero_ = Type();
450 
451 
452 
453 
454 //=================================================================================================
455 //
456 // CONSTRUCTORS
457 //
458 //=================================================================================================
459 
460 //*************************************************************************************************
463 template< typename Type // Data type of the sparse matrix
464  , bool SO > // Storage order
466  : m_ ( 0UL ) // The current number of rows of the sparse matrix
467  , n_ ( 0UL ) // The current number of columns of the sparse matrix
468  , capacity_( 0UL ) // The current capacity of the pointer array
469  , begin_( new Iterator[2] ) // Pointers to the first non-zero element of each row
470  , end_ ( begin_+1 ) // Pointers one past the last non-zero element of each row
471 {
472  begin_[0] = end_[0] = NULL;
473 }
474 //*************************************************************************************************
475 
476 
477 //*************************************************************************************************
485 template< typename Type // Data type of the sparse matrix
486  , bool SO > // Storage order
488  : m_ ( m ) // The current number of rows of the sparse matrix
489  , n_ ( n ) // The current number of columns of the sparse matrix
490  , capacity_( m ) // The current capacity of the pointer array
491  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
492  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
493 {
494  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
495  begin_[i] = NULL;
496 }
497 //*************************************************************************************************
498 
499 
500 //*************************************************************************************************
509 template< typename Type // Data type of the sparse matrix
510  , bool SO > // Storage order
511 inline CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
512  : m_ ( m ) // The current number of rows of the sparse matrix
513  , n_ ( n ) // The current number of columns of the sparse matrix
514  , capacity_( m ) // The current capacity of the pointer array
515  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
516  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
517 {
518  begin_[0UL] = allocate<Element>( nonzeros );
519  for( size_t i=1UL; i<(2UL*m_+1UL); ++i )
520  begin_[i] = begin_[0UL];
521  end_[m_] = begin_[0UL]+nonzeros;
522 }
523 //*************************************************************************************************
524 
525 
526 //*************************************************************************************************
535 template< typename Type // Data type of the sparse matrix
536  , bool SO > // Storage order
537 CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
538  : m_ ( m ) // The current number of rows of the sparse matrix
539  , n_ ( n ) // The current number of columns of the sparse matrix
540  , capacity_( m ) // The current capacity of the pointer array
541  , begin_( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
542  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
543 {
544  BLAZE_USER_ASSERT( nonzeros.size() == m, "Size of capacity vector and number of rows don't match" );
545 
546  size_t newCapacity( 0UL );
547  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
548  newCapacity += *it;
549 
550  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
551  for( size_t i=0UL; i<m_; ++i ) {
552  begin_[i+1UL] = end_[i+1UL] = begin_[i] + nonzeros[i];
553  }
554 }
555 //*************************************************************************************************
556 
557 
558 //*************************************************************************************************
563 template< typename Type // Data type of the sparse matrix
564  , bool SO > // Storage order
566  : m_ ( sm.m_ ) // The current number of rows of the sparse matrix
567  , n_ ( sm.n_ ) // The current number of columns of the sparse matrix
568  , capacity_( sm.m_ ) // The current capacity of the pointer array
569  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
570  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
571 {
572  const size_t nonzeros( sm.nonZeros() );
573 
574  begin_[0UL] = allocate<Element>( nonzeros );
575  for( size_t i=0UL; i<m_; ++i )
576  begin_[i+1UL] = end_[i] = std::copy( sm.begin(i), sm.end(i), begin_[i] );
577  end_[m_] = begin_[0UL]+nonzeros;
578 }
579 //*************************************************************************************************
580 
581 
582 //*************************************************************************************************
587 template< typename Type // Data type of the sparse matrix
588  , bool SO > // Storage order
589 template< typename MT // Type of the foreign dense matrix
590  , bool SO2 > // Storage order of the foreign dense matrix
592  : m_ ( (~dm).rows() ) // The current number of rows of the sparse matrix
593  , n_ ( (~dm).columns() ) // The current number of columns of the sparse matrix
594  , capacity_( m_ ) // The current capacity of the pointer array
595  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
596  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
597 {
598  using blaze::assign;
599 
600  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
601  begin_[i] = NULL;
602 
603  assign( *this, ~dm );
604 }
605 //*************************************************************************************************
606 
607 
608 //*************************************************************************************************
613 template< typename Type // Data type of the sparse matrix
614  , bool SO > // Storage order
615 template< typename MT // Type of the foreign sparse matrix
616  , bool SO2 > // Storage order of the foreign sparse matrix
618  : m_ ( (~sm).rows() ) // The current number of rows of the sparse matrix
619  , n_ ( (~sm).columns() ) // The current number of columns of the sparse matrix
620  , capacity_( m_ ) // The current capacity of the pointer array
621  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
622  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
623 {
624  using blaze::assign;
625 
626  const size_t nonzeros( (~sm).nonZeros() );
627 
628  begin_[0UL] = allocate<Element>( nonzeros );
629  for( size_t i=0UL; i<m_; ++i )
630  begin_[i+1UL] = end_[i] = begin_[0UL];
631  end_[m_] = begin_[0UL]+nonzeros;
632 
633  assign( *this, ~sm );
634 }
635 //*************************************************************************************************
636 
637 
638 
639 
640 //=================================================================================================
641 //
642 // DESTRUCTOR
643 //
644 //=================================================================================================
645 
646 //*************************************************************************************************
649 template< typename Type // Data type of the sparse matrix
650  , bool SO > // Storage order
652 {
653  deallocate( begin_[0UL] );
654  delete [] begin_;
655 }
656 //*************************************************************************************************
657 
658 
659 
660 
661 //=================================================================================================
662 //
663 // DATA ACCESS FUNCTIONS
664 //
665 //=================================================================================================
666 
667 //*************************************************************************************************
674 template< typename Type // Data type of the sparse matrix
675  , bool SO > // Storage order
678 {
679  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
680  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
681 
682  return Reference( *this, i, j );
683 }
684 //*************************************************************************************************
685 
686 
687 //*************************************************************************************************
694 template< typename Type // Data type of the sparse matrix
695  , bool SO > // Storage order
697  CompressedMatrix<Type,SO>::operator()( size_t i, size_t j ) const
698 {
699  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
700  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
701 
702  const ConstIterator pos( lowerBound( i, j ) );
703 
704  if( pos == end_[i] || pos->index_ != j )
705  return zero_;
706  else
707  return pos->value_;
708 }
709 //*************************************************************************************************
710 
711 
712 //*************************************************************************************************
723 template< typename Type // Data type of the sparse matrix
724  , bool SO > // Storage order
727 {
728  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
729  return begin_[i];
730 }
731 //*************************************************************************************************
732 
733 
734 //*************************************************************************************************
745 template< typename Type // Data type of the sparse matrix
746  , bool SO > // Storage order
749 {
750  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
751  return begin_[i];
752 }
753 //*************************************************************************************************
754 
755 
756 //*************************************************************************************************
767 template< typename Type // Data type of the sparse matrix
768  , bool SO > // Storage order
771 {
772  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
773  return begin_[i];
774 }
775 //*************************************************************************************************
776 
777 
778 //*************************************************************************************************
789 template< typename Type // Data type of the sparse matrix
790  , bool SO > // Storage order
793 {
794  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
795  return end_[i];
796 }
797 //*************************************************************************************************
798 
799 
800 //*************************************************************************************************
811 template< typename Type // Data type of the sparse matrix
812  , bool SO > // Storage order
815 {
816  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
817  return end_[i];
818 }
819 //*************************************************************************************************
820 
821 
822 //*************************************************************************************************
833 template< typename Type // Data type of the sparse matrix
834  , bool SO > // Storage order
837 {
838  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
839  return end_[i];
840 }
841 //*************************************************************************************************
842 
843 
844 
845 
846 //=================================================================================================
847 //
848 // ASSIGNMENT OPERATORS
849 //
850 //=================================================================================================
851 
852 //*************************************************************************************************
861 template< typename Type // Data type of the sparse matrix
862  , bool SO > // Storage order
865 {
866  if( &rhs == this ) return *this;
867 
868  const size_t nonzeros( rhs.nonZeros() );
869 
870  if( rhs.m_ > capacity_ || nonzeros > capacity() )
871  {
872  Iterator* newBegin( new Iterator[2UL*rhs.m_+2UL] );
873  Iterator* newEnd ( newBegin+(rhs.m_+1UL) );
874 
875  newBegin[0UL] = allocate<Element>( nonzeros );
876  for( size_t i=0UL; i<rhs.m_; ++i ) {
877  newBegin[i+1UL] = newEnd[i] = std::copy( rhs.begin_[i], rhs.end_[i], newBegin[i] );
878  }
879  newEnd[rhs.m_] = newBegin[0UL]+nonzeros;
880 
881  std::swap( begin_, newBegin );
882  end_ = newEnd;
883  deallocate( newBegin[0UL] );
884  delete [] newBegin;
885  capacity_ = rhs.m_;
886  }
887  else {
888  for( size_t i=0UL; i<rhs.m_; ++i ) {
889  begin_[i+1UL] = end_[i] = std::copy( rhs.begin_[i], rhs.end_[i], begin_[i] );
890  }
891  }
892 
893  m_ = rhs.m_;
894  n_ = rhs.n_;
895 
896  return *this;
897 }
898 //*************************************************************************************************
899 
900 
901 //*************************************************************************************************
910 template< typename Type // Data type of the sparse matrix
911  , bool SO > // Storage order
912 template< typename MT // Type of the right-hand side dense matrix
913  , bool SO2 > // Storage order of the right-hand side dense matrix
916 {
917  using blaze::assign;
918 
919  if( (~rhs).canAlias( this ) ) {
920  CompressedMatrix tmp( ~rhs );
921  swap( tmp );
922  }
923  else {
924  resize( (~rhs).rows(), (~rhs).columns(), false );
925  assign( *this, ~rhs );
926  }
927 
928  return *this;
929 }
930 //*************************************************************************************************
931 
932 
933 //*************************************************************************************************
942 template< typename Type // Data type of the sparse matrix
943  , bool SO > // Storage order
944 template< typename MT // Type of the right-hand side sparse matrix
945  , bool SO2 > // Storage order of the right-hand side sparse matrix
948 {
949  using blaze::assign;
950 
951  if( (~rhs).canAlias( this ) ||
952  (~rhs).rows() > capacity_ ||
953  (~rhs).nonZeros() > capacity() ) {
954  CompressedMatrix tmp( ~rhs );
955  swap( tmp );
956  }
957  else {
958  resize( (~rhs).rows(), (~rhs).columns(), false );
959  reset();
960  assign( *this, ~rhs );
961  }
962 
963  return *this;
964 }
965 //*************************************************************************************************
966 
967 
968 //*************************************************************************************************
978 template< typename Type // Data type of the sparse matrix
979  , bool SO > // Storage order
980 template< typename MT // Type of the right-hand side matrix
981  , bool SO2 > // Storage order of the right-hand side matrix
984 {
985  using blaze::addAssign;
986 
987  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
988  throw std::invalid_argument( "Matrix sizes do not match" );
989 
990  addAssign( *this, ~rhs );
991  return *this;
992 }
993 //*************************************************************************************************
994 
995 
996 //*************************************************************************************************
1006 template< typename Type // Data type of the sparse matrix
1007  , bool SO > // Storage order
1008 template< typename MT // Type of the right-hand side matrix
1009  , bool SO2 > // Storage order of the right-hand side matrix
1011 {
1012  using blaze::subAssign;
1013 
1014  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
1015  throw std::invalid_argument( "Matrix sizes do not match" );
1016 
1017  subAssign( *this, ~rhs );
1018  return *this;
1019 }
1020 //*************************************************************************************************
1021 
1022 
1023 //*************************************************************************************************
1033 template< typename Type // Data type of the sparse matrix
1034  , bool SO > // Storage order
1035 template< typename MT // Type of the right-hand side matrix
1036  , bool SO2 > // Storage order of the right-hand side matrix
1039 {
1040  if( (~rhs).rows() != n_ )
1041  throw std::invalid_argument( "Matrix sizes do not match" );
1042 
1043  CompressedMatrix tmp( *this * (~rhs) );
1044  swap( tmp );
1045 
1046  return *this;
1047 }
1048 //*************************************************************************************************
1049 
1050 
1051 //*************************************************************************************************
1058 template< typename Type // Data type of the sparse matrix
1059  , bool SO > // Storage order
1060 template< typename Other > // Data type of the right-hand side scalar
1061 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,SO> >::Type&
1063 {
1064  for( size_t i=0UL; i<m_; ++i ) {
1065  const Iterator last( end(i) );
1066  for( Iterator element=begin(i); element!=last; ++element )
1067  element->value_ *= rhs;
1068  }
1069  return *this;
1070 }
1071 //*************************************************************************************************
1072 
1073 
1074 //*************************************************************************************************
1081 template< typename Type // Data type of the sparse matrix
1082  , bool SO > // Storage order
1083 template< typename Other > // Data type of the right-hand side scalar
1084 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,SO> >::Type&
1086 {
1087  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1088 
1089  typedef typename DivTrait<Type,Other>::Type DT;
1090  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
1091 
1092  // Depending on the two involved data types, an integer division is applied or a
1093  // floating point division is selected.
1095  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1096  for( size_t i=0UL; i<m_; ++i ) {
1097  const Iterator last( end(i) );
1098  for( Iterator element=begin(i); element!=last; ++element )
1099  element->value_ *= tmp;
1100  }
1101  }
1102  else {
1103  for( size_t i=0UL; i<m_; ++i ) {
1104  const Iterator last( end(i) );
1105  for( Iterator element=begin(i); element!=last; ++element )
1106  element->value_ /= rhs;
1107  }
1108  }
1109 
1110  return *this;
1111 }
1112 //*************************************************************************************************
1113 
1114 
1115 
1116 
1117 //=================================================================================================
1118 //
1119 // UTILITY FUNCTIONS
1120 //
1121 //=================================================================================================
1122 
1123 //*************************************************************************************************
1128 template< typename Type // Data type of the sparse matrix
1129  , bool SO > // Storage order
1130 inline size_t CompressedMatrix<Type,SO>::rows() const
1131 {
1132  return m_;
1133 }
1134 //*************************************************************************************************
1135 
1136 
1137 //*************************************************************************************************
1142 template< typename Type // Data type of the sparse matrix
1143  , bool SO > // Storage order
1145 {
1146  return n_;
1147 }
1148 //*************************************************************************************************
1149 
1150 
1151 //*************************************************************************************************
1156 template< typename Type // Data type of the sparse matrix
1157  , bool SO > // Storage order
1159 {
1160  return end_[m_] - begin_[0UL];
1161 }
1162 //*************************************************************************************************
1163 
1164 
1165 //*************************************************************************************************
1176 template< typename Type // Data type of the sparse matrix
1177  , bool SO > // Storage order
1178 inline size_t CompressedMatrix<Type,SO>::capacity( size_t i ) const
1179 {
1180  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1181  return begin_[i+1UL] - begin_[i];
1182 }
1183 //*************************************************************************************************
1184 
1185 
1186 //*************************************************************************************************
1191 template< typename Type // Data type of the sparse matrix
1192  , bool SO > // Storage order
1194 {
1195  size_t nonzeros( 0UL );
1196 
1197  for( size_t i=0UL; i<m_; ++i )
1198  nonzeros += nonZeros( i );
1199 
1200  return nonzeros;
1201 }
1202 //*************************************************************************************************
1203 
1204 
1205 //*************************************************************************************************
1216 template< typename Type // Data type of the sparse matrix
1217  , bool SO > // Storage order
1218 inline size_t CompressedMatrix<Type,SO>::nonZeros( size_t i ) const
1219 {
1220  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1221  return end_[i] - begin_[i];
1222 }
1223 //*************************************************************************************************
1224 
1225 
1226 //*************************************************************************************************
1231 template< typename Type // Data type of the sparse matrix
1232  , bool SO > // Storage order
1234 {
1235  for( size_t i=0UL; i<m_; ++i )
1236  end_[i] = begin_[i];
1237 }
1238 //*************************************************************************************************
1239 
1240 
1241 //*************************************************************************************************
1252 template< typename Type // Data type of the sparse matrix
1253  , bool SO > // Storage order
1254 inline void CompressedMatrix<Type,SO>::reset( size_t i )
1255 {
1256  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1257  end_[i] = begin_[i];
1258 }
1259 //*************************************************************************************************
1260 
1261 
1262 //*************************************************************************************************
1269 template< typename Type // Data type of the sparse matrix
1270  , bool SO > // Storage order
1272 {
1273  end_[0UL] = end_[m_];
1274  m_ = 0UL;
1275  n_ = 0UL;
1276 }
1277 //*************************************************************************************************
1278 
1279 
1280 //*************************************************************************************************
1292 template< typename Type // Data type of the sparse matrix
1293  , bool SO > // Storage order
1295  CompressedMatrix<Type,SO>::set( size_t i, size_t j, const Type& value )
1296 {
1297  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1298  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1299 
1300  const Iterator pos( lowerBound( i, j ) );
1301 
1302  if( pos != end_[i] && pos->index_ == j ) {
1303  pos->value() = value;
1304  return pos;
1305  }
1306  else return insert( pos, i, j, value );
1307 }
1308 //*************************************************************************************************
1309 
1310 
1311 //*************************************************************************************************
1324 template< typename Type // Data type of the sparse matrix
1325  , bool SO > // Storage order
1327  CompressedMatrix<Type,SO>::insert( size_t i, size_t j, const Type& value )
1328 {
1329  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1330  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1331 
1332  const Iterator pos( lowerBound( i, j ) );
1333 
1334  if( pos != end_[i] && pos->index_ == j )
1335  throw std::invalid_argument( "Bad access index" );
1336 
1337  return insert( pos, i, j, value );
1338 }
1339 //*************************************************************************************************
1340 
1341 
1342 //*************************************************************************************************
1352 template< typename Type // Data type of the sparse matrix
1353  , bool SO > // Storage order
1355  CompressedMatrix<Type,SO>::insert( Iterator pos, size_t i, size_t j, const Type& value )
1356 {
1357  if( begin_[i+1UL] - end_[i] != 0 ) {
1358  std::copy_backward( pos, end_[i], end_[i]+1 );
1359  pos->value_ = value;
1360  pos->index_ = j;
1361  ++end_[i];
1362 
1363  return pos;
1364  }
1365  else if( end_[m_] - begin_[m_] != 0 ) {
1366  std::copy_backward( pos, end_[m_-1UL], end_[m_-1UL]+1 );
1367 
1368  pos->value_ = value;
1369  pos->index_ = j;
1370 
1371  for( size_t k=i+1UL; k<m_+1UL; ++k ) {
1372  ++begin_[k];
1373  ++end_[k-1UL];
1374  }
1375 
1376  return pos;
1377  }
1378  else {
1379  size_t newCapacity( extendCapacity() );
1380 
1381  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1382  Iterator* newEnd = newBegin+capacity_+1UL;
1383 
1384  newBegin[0UL] = allocate<Element>( newCapacity );
1385 
1386  for( size_t k=0UL; k<i; ++k ) {
1387  const size_t nonzeros( end_[k] - begin_[k] );
1388  const size_t total( begin_[k+1UL] - begin_[k] );
1389  newEnd [k] = newBegin[k] + nonzeros;
1390  newBegin[k+1UL] = newBegin[k] + total;
1391  }
1392  newEnd [i] = newBegin[i] + ( end_[i] - begin_[i] ) + 1;
1393  newBegin[i+1UL] = newBegin[i] + ( begin_[i+1] - begin_[i] ) + 1;
1394  for( size_t k=i+1UL; k<m_; ++k ) {
1395  const size_t nonzeros( end_[k] - begin_[k] );
1396  const size_t total( begin_[k+1UL] - begin_[k] );
1397  newEnd [k] = newBegin[k] + nonzeros;
1398  newBegin[k+1UL] = newBegin[k] + total;
1399  }
1400 
1401  newEnd[m_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
1402 
1403  Iterator tmp = std::copy( begin_[0UL], pos, newBegin[0UL] );
1404  tmp->value_ = value;
1405  tmp->index_ = j;
1406  std::copy( pos, end_[m_-1UL], tmp+1UL );
1407 
1408  std::swap( newBegin, begin_ );
1409  end_ = newEnd;
1410  deallocate( newBegin[0UL] );
1411  delete [] newBegin;
1412 
1413  return tmp;
1414  }
1415 }
1416 //*************************************************************************************************
1417 
1418 
1419 //*************************************************************************************************
1428 template< typename Type // Data type of the sparse matrix
1429  , bool SO > // Storage order
1430 inline void CompressedMatrix<Type,SO>::erase( size_t i, size_t j )
1431 {
1432  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1433  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1434 
1435  const Iterator pos( find( i, j ) );
1436  if( pos != end_[i] )
1437  end_[i] = std::copy( pos+1, end_[i], pos );
1438 }
1439 //*************************************************************************************************
1440 
1441 
1442 //*************************************************************************************************
1453 template< typename Type // Data type of the sparse matrix
1454  , bool SO > // Storage order
1457 {
1458  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1459  BLAZE_USER_ASSERT( pos >= begin_[i] && pos <= end_[i], "Invalid compressed matrix iterator" );
1460 
1461  if( pos != end_[i] )
1462  end_[i] = std::copy( pos+1, end_[i], pos );
1463 
1464  return pos;
1465 }
1466 //*************************************************************************************************
1467 
1468 
1469 //*************************************************************************************************
1481 template< typename Type // Data type of the sparse matrix
1482  , bool SO > // Storage order
1485 {
1486  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1487  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
1488  BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i], "Invalid compressed matrix iterator" );
1489  BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i], "Invalid compressed matrix iterator" );
1490 
1491  if( first != last )
1492  end_[i] = std::copy( last, end_[i], first );
1493 
1494  return first;
1495 }
1496 //*************************************************************************************************
1497 
1498 
1499 //*************************************************************************************************
1514 template< typename Type // Data type of the sparse matrix
1515  , bool SO > // Storage order
1516 void CompressedMatrix<Type,SO>::resize( size_t m, size_t n, bool preserve )
1517 {
1518  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1519  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1520 
1521  if( m == m_ && n == n_ ) return;
1522 
1523  if( m > capacity_ )
1524  {
1525  Iterator* newBegin( new Iterator[2UL*m+2UL] );
1526  Iterator* newEnd ( newBegin+m+1UL );
1527 
1528  newBegin[0UL] = begin_[0UL];
1529 
1530  if( preserve ) {
1531  for( size_t i=0UL; i<m_; ++i ) {
1532  newEnd [i] = end_ [i];
1533  newBegin[i+1UL] = begin_[i+1UL];
1534  }
1535  for( size_t i=m_; i<m; ++i ) {
1536  newBegin[i+1UL] = newEnd[i] = begin_[m_];
1537  }
1538  }
1539  else {
1540  for( size_t i=0UL; i<m; ++i ) {
1541  newBegin[i+1UL] = newEnd[i] = begin_[0UL];
1542  }
1543  }
1544 
1545  newEnd[m] = end_[m_];
1546 
1547  std::swap( newBegin, begin_ );
1548  delete [] newBegin;
1549 
1550  end_ = newEnd;
1551  capacity_ = m;
1552  }
1553  else if( m > m_ )
1554  {
1555  end_[m] = end_[m_];
1556 
1557  if( !preserve ) {
1558  for( size_t i=0UL; i<m_; ++i )
1559  end_[i] = begin_[i];
1560  }
1561 
1562  for( size_t i=m_; i<m; ++i )
1563  begin_[i+1UL] = end_[i] = begin_[m_];
1564  }
1565  else
1566  {
1567  if( preserve ) {
1568  for( size_t i=0UL; i<m; ++i )
1569  end_[i] = lowerBound( i, n );
1570  }
1571  else {
1572  for( size_t i=0UL; i<m; ++i )
1573  end_[i] = begin_[i];
1574  }
1575 
1576  end_[m] = end_[m_];
1577  }
1578 
1579  m_ = m;
1580  n_ = n;
1581 }
1582 //*************************************************************************************************
1583 
1584 
1585 //*************************************************************************************************
1595 template< typename Type // Data type of the sparse matrix
1596  , bool SO > // Storage order
1597 inline void CompressedMatrix<Type,SO>::reserve( size_t nonzeros )
1598 {
1599  if( nonzeros > capacity() )
1600  reserveElements( nonzeros );
1601 }
1602 //*************************************************************************************************
1603 
1604 
1605 //*************************************************************************************************
1619 template< typename Type // Data type of the sparse matrix
1620  , bool SO > // Storage order
1621 void CompressedMatrix<Type,SO>::reserve( size_t i, size_t nonzeros )
1622 {
1623  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1624 
1625  const size_t current( capacity(i) );
1626 
1627  if( current >= nonzeros ) return;
1628 
1629  const ptrdiff_t additional( nonzeros - current );
1630 
1631  if( end_[m_] - begin_[m_] < additional )
1632  {
1633  const size_t newCapacity( begin_[m_] - begin_[0UL] + additional );
1634  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
1635 
1636  Iterator* newBegin( new Iterator[2UL*m_+2UL] );
1637  Iterator* newEnd ( newBegin+m_+1UL );
1638 
1639  newBegin[0UL] = allocate<Element>( newCapacity );
1640  newEnd [m_ ] = newBegin[0UL]+newCapacity;
1641 
1642  for( size_t k=0UL; k<i; ++k ) {
1643  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
1644  newBegin[k+1UL] = newBegin[k] + capacity(k);
1645  }
1646  newEnd [i ] = std::copy( begin_[i], end_[i], newBegin[i] );
1647  newBegin[i+1UL] = newBegin[i] + nonzeros;
1648  for( size_t k=i+1UL; k<m_; ++k ) {
1649  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
1650  newBegin[k+1UL] = newBegin[k] + capacity(k);
1651  }
1652 
1653  BLAZE_INTERNAL_ASSERT( newBegin[m_] == newEnd[m_], "Invalid pointer calculations" );
1654 
1655  std::swap( newBegin, begin_ );
1656  deallocate( newBegin[0UL] );
1657  delete [] newBegin;
1658  end_ = newEnd;
1659  }
1660  else
1661  {
1662  begin_[m_] += additional;
1663  for( size_t j=m_-1UL; j>i; --j ) {
1664  begin_[j] = std::copy_backward( begin_[j], end_[j], end_[j]+additional );
1665  end_ [j] += additional;
1666  }
1667  }
1668 }
1669 //*************************************************************************************************
1670 
1671 
1672 //*************************************************************************************************
1682 template< typename Type // Data type of the sparse matrix
1683  , bool SO > // Storage order
1685 {
1686  for( size_t i=0UL; i<m_; ++i )
1687  trim( i );
1688 }
1689 //*************************************************************************************************
1690 
1691 
1692 //*************************************************************************************************
1703 template< typename Type // Data type of the sparse matrix
1704  , bool SO > // Storage order
1705 inline void CompressedMatrix<Type,SO>::trim( size_t i )
1706 {
1707  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1708 
1709  if( i < ( m_ - 1UL ) )
1710  end_[i+1] = std::copy( begin_[i+1], end_[i+1], end_[i] );
1711  begin_[i+1] = end_[i];
1712 }
1713 //*************************************************************************************************
1714 
1715 
1716 //*************************************************************************************************
1721 template< typename Type // Data type of the sparse matrix
1722  , bool SO > // Storage order
1724 {
1725  CompressedMatrix tmp( trans( *this ) );
1726  swap( tmp );
1727  return *this;
1728 }
1729 //*************************************************************************************************
1730 
1731 
1732 //*************************************************************************************************
1738 template< typename Type // Data type of the sparse matrix
1739  , bool SO > // Storage order
1740 template< typename Other > // Data type of the scalar value
1742 {
1743  for( size_t i=0UL; i<m_; ++i )
1744  for( Iterator element=begin_[i]; element!=end_[i]; ++element )
1745  element->value_ *= scalar;
1746 
1747  return *this;
1748 }
1749 //*************************************************************************************************
1750 
1751 
1752 //*************************************************************************************************
1758 template< typename Type // Data type of the sparse matrix
1759  , bool SO > // Storage order
1760 template< typename Other > // Data type of the scalar value
1762 {
1763  const size_t size( blaze::min( m_, n_ ) );
1764 
1765  for( size_t i=0UL; i<size; ++i ) {
1766  Iterator pos = lowerBound( i, i );
1767  if( pos != end_[i] && pos->index_ == i )
1768  pos->value_ *= scalar;
1769  }
1770 
1771  return *this;
1772 }
1773 //*************************************************************************************************
1774 
1775 
1776 //*************************************************************************************************
1783 template< typename Type // Data type of the sparse matrix
1784  , bool SO > // Storage order
1785 inline void CompressedMatrix<Type,SO>::swap( CompressedMatrix& sm ) /* throw() */
1786 {
1787  std::swap( m_, sm.m_ );
1788  std::swap( n_, sm.n_ );
1789  std::swap( capacity_, sm.capacity_ );
1790  std::swap( begin_, sm.begin_ );
1791  std::swap( end_ , sm.end_ );
1792 }
1793 //*************************************************************************************************
1794 
1795 
1796 //*************************************************************************************************
1804 template< typename Type // Data type of the sparse matrix
1805  , bool SO > // Storage order
1807 {
1808  size_t nonzeros( 2UL*capacity()+1UL );
1809  nonzeros = blaze::max( nonzeros, 7UL );
1810 
1811  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
1812 
1813  return nonzeros;
1814 }
1815 //*************************************************************************************************
1816 
1817 
1818 //*************************************************************************************************
1824 template< typename Type // Data type of the sparse matrix
1825  , bool SO > // Storage order
1827 {
1828  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1829  Iterator* newEnd = newBegin+capacity_+1UL;
1830 
1831  newBegin[0UL] = allocate<Element>( nonzeros );
1832 
1833  for( size_t k=0UL; k<m_; ++k ) {
1834  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid row pointers" );
1835  newEnd [k] = std::copy( begin_[k], end_[k], newBegin[k] );
1836  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
1837  }
1838 
1839  newEnd[m_] = newBegin[0UL]+nonzeros;
1840 
1841  std::swap( newBegin, begin_ );
1842  deallocate( newBegin[0UL] );
1843  delete [] newBegin;
1844  end_ = newEnd;
1845 }
1846 //*************************************************************************************************
1847 
1848 
1849 
1850 
1851 //=================================================================================================
1852 //
1853 // LOOKUP FUNCTIONS
1854 //
1855 //=================================================================================================
1856 
1857 //*************************************************************************************************
1872 template< typename Type // Data type of the sparse matrix
1873  , bool SO > // Storage order
1875  CompressedMatrix<Type,SO>::find( size_t i, size_t j )
1876 {
1877  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
1878 }
1879 //*************************************************************************************************
1880 
1881 
1882 //*************************************************************************************************
1897 template< typename Type // Data type of the sparse matrix
1898  , bool SO > // Storage order
1900  CompressedMatrix<Type,SO>::find( size_t i, size_t j ) const
1901 {
1902  const ConstIterator pos( lowerBound( i, j ) );
1903  if( pos != end_[i] && pos->index_ == j )
1904  return pos;
1905  else return end_[i];
1906 }
1907 //*************************************************************************************************
1908 
1909 
1910 //*************************************************************************************************
1925 template< typename Type // Data type of the sparse matrix
1926  , bool SO > // Storage order
1929 {
1930  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
1931 }
1932 //*************************************************************************************************
1933 
1934 
1935 //*************************************************************************************************
1950 template< typename Type // Data type of the sparse matrix
1951  , bool SO > // Storage order
1953  CompressedMatrix<Type,SO>::lowerBound( size_t i, size_t j ) const
1954 {
1955  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1956  return std::lower_bound( begin_[i], end_[i], j, FindIndex() );
1957 }
1958 //*************************************************************************************************
1959 
1960 
1961 //*************************************************************************************************
1976 template< typename Type // Data type of the sparse matrix
1977  , bool SO > // Storage order
1980 {
1981  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
1982 }
1983 //*************************************************************************************************
1984 
1985 
1986 //*************************************************************************************************
2001 template< typename Type // Data type of the sparse matrix
2002  , bool SO > // Storage order
2004  CompressedMatrix<Type,SO>::upperBound( size_t i, size_t j ) const
2005 {
2006  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2007  return std::upper_bound( begin_[i], end_[i], j, FindIndex() );
2008 }
2009 //*************************************************************************************************
2010 
2011 
2012 
2013 
2014 //=================================================================================================
2015 //
2016 // LOW-LEVEL UTILITY FUNCTIONS
2017 //
2018 //=================================================================================================
2019 
2020 //*************************************************************************************************
2063 template< typename Type // Data type of the sparse matrix
2064  , bool SO > // Storage order
2065 inline void CompressedMatrix<Type,SO>::append( size_t i, size_t j, const Type& value, bool check )
2066 {
2067  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2068  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
2069  BLAZE_USER_ASSERT( end_[i] < end_[m_], "Not enough reserved space left" );
2070  BLAZE_USER_ASSERT( begin_[i] == end_[i] || j > ( end_[i]-1UL )->index_, "Index is not strictly increasing" );
2071 
2072  end_[i]->value_ = value;
2073 
2074  if( !check || !isDefault( end_[i]->value_ ) ) {
2075  end_[i]->index_ = j;
2076  ++end_[i];
2077  }
2078 }
2079 //*************************************************************************************************
2080 
2081 
2082 //*************************************************************************************************
2095 template< typename Type // Data type of the sparse matrix
2096  , bool SO > // Storage order
2098 {
2099  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2100 
2101  begin_[i+1UL] = end_[i];
2102  if( i != m_-1UL )
2103  end_[i+1UL] = end_[i];
2104 }
2105 //*************************************************************************************************
2106 
2107 
2108 
2109 
2110 //=================================================================================================
2111 //
2112 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2113 //
2114 //=================================================================================================
2115 
2116 //*************************************************************************************************
2126 template< typename Type // Data type of the sparse matrix
2127  , bool SO > // Storage order
2128 template< typename Other > // Data type of the foreign expression
2129 inline bool CompressedMatrix<Type,SO>::canAlias( const Other* alias ) const
2130 {
2131  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2132 }
2133 //*************************************************************************************************
2134 
2135 
2136 //*************************************************************************************************
2146 template< typename Type // Data type of the sparse matrix
2147  , bool SO > // Storage order
2148 template< typename Other > // Data type of the foreign expression
2149 inline bool CompressedMatrix<Type,SO>::isAliased( const Other* alias ) const
2150 {
2151  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2152 }
2153 //*************************************************************************************************
2154 
2155 
2156 //*************************************************************************************************
2166 template< typename Type // Data type of the sparse matrix
2167  , bool SO > // Storage order
2169 {
2170  return false;
2171 }
2172 //*************************************************************************************************
2173 
2174 
2175 //*************************************************************************************************
2186 template< typename Type // Data type of the sparse matrix
2187  , bool SO > // Storage order
2188 template< typename MT // Type of the right-hand side dense matrix
2189  , bool SO2 > // Storage order of the right-hand side dense matrix
2191 {
2192  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2193  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2194 
2195  size_t nonzeros( 0UL );
2196 
2197  for( size_t i=1UL; i<=m_; ++i )
2198  begin_[i] = end_[i] = end_[m_];
2199 
2200  for( size_t i=0UL; i<m_; ++i )
2201  {
2202  begin_[i] = end_[i] = begin_[0UL]+nonzeros;
2203 
2204  for( size_t j=0UL; j<n_; ++j )
2205  {
2206  if( nonzeros == capacity() ) {
2207  reserveElements( extendCapacity() );
2208  for( size_t k=i+1UL; k<=m_; ++k )
2209  begin_[k] = end_[k] = end_[m_];
2210  }
2211 
2212  end_[i]->value_ = (~rhs)(i,j);
2213 
2214  if( !isDefault( end_[i]->value_ ) ) {
2215  end_[i]->index_ = j;
2216  ++end_[i];
2217  ++nonzeros;
2218  }
2219  }
2220  }
2221 
2222  begin_[m_] = begin_[0UL]+nonzeros;
2223 }
2224 //*************************************************************************************************
2225 
2226 
2227 //*************************************************************************************************
2238 template< typename Type // Data type of the sparse matrix
2239  , bool SO > // Storage order
2240 template< typename MT > // Type of the right-hand side sparse matrix
2242 {
2243  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2244  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2245  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2246 
2247  for( size_t i=0UL; i<(~rhs).rows(); ++i ) {
2248  begin_[i+1UL] = end_[i] = std::copy( (~rhs).begin(i), (~rhs).end(i), begin_[i] );
2249  }
2250 }
2251 //*************************************************************************************************
2252 
2253 
2254 //*************************************************************************************************
2265 template< typename Type // Data type of the sparse matrix
2266  , bool SO > // Storage order
2267 template< typename MT > // Type of the right-hand side sparse matrix
2269 {
2271 
2272  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2273  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2274  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2275 
2276  typedef typename MT::ConstIterator RhsIterator;
2277 
2278  // Counting the number of elements per row
2279  std::vector<size_t> rowLengths( m_, 0UL );
2280  for( size_t j=0UL; j<n_; ++j ) {
2281  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2282  ++rowLengths[element->index()];
2283  }
2284 
2285  // Resizing the sparse matrix
2286  for( size_t i=0UL; i<m_; ++i ) {
2287  begin_[i+1UL] = end_[i+1UL] = begin_[i] + rowLengths[i];
2288  }
2289 
2290  // Appending the elements to the rows of the sparse matrix
2291  for( size_t j=0UL; j<n_; ++j ) {
2292  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2293  append( element->index(), j, element->value() );
2294  }
2295 }
2296 //*************************************************************************************************
2297 
2298 
2299 //*************************************************************************************************
2310 template< typename Type // Data type of the sparse matrix
2311  , bool SO > // Storage order
2312 template< typename MT // Type of the right-hand side dense matrix
2313  , bool SO2 > // Storage order of the right-hand side dense matrix
2315 {
2316  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2317  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2318 
2319  CompressedMatrix tmp( serial( *this + (~rhs) ) );
2320  swap( tmp );
2321 }
2322 //*************************************************************************************************
2323 
2324 
2325 //*************************************************************************************************
2336 template< typename Type // Data type of the sparse matrix
2337  , bool SO > // Storage order
2338 template< typename MT // Type of the right-hand side sparse matrix
2339  , bool SO2 > // Storage order of the right-hand side sparse matrix
2341 {
2342  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2343  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2344 
2345  CompressedMatrix tmp( serial( *this + (~rhs) ) );
2346  swap( tmp );
2347 }
2348 //*************************************************************************************************
2349 
2350 
2351 //*************************************************************************************************
2362 template< typename Type // Data type of the sparse matrix
2363  , bool SO > // Storage order
2364 template< typename MT // Type of the right-hand side dense matrix
2365  , bool SO2 > // Storage order of the right-hand side dense matrix
2367 {
2368  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2369  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2370 
2371  CompressedMatrix tmp( serial( *this - (~rhs) ) );
2372  swap( tmp );
2373 }
2374 //*************************************************************************************************
2375 
2376 
2377 //*************************************************************************************************
2388 template< typename Type // Data type of the sparse matrix
2389  , bool SO > // Storage order
2390 template< typename MT // Type of the right-hand side sparse matrix
2391  , bool SO2 > // Storage order of the right-hand sparse matrix
2393 {
2394  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2395  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2396 
2397  CompressedMatrix tmp( serial( *this - (~rhs) ) );
2398  swap( tmp );
2399 }
2400 //*************************************************************************************************
2401 
2402 
2403 
2404 
2405 
2406 
2407 
2408 
2409 //=================================================================================================
2410 //
2411 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2412 //
2413 //=================================================================================================
2414 
2415 //*************************************************************************************************
2423 template< typename Type > // Data type of the sparse matrix
2424 class CompressedMatrix<Type,true> : public SparseMatrix< CompressedMatrix<Type,true>, true >
2425 {
2426  private:
2427  //**Type definitions****************************************************************************
2429  //**********************************************************************************************
2430 
2431  //**Private class Element***********************************************************************
2435  struct Element : public ElementBase
2436  {
2437  // This operator is required due to a bug in all versions of the the MSVC compiler.
2438  // A simple 'using ElementBase::operator=;' statement results in ambiguity problems.
2439  template< typename Other >
2440  inline Element& operator=( const Other& rhs )
2441  {
2442  ElementBase::operator=( rhs );
2443  return *this;
2444  }
2445 
2446  friend class CompressedMatrix;
2447  };
2449  //**********************************************************************************************
2450 
2451  //**Private class FindIndex*********************************************************************
2455  struct FindIndex : public std::binary_function<Element,size_t,bool>
2456  {
2457  inline bool operator()( const Element& element, size_t index ) const {
2458  return element.index() < index;
2459  }
2460  inline bool operator()( size_t index, const Element& element ) const {
2461  return index < element.index();
2462  }
2463  inline bool operator()( const Element& element1, const Element& element2 ) const {
2464  return element1.index() < element2.index();
2465  }
2466  };
2468  //**********************************************************************************************
2469 
2470  public:
2471  //**Type definitions****************************************************************************
2473  typedef This ResultType;
2476  typedef Type ElementType;
2477  typedef const Type& ReturnType;
2478  typedef const This& CompositeType;
2480  typedef const Type& ConstReference;
2481  typedef Element* Iterator;
2482  typedef const Element* ConstIterator;
2483  //**********************************************************************************************
2484 
2485  //**Rebind struct definition********************************************************************
2488  template< typename ET > // Data type of the other matrix
2489  struct Rebind {
2491  };
2492  //**********************************************************************************************
2493 
2494  //**Compilation flags***************************************************************************
2496 
2499  enum { smpAssignable = !IsSMPAssignable<Type>::value };
2500  //**********************************************************************************************
2501 
2502  //**Constructors********************************************************************************
2505  explicit inline CompressedMatrix();
2506  explicit inline CompressedMatrix( size_t m, size_t n );
2507  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
2508  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
2509  inline CompressedMatrix( const CompressedMatrix& sm );
2510  template< typename MT, bool SO > inline CompressedMatrix( const DenseMatrix<MT,SO>& dm );
2511  template< typename MT, bool SO > inline CompressedMatrix( const SparseMatrix<MT,SO>& sm );
2513  //**********************************************************************************************
2514 
2515  //**Destructor**********************************************************************************
2518  inline ~CompressedMatrix();
2520  //**********************************************************************************************
2521 
2522  //**Data access functions***********************************************************************
2525  inline Reference operator()( size_t i, size_t j );
2526  inline ConstReference operator()( size_t i, size_t j ) const;
2527  inline Iterator begin ( size_t i );
2528  inline ConstIterator begin ( size_t i ) const;
2529  inline ConstIterator cbegin( size_t i ) const;
2530  inline Iterator end ( size_t i );
2531  inline ConstIterator end ( size_t i ) const;
2532  inline ConstIterator cend ( size_t i ) const;
2534  //**********************************************************************************************
2535 
2536  //**Assignment operators************************************************************************
2539  inline CompressedMatrix& operator= ( const CompressedMatrix& rhs );
2540  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO>& rhs );
2541  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO>& rhs );
2542  template< typename MT, bool SO > inline CompressedMatrix& operator+=( const Matrix<MT,SO>& rhs );
2543  template< typename MT, bool SO > inline CompressedMatrix& operator-=( const Matrix<MT,SO>& rhs );
2544  template< typename MT, bool SO > inline CompressedMatrix& operator*=( const Matrix<MT,SO>& rhs );
2545 
2546  template< typename Other >
2547  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
2548  operator*=( Other rhs );
2549 
2550  template< typename Other >
2551  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
2552  operator/=( Other rhs );
2554  //**********************************************************************************************
2555 
2556  //**Utility functions***************************************************************************
2559  inline size_t rows() const;
2560  inline size_t columns() const;
2561  inline size_t capacity() const;
2562  inline size_t capacity( size_t j ) const;
2563  inline size_t nonZeros() const;
2564  inline size_t nonZeros( size_t j ) const;
2565  inline void reset();
2566  inline void reset( size_t j );
2567  inline void clear();
2568  inline Iterator set ( size_t i, size_t j, const Type& value );
2569  inline Iterator insert ( size_t i, size_t j, const Type& value );
2570  inline void erase ( size_t i, size_t j );
2571  inline Iterator erase ( size_t j, Iterator pos );
2572  inline Iterator erase ( size_t j, Iterator first, Iterator last );
2573  void resize ( size_t m, size_t n, bool preserve=true );
2574  inline void reserve( size_t nonzeros );
2575  void reserve( size_t j, size_t nonzeros );
2576  inline void trim ();
2577  inline void trim ( size_t j );
2578  inline CompressedMatrix& transpose();
2579  template< typename Other > inline CompressedMatrix& scale( const Other& scalar );
2580  template< typename Other > inline CompressedMatrix& scaleDiagonal( Other scalar );
2581  inline void swap( CompressedMatrix& sm ) /* throw() */;
2583  //**********************************************************************************************
2584 
2585  //**Lookup functions****************************************************************************
2588  inline Iterator find ( size_t i, size_t j );
2589  inline ConstIterator find ( size_t i, size_t j ) const;
2590  inline Iterator lowerBound( size_t i, size_t j );
2591  inline ConstIterator lowerBound( size_t i, size_t j ) const;
2592  inline Iterator upperBound( size_t i, size_t j );
2593  inline ConstIterator upperBound( size_t i, size_t j ) const;
2595  //**********************************************************************************************
2596 
2597  //**Low-level utility functions*****************************************************************
2600  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
2601  inline void finalize( size_t j );
2603  //**********************************************************************************************
2604 
2605  //**Expression template evaluation functions****************************************************
2608  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2609  template< typename Other > inline bool isAliased( const Other* alias ) const;
2610 
2611  inline bool canSMPAssign() const;
2612 
2613  template< typename MT, bool SO > inline void assign ( const DenseMatrix<MT,SO>& rhs );
2614  template< typename MT > inline void assign ( const SparseMatrix<MT,true>& rhs );
2615  template< typename MT > inline void assign ( const SparseMatrix<MT,false>& rhs );
2616  template< typename MT, bool SO > inline void addAssign( const DenseMatrix<MT,SO>& rhs );
2617  template< typename MT, bool SO > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
2618  template< typename MT, bool SO > inline void subAssign( const DenseMatrix<MT,SO>& rhs );
2619  template< typename MT, bool SO > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
2621  //**********************************************************************************************
2622 
2623  private:
2624  //**Utility functions***************************************************************************
2627  Iterator insert( Iterator pos, size_t i, size_t j, const Type& value );
2628  inline size_t extendCapacity() const;
2629  void reserveElements( size_t nonzeros );
2631  //**********************************************************************************************
2632 
2633  //**Member variables****************************************************************************
2636  size_t m_;
2637  size_t n_;
2638  size_t capacity_;
2641 
2642  static const Type zero_;
2643 
2644  //**********************************************************************************************
2645 
2646  //**Compile time checks*************************************************************************
2654  //**********************************************************************************************
2655 };
2657 //*************************************************************************************************
2658 
2659 
2660 
2661 
2662 //=================================================================================================
2663 //
2664 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
2665 //
2666 //=================================================================================================
2667 
2668 template< typename Type >
2669 const Type CompressedMatrix<Type,true>::zero_ = Type();
2670 
2671 
2672 
2673 
2674 //=================================================================================================
2675 //
2676 // CONSTRUCTORS
2677 //
2678 //=================================================================================================
2679 
2680 //*************************************************************************************************
2684 template< typename Type > // Data type of the sparse matrix
2686  : m_ ( 0UL ) // The current number of rows of the sparse matrix
2687  , n_ ( 0UL ) // The current number of columns of the sparse matrix
2688  , capacity_( 0UL ) // The current capacity of the pointer array
2689  , begin_( new Iterator[2UL] ) // Pointers to the first non-zero element of each column
2690  , end_ ( begin_+1UL ) // Pointers one past the last non-zero element of each column
2691 {
2692  begin_[0UL] = end_[0UL] = NULL;
2693 }
2695 //*************************************************************************************************
2696 
2697 
2698 //*************************************************************************************************
2707 template< typename Type > // Data type of the sparse matrix
2708 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n )
2709  : m_ ( m ) // The current number of rows of the sparse matrix
2710  , n_ ( n ) // The current number of columns of the sparse matrix
2711  , capacity_( n ) // The current capacity of the pointer array
2712  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
2713  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
2714 {
2715  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
2716  begin_[j] = NULL;
2717 }
2719 //*************************************************************************************************
2720 
2721 
2722 //*************************************************************************************************
2732 template< typename Type > // Data type of the sparse matrix
2733 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
2734  : m_ ( m ) // The current number of rows of the sparse matrix
2735  , n_ ( n ) // The current number of columns of the sparse matrix
2736  , capacity_( n ) // The current capacity of the pointer array
2737  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
2738  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
2739 {
2740  begin_[0UL] = allocate<Element>( nonzeros );
2741  for( size_t j=1UL; j<(2UL*n_+1UL); ++j )
2742  begin_[j] = begin_[0UL];
2743  end_[n_] = begin_[0UL]+nonzeros;
2744 }
2746 //*************************************************************************************************
2747 
2748 
2749 //*************************************************************************************************
2759 template< typename Type > // Data type of the sparse matrix
2760 CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
2761  : m_ ( m ) // The current number of rows of the sparse matrix
2762  , n_ ( n ) // The current number of columns of the sparse matrix
2763  , capacity_( n ) // The current capacity of the pointer array
2764  , begin_( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2765  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2766 {
2767  BLAZE_USER_ASSERT( nonzeros.size() == n, "Size of capacity vector and number of columns don't match" );
2768 
2769  size_t newCapacity( 0UL );
2770  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
2771  newCapacity += *it;
2772 
2773  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
2774  for( size_t j=0UL; j<n_; ++j ) {
2775  begin_[j+1UL] = end_[j+1UL] = begin_[j] + nonzeros[j];
2776  }
2777 }
2779 //*************************************************************************************************
2780 
2781 
2782 //*************************************************************************************************
2788 template< typename Type > // Data type of the sparse matrix
2789 inline CompressedMatrix<Type,true>::CompressedMatrix( const CompressedMatrix& sm )
2790  : m_ ( sm.m_ ) // The current number of rows of the sparse matrix
2791  , n_ ( sm.n_ ) // The current number of columns of the sparse matrix
2792  , capacity_( sm.n_ ) // The current capacity of the pointer array
2793  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2794  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2795 {
2796  const size_t nonzeros( sm.nonZeros() );
2797 
2798  begin_[0UL] = allocate<Element>( nonzeros );
2799  for( size_t j=0UL; j<n_; ++j )
2800  begin_[j+1UL] = end_[j] = std::copy( sm.begin(j), sm.end(j), begin_[j] );
2801  end_[n_] = begin_[0UL]+nonzeros;
2802 }
2804 //*************************************************************************************************
2805 
2806 
2807 //*************************************************************************************************
2813 template< typename Type > // Data type of the sparse matrix
2814 template< typename MT // Type of the foreign dense matrix
2815  , bool SO > // Storage order of the foreign dense matrix
2816 inline CompressedMatrix<Type,true>::CompressedMatrix( const DenseMatrix<MT,SO>& dm )
2817  : m_ ( (~dm).rows() ) // The current number of rows of the sparse matrix
2818  , n_ ( (~dm).columns() ) // The current number of columns of the sparse matrix
2819  , capacity_( n_ ) // The current capacity of the pointer array
2820  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2821  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2822 {
2823  using blaze::assign;
2824 
2825  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
2826  begin_[j] = NULL;
2827 
2828  assign( *this, ~dm );
2829 }
2831 //*************************************************************************************************
2832 
2833 
2834 //*************************************************************************************************
2840 template< typename Type > // Data type of the sparse matrix
2841 template< typename MT // Type of the foreign sparse matrix
2842  , bool SO > // Storage order of the foreign sparse matrix
2843 inline CompressedMatrix<Type,true>::CompressedMatrix( const SparseMatrix<MT,SO>& sm )
2844  : m_ ( (~sm).rows() ) // The current number of rows of the sparse matrix
2845  , n_ ( (~sm).columns() ) // The current number of columns of the sparse matrix
2846  , capacity_( n_ ) // The current capacity of the pointer array
2847  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2848  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2849 {
2850  using blaze::assign;
2851 
2852  const size_t nonzeros( (~sm).nonZeros() );
2853 
2854  begin_[0UL] = allocate<Element>( nonzeros );
2855  for( size_t j=0UL; j<n_; ++j )
2856  begin_[j+1UL] = end_[j] = begin_[0UL];
2857  end_[n_] = begin_[0UL]+nonzeros;
2858 
2859  assign( *this, ~sm );
2860 }
2862 //*************************************************************************************************
2863 
2864 
2865 
2866 
2867 //=================================================================================================
2868 //
2869 // DESTRUCTOR
2870 //
2871 //=================================================================================================
2872 
2873 //*************************************************************************************************
2877 template< typename Type > // Data type of the sparse matrix
2878 inline CompressedMatrix<Type,true>::~CompressedMatrix()
2879 {
2880  deallocate( begin_[0UL] );
2881  delete [] begin_;
2882 }
2884 //*************************************************************************************************
2885 
2886 
2887 
2888 
2889 //=================================================================================================
2890 //
2891 // DATA ACCESS FUNCTIONS
2892 //
2893 //=================================================================================================
2894 
2895 //*************************************************************************************************
2903 template< typename Type > // Data type of the sparse matrix
2905  CompressedMatrix<Type,true>::operator()( size_t i, size_t j )
2906 {
2907  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2908  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2909 
2910  return Reference( *this, i, j );
2911 }
2913 //*************************************************************************************************
2914 
2915 
2916 //*************************************************************************************************
2924 template< typename Type > // Data type of the sparse matrix
2926  CompressedMatrix<Type,true>::operator()( size_t i, size_t j ) const
2927 {
2928  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2929  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2930 
2931  const ConstIterator pos( lowerBound( i, j ) );
2932 
2933  if( pos == end_[j] || pos->index_ != i )
2934  return zero_;
2935  else
2936  return pos->value_;
2937 }
2939 //*************************************************************************************************
2940 
2941 
2942 //*************************************************************************************************
2949 template< typename Type > // Data type of the sparse matrix
2951  CompressedMatrix<Type,true>::begin( size_t j )
2952 {
2953  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2954  return begin_[j];
2955 }
2957 //*************************************************************************************************
2958 
2959 
2960 //*************************************************************************************************
2967 template< typename Type > // Data type of the sparse matrix
2969  CompressedMatrix<Type,true>::begin( size_t j ) const
2970 {
2971  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2972  return begin_[j];
2973 }
2975 //*************************************************************************************************
2976 
2977 
2978 //*************************************************************************************************
2985 template< typename Type > // Data type of the sparse matrix
2987  CompressedMatrix<Type,true>::cbegin( size_t j ) const
2988 {
2989  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2990  return begin_[j];
2991 }
2993 //*************************************************************************************************
2994 
2995 
2996 //*************************************************************************************************
3003 template< typename Type > // Data type of the sparse matrix
3005  CompressedMatrix<Type,true>::end( size_t j )
3006 {
3007  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
3008  return end_[j];
3009 }
3011 //*************************************************************************************************
3012 
3013 
3014 //*************************************************************************************************
3021 template< typename Type > // Data type of the sparse matrix
3023  CompressedMatrix<Type,true>::end( size_t j ) const
3024 {
3025  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
3026  return end_[j];
3027 }
3029 //*************************************************************************************************
3030 
3031 
3032 //*************************************************************************************************
3039 template< typename Type > // Data type of the sparse matrix
3041  CompressedMatrix<Type,true>::cend( size_t j ) const
3042 {
3043  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
3044  return end_[j];
3045 }
3047 //*************************************************************************************************
3048 
3049 
3050 
3051 
3052 //=================================================================================================
3053 //
3054 // ASSIGNMENT OPERATORS
3055 //
3056 //=================================================================================================
3057 
3058 //*************************************************************************************************
3068 template< typename Type > // Data type of the sparse matrix
3069 inline CompressedMatrix<Type,true>&
3070  CompressedMatrix<Type,true>::operator=( const CompressedMatrix& rhs )
3071 {
3072  if( &rhs == this ) return *this;
3073 
3074  const size_t nonzeros( rhs.nonZeros() );
3075 
3076  if( rhs.n_ > capacity_ || nonzeros > capacity() )
3077  {
3078  Iterator* newBegin( new Iterator[2UL*rhs.n_+2UL] );
3079  Iterator* newEnd ( newBegin+(rhs.n_+1UL) );
3080 
3081  newBegin[0UL] = allocate<Element>( nonzeros );
3082  for( size_t j=0UL; j<rhs.n_; ++j ) {
3083  newBegin[j+1UL] = newEnd[j] = std::copy( rhs.begin_[j], rhs.end_[j], newBegin[j] );
3084  }
3085  newEnd[rhs.n_] = newBegin[0UL]+nonzeros;
3086 
3087  std::swap( begin_, newBegin );
3088  end_ = newEnd;
3089  deallocate( newBegin[0UL] );
3090  delete [] newBegin;
3091  capacity_ = rhs.n_;
3092  }
3093  else {
3094  for( size_t j=0UL; j<rhs.n_; ++j ) {
3095  begin_[j+1UL] = end_[j] = std::copy( rhs.begin_[j], rhs.end_[j], begin_[j] );
3096  }
3097  }
3098 
3099  m_ = rhs.m_;
3100  n_ = rhs.n_;
3101 
3102  return *this;
3103 }
3105 //*************************************************************************************************
3106 
3107 
3108 //*************************************************************************************************
3118 template< typename Type > // Data type of the sparse matrix
3119 template< typename MT // Type of the right-hand side dense matrix
3120  , bool SO > // Storage order of the right-hand side dense matrix
3121 inline CompressedMatrix<Type,true>&
3122  CompressedMatrix<Type,true>::operator=( const DenseMatrix<MT,SO>& rhs )
3123 {
3124  using blaze::assign;
3125 
3126  if( (~rhs).canAlias( this ) ) {
3127  CompressedMatrix tmp( ~rhs );
3128  swap( tmp );
3129  }
3130  else {
3131  resize( (~rhs).rows(), (~rhs).columns(), false );
3132  assign( *this, ~rhs );
3133  }
3134 
3135  return *this;
3136 }
3138 //*************************************************************************************************
3139 
3140 
3141 //*************************************************************************************************
3151 template< typename Type > // Data type of the sparse matrix
3152 template< typename MT // Type of the right-hand side sparse matrix
3153  , bool SO > // Storage order of the right-hand side sparse matrix
3154 inline CompressedMatrix<Type,true>&
3155  CompressedMatrix<Type,true>::operator=( const SparseMatrix<MT,SO>& rhs )
3156 {
3157  using blaze::assign;
3158 
3159  if( (~rhs).canAlias( this ) ||
3160  (~rhs).columns() > capacity_ ||
3161  (~rhs).nonZeros() > capacity() ) {
3162  CompressedMatrix tmp( ~rhs );
3163  swap( tmp );
3164  }
3165  else {
3166  resize( (~rhs).rows(), (~rhs).columns(), false );
3167  reset();
3168  assign( *this, ~rhs );
3169  }
3170 
3171  return *this;
3172 }
3174 //*************************************************************************************************
3175 
3176 
3177 //*************************************************************************************************
3188 template< typename Type > // Data type of the sparse matrix
3189 template< typename MT // Type of the right-hand side matrix
3190  , bool SO > // Storage order of the right-hand side matrix
3191 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator+=( const Matrix<MT,SO>& rhs )
3192 {
3193  using blaze::addAssign;
3194 
3195  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
3196  throw std::invalid_argument( "Matrix sizes do not match" );
3197 
3198  addAssign( *this, ~rhs );
3199  return *this;
3200 }
3202 //*************************************************************************************************
3203 
3204 
3205 //*************************************************************************************************
3216 template< typename Type > // Data type of the sparse matrix
3217 template< typename MT // Type of the right-hand side matrix
3218  , bool SO > // Storage order of the right-hand side matrix
3219 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator-=( const Matrix<MT,SO>& rhs )
3220 {
3221  using blaze::subAssign;
3222 
3223  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
3224  throw std::invalid_argument( "Matrix sizes do not match" );
3225 
3226  subAssign( *this, ~rhs );
3227  return *this;
3228 }
3230 //*************************************************************************************************
3231 
3232 
3233 //*************************************************************************************************
3244 template< typename Type > // Data type of the sparse matrix
3245 template< typename MT // Type of the right-hand side matrix
3246  , bool SO > // Storage order of the right-hand side matrix
3247 inline CompressedMatrix<Type,true>&
3248  CompressedMatrix<Type,true>::operator*=( const Matrix<MT,SO>& rhs )
3249 {
3250  if( (~rhs).rows() != n_ )
3251  throw std::invalid_argument( "Matrix sizes do not match" );
3252 
3253  CompressedMatrix tmp( *this * (~rhs) );
3254  swap( tmp );
3255 
3256  return *this;
3257 }
3259 //*************************************************************************************************
3260 
3261 
3262 //*************************************************************************************************
3270 template< typename Type > // Data type of the sparse matrix
3271 template< typename Other > // Data type of the right-hand side scalar
3272 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,true> >::Type&
3273  CompressedMatrix<Type,true>::operator*=( Other rhs )
3274 {
3275  for( size_t j=0UL; j<n_; ++j ) {
3276  const Iterator last( end(j) );
3277  for( Iterator element=begin(j); element!=last; ++element )
3278  element->value_ *= rhs;
3279  }
3280  return *this;
3281 }
3283 //*************************************************************************************************
3284 
3285 
3286 //*************************************************************************************************
3294 template< typename Type > // Data type of the sparse matrix
3295 template< typename Other > // Data type of the right-hand side scalar
3296 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,true> >::Type&
3297  CompressedMatrix<Type,true>::operator/=( Other rhs )
3298 {
3299  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3300 
3301  typedef typename DivTrait<Type,Other>::Type DT;
3302  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
3303 
3304  // Depending on the two involved data types, an integer division is applied or a
3305  // floating point division is selected.
3306  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
3307  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
3308  for( size_t j=0UL; j<n_; ++j ) {
3309  const Iterator last( end(j) );
3310  for( Iterator element=begin(j); element!=last; ++element )
3311  element->value_ *= tmp;
3312  }
3313  }
3314  else {
3315  for( size_t j=0UL; j<n_; ++j ) {
3316  const Iterator last( end(j) );
3317  for( Iterator element=begin(j); element!=last; ++element )
3318  element->value_ /= rhs;
3319  }
3320  }
3321 
3322  return *this;
3323 }
3325 //*************************************************************************************************
3326 
3327 
3328 
3329 
3330 //=================================================================================================
3331 //
3332 // UTILITY FUNCTIONS
3333 //
3334 //=================================================================================================
3335 
3336 //*************************************************************************************************
3342 template< typename Type > // Data type of the sparse matrix
3343 inline size_t CompressedMatrix<Type,true>::rows() const
3344 {
3345  return m_;
3346 }
3348 //*************************************************************************************************
3349 
3350 
3351 //*************************************************************************************************
3357 template< typename Type > // Data type of the sparse matrix
3358 inline size_t CompressedMatrix<Type,true>::columns() const
3359 {
3360  return n_;
3361 }
3363 //*************************************************************************************************
3364 
3365 
3366 //*************************************************************************************************
3372 template< typename Type > // Data type of the sparse matrix
3373 inline size_t CompressedMatrix<Type,true>::capacity() const
3374 {
3375  return end_[n_] - begin_[0UL];
3376 }
3378 //*************************************************************************************************
3379 
3380 
3381 //*************************************************************************************************
3388 template< typename Type > // Data type of the sparse matrix
3389 inline size_t CompressedMatrix<Type,true>::capacity( size_t j ) const
3390 {
3391  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3392  return begin_[j+1UL] - begin_[j];
3393 }
3395 //*************************************************************************************************
3396 
3397 
3398 //*************************************************************************************************
3404 template< typename Type > // Data type of the sparse matrix
3405 inline size_t CompressedMatrix<Type,true>::nonZeros() const
3406 {
3407  size_t nonzeros( 0UL );
3408 
3409  for( size_t j=0UL; j<n_; ++j )
3410  nonzeros += nonZeros( j );
3411 
3412  return nonzeros;
3413 }
3415 //*************************************************************************************************
3416 
3417 
3418 //*************************************************************************************************
3425 template< typename Type > // Data type of the sparse matrix
3426 inline size_t CompressedMatrix<Type,true>::nonZeros( size_t j ) const
3427 {
3428  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3429  return end_[j] - begin_[j];
3430 }
3432 //*************************************************************************************************
3433 
3434 
3435 //*************************************************************************************************
3441 template< typename Type > // Data type of the sparse matrix
3443 {
3444  for( size_t j=0UL; j<n_; ++j )
3445  end_[j] = begin_[j];
3446 }
3448 //*************************************************************************************************
3449 
3450 
3451 //*************************************************************************************************
3461 template< typename Type > // Data type of the sparse matrix
3462 inline void CompressedMatrix<Type,true>::reset( size_t j )
3463 {
3464  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3465  end_[j] = begin_[j];
3466 }
3468 //*************************************************************************************************
3469 
3470 
3471 //*************************************************************************************************
3479 template< typename Type > // Data type of the sparse matrix
3481 {
3482  end_[0UL] = end_[n_];
3483  m_ = 0UL;
3484  n_ = 0UL;
3485 }
3487 //*************************************************************************************************
3488 
3489 
3490 //*************************************************************************************************
3503 template< typename Type > // Data type of the sparse matrix
3505  CompressedMatrix<Type,true>::set( size_t i, size_t j, const Type& value )
3506 {
3507  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3508  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3509 
3510  const Iterator pos( lowerBound( i, j ) );
3511 
3512  if( pos != end_[j] && pos->index_ == i ) {
3513  pos->value() = value;
3514  return pos;
3515  }
3516  else return insert( pos, i, j, value );
3517 }
3519 //*************************************************************************************************
3520 
3521 
3522 //*************************************************************************************************
3536 template< typename Type > // Data type of the sparse matrix
3538  CompressedMatrix<Type,true>::insert( size_t i, size_t j, const Type& value )
3539 {
3540  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3541  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3542 
3543  const Iterator pos( lowerBound( i, j ) );
3544 
3545  if( pos != end_[j] && pos->index_ == i )
3546  throw std::invalid_argument( "Bad access index" );
3547 
3548  return insert( pos, i, j, value );
3549 }
3551 //*************************************************************************************************
3552 
3553 
3554 //*************************************************************************************************
3565 template< typename Type > // Data type of the sparse matrix
3567  CompressedMatrix<Type,true>::insert( Iterator pos, size_t i, size_t j, const Type& value )
3568 {
3569  if( begin_[j+1UL] - end_[j] != 0 ) {
3570  std::copy_backward( pos, end_[j], end_[j]+1 );
3571  pos->value_ = value;
3572  pos->index_ = i;
3573  ++end_[j];
3574 
3575  return pos;
3576  }
3577  else if( end_[n_] - begin_[n_] != 0 ) {
3578  std::copy_backward( pos, end_[n_-1UL], end_[n_-1]+1 );
3579 
3580  pos->value_ = value;
3581  pos->index_ = i;
3582 
3583  for( size_t k=j+1UL; k<n_+1UL; ++k ) {
3584  ++begin_[k];
3585  ++end_[k-1UL];
3586  }
3587 
3588  return pos;
3589  }
3590  else {
3591  size_t newCapacity( extendCapacity() );
3592 
3593  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
3594  Iterator* newEnd = newBegin+capacity_+1UL;
3595 
3596  newBegin[0UL] = allocate<Element>( newCapacity );
3597 
3598  for( size_t k=0UL; k<j; ++k ) {
3599  const size_t nonzeros( end_[k] - begin_[k] );
3600  const size_t total( begin_[k+1UL] - begin_[k] );
3601  newEnd [k] = newBegin[k] + nonzeros;
3602  newBegin[k+1UL] = newBegin[k] + total;
3603  }
3604  newEnd [j] = newBegin[j] + ( end_[j] - begin_[j] ) + 1;
3605  newBegin[j+1UL] = newBegin[j] + ( begin_[j+1UL] - begin_[j] ) + 1;
3606  for( size_t k=j+1UL; k<n_; ++k ) {
3607  const size_t nonzeros( end_[k] - begin_[k] );
3608  const size_t total( begin_[k+1UL] - begin_[k] );
3609  newEnd [k] = newBegin[k] + nonzeros;
3610  newBegin[k+1UL] = newBegin[k] + total;
3611  }
3612 
3613  newEnd[n_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
3614 
3615  Iterator tmp = std::copy( begin_[0UL], pos, newBegin[0UL] );
3616  tmp->value_ = value;
3617  tmp->index_ = i;
3618  std::copy( pos, end_[n_-1UL], tmp+1UL );
3619 
3620  std::swap( newBegin, begin_ );
3621  end_ = newEnd;
3622  deallocate( newBegin[0UL] );
3623  delete [] newBegin;
3624 
3625  return tmp;
3626  }
3627 }
3629 //*************************************************************************************************
3630 
3631 
3632 //*************************************************************************************************
3642 template< typename Type > // Data type of the sparse matrix
3643 inline void CompressedMatrix<Type,true>::erase( size_t i, size_t j )
3644 {
3645  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3646  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3647 
3648  const Iterator pos( find( i, j ) );
3649  if( pos != end_[j] )
3650  end_[j] = std::copy( pos+1, end_[j], pos );
3651 }
3653 //*************************************************************************************************
3654 
3655 
3656 //*************************************************************************************************
3666 template< typename Type > // Data type of the sparse matrix
3668  CompressedMatrix<Type,true>::erase( size_t j, Iterator pos )
3669 {
3670  BLAZE_USER_ASSERT( j < columns() , "Invalid row access index" );
3671  BLAZE_USER_ASSERT( pos >= begin_[j] && pos <= end_[j], "Invalid compressed matrix iterator" );
3672 
3673  if( pos != end_[j] )
3674  end_[j] = std::copy( pos+1, end_[j], pos );
3675 
3676  return pos;
3677 }
3679 //*************************************************************************************************
3680 
3681 
3682 //*************************************************************************************************
3693 template< typename Type > // Data type of the sparse matrix
3695  CompressedMatrix<Type,true>::erase( size_t j, Iterator first, Iterator last )
3696 {
3697  BLAZE_USER_ASSERT( j < columns(), "Invalid row access index" );
3698  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
3699  BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j], "Invalid compressed matrix iterator" );
3700  BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j], "Invalid compressed matrix iterator" );
3701 
3702  if( first != last )
3703  end_[j] = std::copy( last, end_[j], first );
3704 
3705  return first;
3706 }
3708 //*************************************************************************************************
3709 
3710 
3711 //*************************************************************************************************
3727 template< typename Type > // Data type of the sparse matrix
3728 void CompressedMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
3729 {
3730  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
3731  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
3732 
3733  if( m == m_ && n == n_ ) return;
3734 
3735  if( n > capacity_ )
3736  {
3737  Iterator* newBegin( new Iterator[2UL*n+2UL] );
3738  Iterator* newEnd ( newBegin+n+1UL );
3739 
3740  newBegin[0UL] = begin_[0UL];
3741 
3742  if( preserve ) {
3743  for( size_t j=0UL; j<n_; ++j ) {
3744  newEnd [j] = end_ [j];
3745  newBegin[j+1UL] = begin_[j+1UL];
3746  }
3747  for( size_t j=n_; j<n; ++j ) {
3748  newBegin[j+1UL] = newEnd[j] = begin_[n_];
3749  }
3750  }
3751  else {
3752  for( size_t j=0UL; j<n; ++j ) {
3753  newBegin[j+1UL] = newEnd[j] = begin_[0UL];
3754  }
3755  }
3756 
3757  newEnd[n] = end_[n_];
3758 
3759  std::swap( newBegin, begin_ );
3760  delete [] newBegin;
3761 
3762  end_ = newEnd;
3763  capacity_ = n;
3764  }
3765  else if( n > n_ )
3766  {
3767  end_[n] = end_[n_];
3768 
3769  if( !preserve ) {
3770  for( size_t j=0UL; j<n_; ++j )
3771  end_[j] = begin_[j];
3772  }
3773 
3774  for( size_t j=n_; j<n; ++j )
3775  begin_[j+1UL] = end_[j] = begin_[n_];
3776  }
3777  else
3778  {
3779  if( preserve ) {
3780  for( size_t j=0UL; j<n; ++j )
3781  end_[j] = lowerBound( m, j );
3782  }
3783  else {
3784  for( size_t j=0UL; j<n; ++j )
3785  end_[j] = begin_[j];
3786  }
3787 
3788  end_[n] = end_[n_];
3789  }
3790 
3791  m_ = m;
3792  n_ = n;
3793 }
3795 //*************************************************************************************************
3796 
3797 
3798 //*************************************************************************************************
3809 template< typename Type > // Data type of the sparse matrix
3810 inline void CompressedMatrix<Type,true>::reserve( size_t nonzeros )
3811 {
3812  if( nonzeros > capacity() )
3813  reserveElements( nonzeros );
3814 }
3816 //*************************************************************************************************
3817 
3818 
3819 //*************************************************************************************************
3831 template< typename Type > // Data type of the sparse matrix
3832 void CompressedMatrix<Type,true>::reserve( size_t j, size_t nonzeros )
3833 {
3834  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3835 
3836  const size_t current( capacity(j) );
3837 
3838  if( current >= nonzeros ) return;
3839 
3840  const ptrdiff_t additional( nonzeros - current );
3841 
3842  if( end_[n_] - begin_[n_] < additional )
3843  {
3844  const size_t newCapacity( begin_[n_] - begin_[0UL] + additional );
3845  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
3846 
3847  Iterator* newBegin( new Iterator[2UL*n_+2UL] );
3848  Iterator* newEnd ( newBegin+n_+1UL );
3849 
3850  newBegin[0UL] = allocate<Element>( newCapacity );
3851  newEnd [n_ ] = newBegin[0UL]+newCapacity;
3852 
3853  for( size_t k=0UL; k<j; ++k ) {
3854  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
3855  newBegin[k+1UL] = newBegin[k] + capacity(k);
3856  }
3857  newEnd [j ] = std::copy( begin_[j], end_[j], newBegin[j] );
3858  newBegin[j+1UL] = newBegin[j] + nonzeros;
3859  for( size_t k=j+1UL; k<n_; ++k ) {
3860  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
3861  newBegin[k+1UL] = newBegin[k] + capacity(k);
3862  }
3863 
3864  BLAZE_INTERNAL_ASSERT( newBegin[n_] == newEnd[n_], "Invalid pointer calculations" );
3865 
3866  std::swap( newBegin, begin_ );
3867  deallocate( newBegin[0UL] );
3868  delete [] newBegin;
3869  end_ = newEnd;
3870  }
3871  else
3872  {
3873  begin_[n_] += additional;
3874  for( size_t k=n_-1UL; k>j; --k ) {
3875  begin_[k] = std::copy_backward( begin_[k], end_[k], end_[k]+additional );
3876  end_ [k] += additional;
3877  }
3878  }
3879 }
3881 //*************************************************************************************************
3882 
3883 
3884 //*************************************************************************************************
3894 template< typename Type > // Data type of the sparse matrix
3895 void CompressedMatrix<Type,true>::trim()
3896 {
3897  for( size_t j=0UL; j<n_; ++j )
3898  trim( j );
3899 }
3901 //*************************************************************************************************
3902 
3903 
3904 //*************************************************************************************************
3915 template< typename Type > // Data type of the sparse matrix
3916 void CompressedMatrix<Type,true>::trim( size_t j )
3917 {
3918  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3919 
3920  if( j < ( n_ - 1UL ) )
3921  end_[j+1] = std::copy( begin_[j+1], end_[j+1], end_[j] );
3922  begin_[j+1] = end_[j];
3923 }
3925 //*************************************************************************************************
3926 
3927 
3928 //*************************************************************************************************
3934 template< typename Type > // Data type of the sparse matrix
3935 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::transpose()
3936 {
3937  CompressedMatrix tmp( trans( *this ) );
3938  swap( tmp );
3939  return *this;
3940 }
3942 //*************************************************************************************************
3943 
3944 
3945 //*************************************************************************************************
3952 template< typename Type > // Data type of the sparse matrix
3953 template< typename Other > // Data type of the scalar value
3954 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scale( const Other& scalar )
3955 {
3956  for( size_t j=0UL; j<n_; ++j )
3957  for( Iterator element=begin_[j]; element!=end_[j]; ++element )
3958  element->value_ *= scalar;
3959 
3960  return *this;
3961 }
3963 //*************************************************************************************************
3964 
3965 
3966 //*************************************************************************************************
3973 template< typename Type > // Data type of the sparse matrix
3974 template< typename Other > // Data type of the scalar value
3975 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scaleDiagonal( Other scalar )
3976 {
3977  const size_t size( blaze::min( m_, n_ ) );
3978 
3979  for( size_t j=0UL; j<size; ++j ) {
3980  Iterator pos = lowerBound( j, j );
3981  if( pos != end_[j] && pos->index_ == j )
3982  pos->value_ *= scalar;
3983  }
3984 
3985  return *this;
3986 }
3988 //*************************************************************************************************
3989 
3990 
3991 //*************************************************************************************************
3999 template< typename Type > // Data type of the sparse matrix
4000 inline void CompressedMatrix<Type,true>::swap( CompressedMatrix& sm ) /* throw() */
4001 {
4002  std::swap( m_, sm.m_ );
4003  std::swap( n_, sm.n_ );
4004  std::swap( capacity_, sm.capacity_ );
4005  std::swap( begin_, sm.begin_ );
4006  std::swap( end_ , sm.end_ );
4007 }
4009 //*************************************************************************************************
4010 
4011 
4012 //*************************************************************************************************
4021 template< typename Type > // Data type of the sparse matrix
4022 inline size_t CompressedMatrix<Type,true>::extendCapacity() const
4023 {
4024  size_t nonzeros( 2UL*capacity()+1UL );
4025  nonzeros = blaze::max( nonzeros, 7UL );
4026 
4027  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
4028 
4029  return nonzeros;
4030 }
4032 //*************************************************************************************************
4033 
4034 
4035 //*************************************************************************************************
4042 template< typename Type > // Data type of the sparse matrix
4043 void CompressedMatrix<Type,true>::reserveElements( size_t nonzeros )
4044 {
4045  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
4046  Iterator* newEnd = newBegin+capacity_+1UL;
4047 
4048  newBegin[0UL] = allocate<Element>( nonzeros );
4049 
4050  for( size_t k=0UL; k<n_; ++k ) {
4051  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid column pointers" );
4052  newEnd [k] = std::copy( begin_[k], end_[k], newBegin[k] );
4053  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
4054  }
4055 
4056  newEnd[n_] = newBegin[0UL]+nonzeros;
4057 
4058  std::swap( newBegin, begin_ );
4059  deallocate( newBegin[0UL] );
4060  delete [] newBegin;
4061  end_ = newEnd;
4062 }
4064 //*************************************************************************************************
4065 
4066 
4067 
4068 
4069 //=================================================================================================
4070 //
4071 // LOOKUP FUNCTIONS
4072 //
4073 //=================================================================================================
4074 
4075 //*************************************************************************************************
4090 template< typename Type > // Data type of the sparse matrix
4092  CompressedMatrix<Type,true>::find( size_t i, size_t j )
4093 {
4094  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
4095 }
4097 //*************************************************************************************************
4098 
4099 
4100 //*************************************************************************************************
4115 template< typename Type > // Data type of the sparse matrix
4117  CompressedMatrix<Type,true>::find( size_t i, size_t j ) const
4118 {
4119  const ConstIterator pos( lowerBound( i, j ) );
4120  if( pos != end_[j] && pos->index_ == i )
4121  return pos;
4122  else return end_[j];
4123 }
4125 //*************************************************************************************************
4126 
4127 
4128 //*************************************************************************************************
4142 template< typename Type > // Data type of the sparse matrix
4144  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j )
4145 {
4146  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
4147 }
4149 //*************************************************************************************************
4150 
4151 
4152 //*************************************************************************************************
4166 template< typename Type > // Data type of the sparse matrix
4168  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j ) const
4169 {
4170  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4171  return std::lower_bound( begin_[j], end_[j], i, FindIndex() );
4172 }
4174 //*************************************************************************************************
4175 
4176 
4177 //*************************************************************************************************
4191 template< typename Type > // Data type of the sparse matrix
4193  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j )
4194 {
4195  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
4196 }
4198 //*************************************************************************************************
4199 
4200 
4201 //*************************************************************************************************
4215 template< typename Type > // Data type of the sparse matrix
4217  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j ) const
4218 {
4219  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4220  return std::upper_bound( begin_[j], end_[j], i, FindIndex() );
4221 }
4223 //*************************************************************************************************
4224 
4225 
4226 
4227 
4228 //=================================================================================================
4229 //
4230 // LOW-LEVEL UTILITY FUNCTIONS
4231 //
4232 //=================================================================================================
4233 
4234 //*************************************************************************************************
4275 template< typename Type > // Data type of the sparse matrix
4276 inline void CompressedMatrix<Type,true>::append( size_t i, size_t j, const Type& value, bool check )
4277 {
4278  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
4279  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
4280  BLAZE_USER_ASSERT( end_[j] < end_[n_], "Not enough reserved space left" );
4281  BLAZE_USER_ASSERT( begin_[j] == end_[j] || i > ( end_[j]-1UL )->index_, "Index is not strictly increasing" );
4282 
4283  end_[j]->value_ = value;
4284 
4285  if( !check || !isDefault( end_[j]->value_ ) ) {
4286  end_[j]->index_ = i;
4287  ++end_[j];
4288  }
4289 }
4291 //*************************************************************************************************
4292 
4293 
4294 //*************************************************************************************************
4308 template< typename Type > // Data type of the sparse matrix
4309 inline void CompressedMatrix<Type,true>::finalize( size_t j )
4310 {
4311  BLAZE_USER_ASSERT( j < n_, "Invalid row access index" );
4312 
4313  begin_[j+1UL] = end_[j];
4314  if( j != n_-1UL )
4315  end_[j+1UL] = end_[j];
4316 }
4318 //*************************************************************************************************
4319 
4320 
4321 
4322 
4323 //=================================================================================================
4324 //
4325 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4326 //
4327 //=================================================================================================
4328 
4329 //*************************************************************************************************
4340 template< typename Type > // Data type of the sparse matrix
4341 template< typename Other > // Data type of the foreign expression
4342 inline bool CompressedMatrix<Type,true>::canAlias( const Other* alias ) const
4343 {
4344  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4345 }
4347 //*************************************************************************************************
4348 
4349 
4350 //*************************************************************************************************
4361 template< typename Type > // Data type of the sparse matrix
4362 template< typename Other > // Data type of the foreign expression
4363 inline bool CompressedMatrix<Type,true>::isAliased( const Other* alias ) const
4364 {
4365  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4366 }
4368 //*************************************************************************************************
4369 
4370 
4371 //*************************************************************************************************
4382 template< typename Type > // Data type of the sparse matrix
4383 inline bool CompressedMatrix<Type,true>::canSMPAssign() const
4384 {
4385  return false;
4386 }
4388 //*************************************************************************************************
4389 
4390 
4391 //*************************************************************************************************
4403 template< typename Type > // Data type of the sparse matrix
4404 template< typename MT // Type of the right-hand side dense matrix
4405  , bool SO > // Storage order of the right-hand side dense matrix
4406 inline void CompressedMatrix<Type,true>::assign( const DenseMatrix<MT,SO>& rhs )
4407 {
4408  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4409  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4410 
4411  size_t nonzeros( 0UL );
4412 
4413  for( size_t j=1UL; j<=n_; ++j )
4414  begin_[j] = end_[j] = end_[n_];
4415 
4416  for( size_t j=0UL; j<n_; ++j )
4417  {
4418  begin_[j] = end_[j] = begin_[0UL]+nonzeros;
4419 
4420  for( size_t i=0UL; i<m_; ++i )
4421  {
4422  if( nonzeros == capacity() ) {
4423  reserveElements( extendCapacity() );
4424  for( size_t k=j+1UL; k<=n_; ++k )
4425  begin_[k] = end_[k] = end_[n_];
4426  }
4427 
4428  end_[j]->value_ = (~rhs)(i,j);
4429 
4430  if( !isDefault( end_[j]->value_ ) ) {
4431  end_[j]->index_ = i;
4432  ++end_[j];
4433  ++nonzeros;
4434  }
4435  }
4436  }
4437 
4438  begin_[n_] = begin_[0UL]+nonzeros;
4439 }
4441 //*************************************************************************************************
4442 
4443 
4444 //*************************************************************************************************
4456 template< typename Type > // Data type of the sparse matrix
4457 template< typename MT > // Type of the right-hand side sparse matrix
4458 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,true>& rhs )
4459 {
4460  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4461  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4462  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4463 
4464  for( size_t j=0UL; j<(~rhs).columns(); ++j ) {
4465  begin_[j+1UL] = end_[j] = std::copy( (~rhs).begin(j), (~rhs).end(j), begin_[j] );
4466  }
4467 }
4469 //*************************************************************************************************
4470 
4471 
4472 //*************************************************************************************************
4484 template< typename Type > // Data type of the sparse matrix
4485 template< typename MT > // Type of the right-hand side sparse matrix
4486 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,false>& rhs )
4487 {
4489 
4490  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4491  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4492  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4493 
4494  typedef typename MT::ConstIterator RhsIterator;
4495 
4496  // Counting the number of elements per column
4497  std::vector<size_t> columnLengths( n_, 0UL );
4498  for( size_t i=0UL; i<m_; ++i ) {
4499  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4500  ++columnLengths[element->index()];
4501  }
4502 
4503  // Resizing the sparse matrix
4504  for( size_t j=0UL; j<n_; ++j ) {
4505  begin_[j+1UL] = end_[j+1UL] = begin_[j] + columnLengths[j];
4506  }
4507 
4508  // Appending the elements to the columns of the sparse matrix
4509  for( size_t i=0UL; i<m_; ++i ) {
4510  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4511  append( i, element->index(), element->value() );
4512  }
4513 }
4515 //*************************************************************************************************
4516 
4517 
4518 //*************************************************************************************************
4530 template< typename Type > // Data type of the sparse matrix
4531 template< typename MT // Type of the right-hand side dense matrix
4532  , bool SO > // Storage order of the right-hand side dense matrix
4533 inline void CompressedMatrix<Type,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
4534 {
4535  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4536  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4537 
4538  CompressedMatrix tmp( serial( *this + (~rhs) ) );
4539  swap( tmp );
4540 }
4542 //*************************************************************************************************
4543 
4544 
4545 //*************************************************************************************************
4557 template< typename Type > // Data type of the sparse matrix
4558 template< typename MT // Type of the right-hand side sparse matrix
4559  , bool SO > // Storage order of the right-hand side sparse matrix
4560 inline void CompressedMatrix<Type,true>::addAssign( const SparseMatrix<MT,SO>& rhs )
4561 {
4562  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4563  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4564 
4565  CompressedMatrix tmp( serial( *this + (~rhs) ) );
4566  swap( tmp );
4567 }
4569 //*************************************************************************************************
4570 
4571 
4572 //*************************************************************************************************
4584 template< typename Type > // Data type of the sparse matrix
4585 template< typename MT // Type of the right-hand side dense matrix
4586  , bool SO > // Storage order of the right-hand side dense matrix
4587 inline void CompressedMatrix<Type,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
4588 {
4589  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4590  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4591 
4592  CompressedMatrix tmp( serial( *this - (~rhs) ) );
4593  swap( tmp );
4594 }
4596 //*************************************************************************************************
4597 
4598 
4599 //*************************************************************************************************
4611 template< typename Type > // Data type of the sparse matrix
4612 template< typename MT // Type of the right-hand side sparse matrix
4613  , bool SO > // Storage order of the right-hand side sparse matrix
4614 inline void CompressedMatrix<Type,true>::subAssign( const SparseMatrix<MT,SO>& rhs )
4615 {
4616  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4617  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4618 
4619  CompressedMatrix tmp( serial( *this - (~rhs) ) );
4620  swap( tmp );
4621 }
4623 //*************************************************************************************************
4624 
4625 
4626 
4627 
4628 
4629 
4630 
4631 
4632 //=================================================================================================
4633 //
4634 // COMPRESSEDMATRIX OPERATORS
4635 //
4636 //=================================================================================================
4637 
4638 //*************************************************************************************************
4641 template< typename Type, bool SO >
4642 inline void reset( CompressedMatrix<Type,SO>& m );
4643 
4644 template< typename Type, bool SO >
4645 inline void reset( CompressedMatrix<Type,SO>& m, size_t i );
4646 
4647 template< typename Type, bool SO >
4648 inline void clear( CompressedMatrix<Type,SO>& m );
4649 
4650 template< typename Type, bool SO >
4651 inline bool isDefault( const CompressedMatrix<Type,SO>& m );
4652 
4653 template< typename Type, bool SO >
4654 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) /* throw() */;
4655 
4656 template< typename Type, bool SO >
4657 inline void move( CompressedMatrix<Type,SO>& dst, CompressedMatrix<Type,SO>& src ) /* throw() */;
4659 //*************************************************************************************************
4660 
4661 
4662 //*************************************************************************************************
4669 template< typename Type // Data type of the sparse matrix
4670  , bool SO > // Storage order
4671 inline void reset( CompressedMatrix<Type,SO>& m )
4672 {
4673  m.reset();
4674 }
4675 //*************************************************************************************************
4676 
4677 
4678 //*************************************************************************************************
4691 template< typename Type // Data type of the sparse matrix
4692  , bool SO > // Storage order
4693 inline void reset( CompressedMatrix<Type,SO>& m, size_t i )
4694 {
4695  m.reset( i );
4696 }
4697 //*************************************************************************************************
4698 
4699 
4700 //*************************************************************************************************
4707 template< typename Type // Data type of the sparse matrix
4708  , bool SO > // Storage order
4709 inline void clear( CompressedMatrix<Type,SO>& m )
4710 {
4711  m.clear();
4712 }
4713 //*************************************************************************************************
4714 
4715 
4716 //*************************************************************************************************
4734 template< typename Type // Data type of the sparse matrix
4735  , bool SO > // Storage order
4736 inline bool isDefault( const CompressedMatrix<Type,SO>& m )
4737 {
4738  return ( m.rows() == 0UL && m.columns() == 0UL );
4739 }
4740 //*************************************************************************************************
4741 
4742 
4743 //*************************************************************************************************
4752 template< typename Type // Data type of the sparse matrix
4753  , bool SO > // Storage order
4754 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) /* throw() */
4755 {
4756  a.swap( b );
4757 }
4758 //*************************************************************************************************
4759 
4760 
4761 //*************************************************************************************************
4770 template< typename Type // Data type of the sparse matrix
4771  , bool SO > // Storage order
4772 inline void move( CompressedMatrix<Type,SO>& dst, CompressedMatrix<Type,SO>& src ) /* throw() */
4773 {
4774  dst.swap( src );
4775 }
4776 //*************************************************************************************************
4777 
4778 
4779 
4780 
4781 //=================================================================================================
4782 //
4783 // ISRESIZABLE SPECIALIZATIONS
4784 //
4785 //=================================================================================================
4786 
4787 //*************************************************************************************************
4789 template< typename T, bool SO >
4790 struct IsResizable< CompressedMatrix<T,SO> > : public TrueType
4791 {
4792  enum { value = 1 };
4793  typedef TrueType Type;
4794 };
4796 //*************************************************************************************************
4797 
4798 
4799 
4800 
4801 //=================================================================================================
4802 //
4803 // ADDTRAIT SPECIALIZATIONS
4804 //
4805 //=================================================================================================
4806 
4807 //*************************************************************************************************
4809 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4810 struct AddTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4811 {
4812  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4813 };
4814 
4815 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4816 struct AddTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4817 {
4818  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO2 > Type;
4819 };
4820 
4821 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4822 struct AddTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4823 {
4824  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4825 };
4826 
4827 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4828 struct AddTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4829 {
4830  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO1 > Type;
4831 };
4832 
4833 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4834 struct AddTrait< CompressedMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
4835 {
4836  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4837 };
4838 
4839 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4840 struct AddTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
4841 {
4842  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, SO2 > Type;
4843 };
4844 
4845 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4846 struct AddTrait< HybridMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4847 {
4848  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4849 };
4850 
4851 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4852 struct AddTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4853 {
4854  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, SO1 > Type;
4855 };
4856 
4857 template< typename T1, bool SO, typename T2 >
4858 struct AddTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4859 {
4860  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4861 };
4862 
4863 template< typename T1, bool SO1, typename T2, bool SO2 >
4864 struct AddTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4865 {
4866  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO2 > Type;
4867 };
4868 
4869 template< typename T1, bool SO, typename T2 >
4870 struct AddTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4871 {
4872  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4873 };
4874 
4875 template< typename T1, bool SO1, typename T2, bool SO2 >
4876 struct AddTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4877 {
4878  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO1 > Type;
4879 };
4880 
4881 template< typename T1, bool SO, typename T2 >
4882 struct AddTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4883 {
4884  typedef CompressedMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4885 };
4886 
4887 template< typename T1, bool SO1, typename T2, bool SO2 >
4888 struct AddTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4889 {
4890  typedef CompressedMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4891 };
4893 //*************************************************************************************************
4894 
4895 
4896 
4897 
4898 //=================================================================================================
4899 //
4900 // SUBTRAIT SPECIALIZATIONS
4901 //
4902 //=================================================================================================
4903 
4904 //*************************************************************************************************
4906 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4907 struct SubTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4908 {
4909  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4910 };
4911 
4912 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4913 struct SubTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4914 {
4915  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO2 > Type;
4916 };
4917 
4918 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4919 struct SubTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4920 {
4921  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4922 };
4923 
4924 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4925 struct SubTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4926 {
4927  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO1 > Type;
4928 };
4929 
4930 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4931 struct SubTrait< CompressedMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
4932 {
4933  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4934 };
4935 
4936 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4937 struct SubTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
4938 {
4939  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, SO2 > Type;
4940 };
4941 
4942 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4943 struct SubTrait< HybridMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4944 {
4945  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4946 };
4947 
4948 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4949 struct SubTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4950 {
4951  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, SO1 > Type;
4952 };
4953 
4954 template< typename T1, bool SO, typename T2 >
4955 struct SubTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4956 {
4957  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4958 };
4959 
4960 template< typename T1, bool SO1, typename T2, bool SO2 >
4961 struct SubTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4962 {
4963  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO2 > Type;
4964 };
4965 
4966 template< typename T1, bool SO, typename T2 >
4967 struct SubTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4968 {
4969  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4970 };
4971 
4972 template< typename T1, bool SO1, typename T2, bool SO2 >
4973 struct SubTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4974 {
4975  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO1 > Type;
4976 };
4977 
4978 template< typename T1, bool SO, typename T2 >
4979 struct SubTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4980 {
4981  typedef CompressedMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4982 };
4983 
4984 template< typename T1, bool SO1, typename T2, bool SO2 >
4985 struct SubTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4986 {
4987  typedef CompressedMatrix< typename SubTrait<T1,T2>::Type , false > Type;
4988 };
4990 //*************************************************************************************************
4991 
4992 
4993 
4994 
4995 //=================================================================================================
4996 //
4997 // MULTTRAIT SPECIALIZATIONS
4998 //
4999 //=================================================================================================
5000 
5001 //*************************************************************************************************
5003 template< typename T1, bool SO, typename T2 >
5004 struct MultTrait< CompressedMatrix<T1,SO>, T2 >
5005 {
5006  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
5008 };
5009 
5010 template< typename T1, typename T2, bool SO >
5011 struct MultTrait< T1, CompressedMatrix<T2,SO> >
5012 {
5013  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
5015 };
5016 
5017 template< typename T1, bool SO, typename T2, size_t N >
5018 struct MultTrait< CompressedMatrix<T1,SO>, StaticVector<T2,N,false> >
5019 {
5020  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
5021 };
5022 
5023 template< typename T1, size_t N, typename T2, bool SO >
5024 struct MultTrait< StaticVector<T1,N,true>, CompressedMatrix<T2,SO> >
5025 {
5026  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
5027 };
5028 
5029 template< typename T1, bool SO, typename T2, size_t N >
5030 struct MultTrait< CompressedMatrix<T1,SO>, HybridVector<T2,N,false> >
5031 {
5032  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
5033 };
5034 
5035 template< typename T1, size_t N, typename T2, bool SO >
5036 struct MultTrait< HybridVector<T1,N,true>, CompressedMatrix<T2,SO> >
5037 {
5038  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
5039 };
5040 
5041 template< typename T1, bool SO, typename T2 >
5042 struct MultTrait< CompressedMatrix<T1,SO>, DynamicVector<T2,false> >
5043 {
5044  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
5045 };
5046 
5047 template< typename T1, typename T2, bool SO >
5048 struct MultTrait< DynamicVector<T1,true>, CompressedMatrix<T2,SO> >
5049 {
5050  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
5051 };
5052 
5053 template< typename T1, bool SO, typename T2 >
5054 struct MultTrait< CompressedMatrix<T1,SO>, CompressedVector<T2,false> >
5055 {
5056  typedef CompressedVector< typename MultTrait<T1,T2>::Type, false > Type;
5057 };
5058 
5059 template< typename T1, typename T2, bool SO >
5060 struct MultTrait< CompressedVector<T1,true>, CompressedMatrix<T2,SO> >
5061 {
5062  typedef CompressedVector< typename MultTrait<T1,T2>::Type, true > Type;
5063 };
5064 
5065 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5066 struct MultTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
5067 {
5068  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5069 };
5070 
5071 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5072 struct MultTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
5073 {
5074  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5075 };
5076 
5077 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5078 struct MultTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
5079 {
5080  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5081 };
5082 
5083 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5084 struct MultTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
5085 {
5086  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5087 };
5088 
5089 template< typename T1, bool SO1, typename T2, bool SO2 >
5090 struct MultTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
5091 {
5092  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5093 };
5094 
5095 template< typename T1, bool SO1, typename T2, bool SO2 >
5096 struct MultTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
5097 {
5098  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5099 };
5100 
5101 template< typename T1, bool SO1, typename T2, bool SO2 >
5102 struct MultTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
5103 {
5104  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5105 };
5107 //*************************************************************************************************
5108 
5109 
5110 
5111 
5112 //=================================================================================================
5113 //
5114 // DIVTRAIT SPECIALIZATIONS
5115 //
5116 //=================================================================================================
5117 
5118 //*************************************************************************************************
5120 template< typename T1, bool SO, typename T2 >
5121 struct DivTrait< CompressedMatrix<T1,SO>, T2 >
5122 {
5123  typedef CompressedMatrix< typename DivTrait<T1,T2>::Type, SO > Type;
5125 };
5127 //*************************************************************************************************
5128 
5129 
5130 
5131 
5132 //=================================================================================================
5133 //
5134 // MATHTRAIT SPECIALIZATIONS
5135 //
5136 //=================================================================================================
5137 
5138 //*************************************************************************************************
5140 template< typename T1, bool SO, typename T2 >
5141 struct MathTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
5142 {
5143  typedef CompressedMatrix< typename MathTrait<T1,T2>::HighType, SO > HighType;
5144  typedef CompressedMatrix< typename MathTrait<T1,T2>::LowType , SO > LowType;
5145 };
5147 //*************************************************************************************************
5148 
5149 
5150 
5151 
5152 //=================================================================================================
5153 //
5154 // SUBMATRIXTRAIT SPECIALIZATIONS
5155 //
5156 //=================================================================================================
5157 
5158 //*************************************************************************************************
5160 template< typename T1, bool SO >
5161 struct SubmatrixTrait< CompressedMatrix<T1,SO> >
5162 {
5163  typedef CompressedMatrix<T1,SO> Type;
5164 };
5166 //*************************************************************************************************
5167 
5168 
5169 
5170 
5171 //=================================================================================================
5172 //
5173 // ROWTRAIT SPECIALIZATIONS
5174 //
5175 //=================================================================================================
5176 
5177 //*************************************************************************************************
5179 template< typename T1, bool SO >
5180 struct RowTrait< CompressedMatrix<T1,SO> >
5181 {
5182  typedef CompressedVector<T1,true> Type;
5183 };
5185 //*************************************************************************************************
5186 
5187 
5188 
5189 
5190 //=================================================================================================
5191 //
5192 // COLUMNTRAIT SPECIALIZATIONS
5193 //
5194 //=================================================================================================
5195 
5196 //*************************************************************************************************
5198 template< typename T1, bool SO >
5199 struct ColumnTrait< CompressedMatrix<T1,SO> >
5200 {
5201  typedef CompressedVector<T1,false> Type;
5202 };
5204 //*************************************************************************************************
5205 
5206 } // namespace blaze
5207 
5208 #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.
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:994
size_t rows() const
Returns the current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:1130
void reserveElements(size_t nonzeros)
Reserving the specified number of sparse matrix elements.
Definition: CompressedMatrix.h:1826
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:421
Header file for mathematical functions.
void swap(SymmetricMatrix< MT, SO, DF, NF > &a, SymmetricMatrix< MT, SO, DF, NF > &b)
Swapping the contents of two matrices.
Definition: SymmetricMatrix.h:195
#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:260
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:261
const bool defaultStorageOrder
The default storage order for all matrices of the Blaze library.This value specifies the default stor...
Definition: StorageOrder.h:56
void move(CompressedMatrix< Type, SO > &dst, CompressedMatrix< Type, SO > &src)
Moving the contents of one compressed matrix to another.
Definition: CompressedMatrix.h:4772
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:258
Header file for the row trait.
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:258
Header file for the IsSparseMatrix type trait.
CompressedMatrix()
The default constructor for CompressedMatrix.
Definition: CompressedMatrix.h:465
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:205
size_t extendCapacity() const
Calculating a new matrix capacity.
Definition: CompressedMatrix.h:1806
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2636
void clear()
Clearing the sparse matrix.
Definition: CompressedMatrix.h:1271
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix)
Returns the maximum capacity of the matrix.
Definition: Matrix.h:348
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:257
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:316
void clear(CompressedMatrix< Type, SO > &m)
Clearing the given compressed matrix.
Definition: CompressedMatrix.h:4709
CompressedMatrix< ET, SO > Other
The type of the other CompressedMatrix.
Definition: CompressedMatrix.h:271
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2472
CompressedMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:255
#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:651
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:695
void reset(CompressedMatrix< Type, SO > &m)
Resetting the given compressed matrix.
Definition: CompressedMatrix.h:4671
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:386
Access proxy for sparse, matrices.The MatrixAccessProxy provides safe access to the elements of a no...
Definition: MatrixAccessProxy.h:95
Header file for memory allocation and deallocation functionality.
bool isAliased(const Other *alias) const
Returns whether the matrix is aliased with the given address alias.
Definition: CompressedMatrix.h:2149
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:423
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:258
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:107
Constraint on the data type.
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: CompressedMatrix.h:1193
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:2638
Header file for the SparseMatrix base class.
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:419
void reserve(size_t nonzeros)
Setting the minimum capacity of the sparse matrix.
Definition: CompressedMatrix.h:1597
void reset()
Reset to the default initial values.
Definition: CompressedMatrix.h:1233
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:259
Header file for the ValueIndexPair class.
bool isDefault(const CompressedMatrix< Type, SO > &m)
Returns whether the given compressed matrix is in default state.
Definition: CompressedMatrix.h:4736
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 compressed matrices.
Definition: CompressedMatrix.h:4754
Iterator set(size_t i, size_t j, const Type &value)
Setting an element of the compressed matrix.
Definition: CompressedMatrix.h:1295
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:2482
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:116
Header file for the IsSMPAssignable type trait.
void erase(size_t i, size_t j)
Erasing an element from the sparse matrix.
Definition: CompressedMatrix.h:1430
Iterator * end_
Pointers one past the last non-zero element of each column.
Definition: CompressedMatrix.h:2640
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:947
BLAZE_ALWAYS_INLINE 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:635
EnableIf< IsBuiltin< T > >::Type deallocate(T *address)
Deallocation of memory for built-in data types.
Definition: Memory.h:226
#define BLAZE_CONSTRAINT_MUST_HAVE_SAME_SIZE(T1, T2)
Constraint on the size of two data types.In case the types T1 and T2 don't have the same size...
Definition: SameSize.h:78
ValueIndexPair< Type > ElementBase
Base class for the sparse matrix element.
Definition: CompressedMatrix.h:209
Constraint on the data type.
Header file for the equal shim.
Header file for the default storage order for all vectors of the Blaze library.
Iterator insert(size_t i, size_t j, const Type &value)
Inserting an element into the compressed matrix.
Definition: CompressedMatrix.h:1327
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:195
CompressedMatrix< ET, true > Other
The type of the other CompressedMatrix.
Definition: CompressedMatrix.h:2490
Compile time check for floating point data types.This type trait tests whether or not the given templ...
Definition: IsFloatingPoint.h:94
Compile time check for data types.This type trait tests whether or not the given template parameter i...
Definition: IsSMPAssignable.h:120
BLAZE_ALWAYS_INLINE void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:535
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2480
void subAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the subtraction assignment of a dense matrix.
Definition: CompressedMatrix.h:2366
Header file for the EnableIf class template.
Header file for the serial shim.
void swap(CompressedMatrix &sm)
Swapping the contents of two sparse matrices.
Definition: CompressedMatrix.h:1785
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:263
bool canSMPAssign() const
Returns whether the matrix can be used in SMP assignments.
Definition: CompressedMatrix.h:2168
size_t capacity() const
Returns the maximum capacity of the sparse matrix.
Definition: CompressedMatrix.h:1158
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the sparse matrix.
Definition: CompressedMatrix.h:1516
Header file for the IsNumeric type trait.
CompressedMatrix & operator=(const CompressedMatrix &rhs)
Copy assignment operator for CompressedMatrix.
Definition: CompressedMatrix.h:864
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:116
Reference operator()(size_t i, size_t j)
2D-access to the sparse matrix elements.
Definition: CompressedMatrix.h:677
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:792
CompressedMatrix & transpose()
Transposing the matrix.
Definition: CompressedMatrix.h:1723
BLAZE_ALWAYS_INLINE 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:742
Header file for the division trait.
void trim()
Removing all excessive capacity from all rows/columns.
Definition: CompressedMatrix.h:1684
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
#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:2481
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:87
BLAZE_ALWAYS_INLINE bool isDefault(const NonNumericProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: NonNumericProxy.h:874
Constraint on the data type.
size_t columns() const
Returns the current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:1144
Constraint on the data type.
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:254
BLAZE_ALWAYS_INLINE void reset(const NonNumericProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: NonNumericProxy.h:833
Iterator * begin_
Pointers to the first non-zero element of each column.
Definition: CompressedMatrix.h:2639
void assign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the assignment of a row-major dense matrix.
Definition: CompressedMatrix.h:2190
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:262
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:2065
void finalize(size_t i)
Finalizing the element insertion of a row/column.
Definition: CompressedMatrix.h:2097
bool canAlias(const Other *alias) const
Returns whether the matrix can alias with the given address alias.
Definition: CompressedMatrix.h:2129
Base template for the DivTrait class.
Definition: DivTrait.h:142
CompressedMatrix< Type, SO > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:253
Iterator find(size_t i, size_t j)
Searches for a specific matrix element.
Definition: CompressedMatrix.h:1875
Header file for the mathematical trait.
Iterator * begin_
Pointers to the first non-zero element of each row.
Definition: CompressedMatrix.h:420
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2637
Index-value-pair for sparse vectors and matrices.The ValueIndexPair class represents a single index-v...
Definition: ValueIndexPair.h:70
Constraint on the size of two data types.
void addAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the addition assignment of a dense matrix.
Definition: CompressedMatrix.h:2314
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:932
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:256
Iterator lowerBound(size_t i, size_t j)
Returns an iterator to the first index not less then the given index.
Definition: CompressedMatrix.h:1928
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:2642
Iterator upperBound(size_t i, size_t j)
Returns an iterator to the first index greater then the given index.
Definition: CompressedMatrix.h:1979
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix)
Returns the current number of columns of the matrix.
Definition: Matrix.h:332
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:770
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2479
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:270
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:2489
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:418
ConstIterator cend(size_t i) const
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:836
Header file for the IsResizable type trait.
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:417
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Iterator begin(size_t i)
Returns an iterator to the first non-zero element of row/column i.
Definition: CompressedMatrix.h:726
BLAZE_ALWAYS_INLINE 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:849
Header file for a safe C++ NULL pointer implementation.