All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CompressedMatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_SPARSE_COMPRESSEDMATRIX_H_
36 #define _BLAZE_MATH_SPARSE_COMPRESSEDMATRIX_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <functional>
45 #include <stdexcept>
46 #include <vector>
48 #include <blaze/math/Forward.h>
49 #include <blaze/math/Functions.h>
50 #include <blaze/math/shims/Equal.h>
68 #include <blaze/util/Assert.h>
75 #include <blaze/util/EnableIf.h>
76 #include <blaze/util/Memory.h>
77 #include <blaze/util/mpl/If.h>
78 #include <blaze/util/Null.h>
79 #include <blaze/util/Types.h>
82 
83 
84 namespace blaze {
85 
86 //=================================================================================================
87 //
88 // CLASS DEFINITION
89 //
90 //=================================================================================================
91 
92 //*************************************************************************************************
197 template< typename Type // Data type of the sparse matrix
198  , bool SO = defaultStorageOrder > // Storage order
199 class CompressedMatrix : public SparseMatrix< CompressedMatrix<Type,SO>, SO >
200 {
201  private:
202  //**Type definitions****************************************************************************
204  //**********************************************************************************************
205 
206  //**Private class Element***********************************************************************
210  struct Element : public ElementBase
211  {
212  // This operator is required due to a bug in all versions of the the MSVC compiler.
213  // A simple 'using ElementBase::operator=;' statement results in ambiguity problems.
214  template< typename Other >
215  inline Element& operator=( const Other& rhs )
216  {
217  ElementBase::operator=( rhs );
218  return *this;
219  }
220 
221  friend class CompressedMatrix;
222  };
224  //**********************************************************************************************
225 
226  //**Private class FindIndex*********************************************************************
230  struct FindIndex : public std::binary_function<Element,size_t,bool>
231  {
232  inline bool operator()( const Element& element, size_t index ) const {
233  return element.index() < index;
234  }
235  inline bool operator()( size_t index, const Element& element ) const {
236  return index < element.index();
237  }
238  inline bool operator()( const Element& element1, const Element& element2 ) const {
239  return element1.index() < element2.index();
240  }
241  };
243  //**********************************************************************************************
244 
245  public:
246  //**Type definitions****************************************************************************
248  typedef This ResultType;
251  typedef Type ElementType;
252  typedef const Type& ReturnType;
253  typedef const This& CompositeType;
255  typedef const Type& ConstReference;
256  typedef Element* Iterator;
257  typedef const Element* ConstIterator;
258  //**********************************************************************************************
259 
260  //**Compilation flags***************************************************************************
262 
265  enum { smpAssignable = !IsSMPAssignable<Type>::value };
266  //**********************************************************************************************
267 
268  //**Constructors********************************************************************************
271  explicit inline CompressedMatrix();
272  explicit inline CompressedMatrix( size_t m, size_t n );
273  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
274  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
275  inline CompressedMatrix( const CompressedMatrix& sm );
276  template< typename MT, bool SO2 > inline CompressedMatrix( const DenseMatrix<MT,SO2>& dm );
277  template< typename MT, bool SO2 > inline CompressedMatrix( const SparseMatrix<MT,SO2>& sm );
279  //**********************************************************************************************
280 
281  //**Destructor**********************************************************************************
284  inline ~CompressedMatrix();
286  //**********************************************************************************************
287 
288  //**Data access functions***********************************************************************
291  inline Reference operator()( size_t i, size_t j );
292  inline ConstReference operator()( size_t i, size_t j ) const;
293  inline Iterator begin ( size_t i );
294  inline ConstIterator begin ( size_t i ) const;
295  inline ConstIterator cbegin( size_t i ) const;
296  inline Iterator end ( size_t i );
297  inline ConstIterator end ( size_t i ) const;
298  inline ConstIterator cend ( size_t i ) const;
300  //**********************************************************************************************
301 
302  //**Assignment operators************************************************************************
305  inline CompressedMatrix& operator= ( const CompressedMatrix& rhs );
306  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO2>& rhs );
307  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO2>& rhs );
308  template< typename MT, bool SO2 > inline CompressedMatrix& operator+=( const Matrix<MT,SO2>& rhs );
309  template< typename MT, bool SO2 > inline CompressedMatrix& operator-=( const Matrix<MT,SO2>& rhs );
310  template< typename MT, bool SO2 > inline CompressedMatrix& operator*=( const Matrix<MT,SO2>& rhs );
311 
312  template< typename Other >
313  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
314  operator*=( Other rhs );
315 
316  template< typename Other >
317  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
318  operator/=( Other rhs );
320  //**********************************************************************************************
321 
322  //**Utility functions***************************************************************************
325  inline size_t rows() const;
326  inline size_t columns() const;
327  inline size_t capacity() const;
328  inline size_t capacity( size_t i ) const;
329  inline size_t nonZeros() const;
330  inline size_t nonZeros( size_t i ) const;
331  inline void reset();
332  inline void reset( size_t i );
333  inline void clear();
334  Iterator insert ( size_t i, size_t j, const Type& value );
335  inline void erase ( size_t i, size_t j );
336  inline Iterator erase ( size_t i, Iterator pos );
337  inline Iterator erase ( size_t i, Iterator first, Iterator last );
338  void resize ( size_t m, size_t n, bool preserve=true );
339  inline void reserve( size_t nonzeros );
340  void reserve( size_t i, size_t nonzeros );
341  inline void trim ();
342  inline void trim ( size_t i );
343  inline CompressedMatrix& transpose();
344  template< typename Other > inline CompressedMatrix& scale( Other scalar );
345  template< typename Other > inline CompressedMatrix& scaleDiagonal( Other scalar );
346  inline void swap( CompressedMatrix& sm ) /* throw() */;
348  //**********************************************************************************************
349 
350  //**Lookup functions****************************************************************************
353  inline Iterator find ( size_t i, size_t j );
354  inline ConstIterator find ( size_t i, size_t j ) const;
355  inline Iterator lowerBound( size_t i, size_t j );
356  inline ConstIterator lowerBound( size_t i, size_t j ) const;
357  inline Iterator upperBound( size_t i, size_t j );
358  inline ConstIterator upperBound( size_t i, size_t j ) const;
360  //**********************************************************************************************
361 
362  //**Low-level utility functions*****************************************************************
365  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
366  inline void finalize( size_t i );
368  //**********************************************************************************************
369 
370  //**Expression template evaluation functions****************************************************
373  template< typename Other > inline bool canAlias ( const Other* alias ) const;
374  template< typename Other > inline bool isAliased( const Other* alias ) const;
375 
376  inline bool canSMPAssign() const;
377 
378  template< typename MT, bool SO2 > inline void assign ( const DenseMatrix<MT,SO2>& rhs );
379  template< typename MT > inline void assign ( const SparseMatrix<MT,SO>& rhs );
380  template< typename MT > inline void assign ( const SparseMatrix<MT,!SO>& rhs );
381  template< typename MT, bool SO2 > inline void addAssign( const DenseMatrix<MT,SO2>& rhs );
382  template< typename MT, bool SO2 > inline void addAssign( const SparseMatrix<MT,SO2>& rhs );
383  template< typename MT, bool SO2 > inline void subAssign( const DenseMatrix<MT,SO2>& rhs );
384  template< typename MT, bool SO2 > inline void subAssign( const SparseMatrix<MT,SO2>& rhs );
386  //**********************************************************************************************
387 
388  private:
389  //**Utility functions***************************************************************************
392  inline size_t extendCapacity() const;
393  void reserveElements( size_t nonzeros );
395  //**********************************************************************************************
396 
397  //**Member variables****************************************************************************
400  size_t m_;
401  size_t n_;
402  size_t capacity_;
405 
406  static const Type zero_;
407 
408  //**********************************************************************************************
409 
410  //**Compile time checks*************************************************************************
418  //**********************************************************************************************
419 };
420 //*************************************************************************************************
421 
422 
423 
424 
425 //=================================================================================================
426 //
427 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
428 //
429 //=================================================================================================
430 
431 template< typename Type, bool SO >
432 const Type CompressedMatrix<Type,SO>::zero_ = Type();
433 
434 
435 
436 
437 //=================================================================================================
438 //
439 // CONSTRUCTORS
440 //
441 //=================================================================================================
442 
443 //*************************************************************************************************
446 template< typename Type // Data type of the sparse matrix
447  , bool SO > // Storage order
449  : m_ ( 0UL ) // The current number of rows of the sparse matrix
450  , n_ ( 0UL ) // The current number of columns of the sparse matrix
451  , capacity_( 0UL ) // The current capacity of the pointer array
452  , begin_( new Iterator[2] ) // Pointers to the first non-zero element of each row
453  , end_ ( begin_+1 ) // Pointers one past the last non-zero element of each row
454 {
455  begin_[0] = end_[0] = NULL;
456 }
457 //*************************************************************************************************
458 
459 
460 //*************************************************************************************************
468 template< typename Type // Data type of the sparse matrix
469  , bool SO > // Storage order
471  : m_ ( m ) // The current number of rows of the sparse matrix
472  , n_ ( n ) // The current number of columns of the sparse matrix
473  , capacity_( m ) // The current capacity of the pointer array
474  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
475  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
476 {
477  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
478  begin_[i] = NULL;
479 }
480 //*************************************************************************************************
481 
482 
483 //*************************************************************************************************
492 template< typename Type // Data type of the sparse matrix
493  , bool SO > // Storage order
494 inline CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
495  : m_ ( m ) // The current number of rows of the sparse matrix
496  , n_ ( n ) // The current number of columns of the sparse matrix
497  , capacity_( m ) // The current capacity of the pointer array
498  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
499  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
500 {
501  begin_[0UL] = allocate<Element>( nonzeros );
502  for( size_t i=1UL; i<(2UL*m_+1UL); ++i )
503  begin_[i] = begin_[0UL];
504  end_[m_] = begin_[0UL]+nonzeros;
505 }
506 //*************************************************************************************************
507 
508 
509 //*************************************************************************************************
518 template< typename Type // Data type of the sparse matrix
519  , bool SO > // Storage order
520 CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
521  : m_ ( m ) // The current number of rows of the sparse matrix
522  , n_ ( n ) // The current number of columns of the sparse matrix
523  , capacity_( m ) // The current capacity of the pointer array
524  , begin_( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
525  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
526 {
527  BLAZE_USER_ASSERT( nonzeros.size() == m, "Size of capacity vector and number of rows don't match" );
528 
529  size_t newCapacity( 0UL );
530  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
531  newCapacity += *it;
532 
533  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
534  for( size_t i=0UL; i<m_; ++i ) {
535  begin_[i+1UL] = end_[i+1UL] = begin_[i] + nonzeros[i];
536  }
537 }
538 //*************************************************************************************************
539 
540 
541 //*************************************************************************************************
546 template< typename Type // Data type of the sparse matrix
547  , bool SO > // Storage order
549  : m_ ( sm.m_ ) // The current number of rows of the sparse matrix
550  , n_ ( sm.n_ ) // The current number of columns of the sparse matrix
551  , capacity_( sm.m_ ) // The current capacity of the pointer array
552  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
553  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
554 {
555  const size_t nonzeros( sm.nonZeros() );
556 
557  begin_[0UL] = allocate<Element>( nonzeros );
558  for( size_t i=0UL; i<m_; ++i )
559  begin_[i+1UL] = end_[i] = std::copy( sm.begin(i), sm.end(i), begin_[i] );
560  end_[m_] = begin_[0UL]+nonzeros;
561 }
562 //*************************************************************************************************
563 
564 
565 //*************************************************************************************************
570 template< typename Type // Data type of the sparse matrix
571  , bool SO > // Storage order
572 template< typename MT // Type of the foreign dense matrix
573  , bool SO2 > // Storage order of the foreign dense matrix
575  : m_ ( (~dm).rows() ) // The current number of rows of the sparse matrix
576  , n_ ( (~dm).columns() ) // The current number of columns of the sparse matrix
577  , capacity_( m_ ) // The current capacity of the pointer array
578  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
579  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
580 {
581  using blaze::assign;
582 
583  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
584  begin_[i] = NULL;
585 
586  assign( *this, ~dm );
587 }
588 //*************************************************************************************************
589 
590 
591 //*************************************************************************************************
596 template< typename Type // Data type of the sparse matrix
597  , bool SO > // Storage order
598 template< typename MT // Type of the foreign sparse matrix
599  , bool SO2 > // Storage order of the foreign sparse matrix
601  : m_ ( (~sm).rows() ) // The current number of rows of the sparse matrix
602  , n_ ( (~sm).columns() ) // The current number of columns of the sparse matrix
603  , capacity_( m_ ) // The current capacity of the pointer array
604  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
605  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
606 {
607  using blaze::assign;
608 
609  const size_t nonzeros( (~sm).nonZeros() );
610 
611  begin_[0UL] = allocate<Element>( nonzeros );
612  for( size_t i=0UL; i<m_; ++i )
613  begin_[i+1UL] = end_[i] = begin_[0UL];
614  end_[m_] = begin_[0UL]+nonzeros;
615 
616  assign( *this, ~sm );
617 }
618 //*************************************************************************************************
619 
620 
621 
622 
623 //=================================================================================================
624 //
625 // DESTRUCTOR
626 //
627 //=================================================================================================
628 
629 //*************************************************************************************************
632 template< typename Type // Data type of the sparse matrix
633  , bool SO > // Storage order
635 {
636  deallocate( begin_[0UL] );
637  delete [] begin_;
638 }
639 //*************************************************************************************************
640 
641 
642 
643 
644 //=================================================================================================
645 //
646 // DATA ACCESS FUNCTIONS
647 //
648 //=================================================================================================
649 
650 //*************************************************************************************************
657 template< typename Type // Data type of the sparse matrix
658  , bool SO > // Storage order
661 {
662  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
663  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
664 
665  return Reference( *this, i, j );
666 }
667 //*************************************************************************************************
668 
669 
670 //*************************************************************************************************
677 template< typename Type // Data type of the sparse matrix
678  , bool SO > // Storage order
680  CompressedMatrix<Type,SO>::operator()( size_t i, size_t j ) const
681 {
682  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
683  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
684 
685  const ConstIterator pos( lowerBound( i, j ) );
686 
687  if( pos == end_[i] || pos->index_ != j )
688  return zero_;
689  else
690  return pos->value_;
691 }
692 //*************************************************************************************************
693 
694 
695 //*************************************************************************************************
706 template< typename Type // Data type of the sparse matrix
707  , bool SO > // Storage order
710 {
711  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
712  return begin_[i];
713 }
714 //*************************************************************************************************
715 
716 
717 //*************************************************************************************************
728 template< typename Type // Data type of the sparse matrix
729  , bool SO > // Storage order
732 {
733  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
734  return begin_[i];
735 }
736 //*************************************************************************************************
737 
738 
739 //*************************************************************************************************
750 template< typename Type // Data type of the sparse matrix
751  , bool SO > // Storage order
754 {
755  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
756  return begin_[i];
757 }
758 //*************************************************************************************************
759 
760 
761 //*************************************************************************************************
772 template< typename Type // Data type of the sparse matrix
773  , bool SO > // Storage order
776 {
777  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
778  return end_[i];
779 }
780 //*************************************************************************************************
781 
782 
783 //*************************************************************************************************
794 template< typename Type // Data type of the sparse matrix
795  , bool SO > // Storage order
798 {
799  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
800  return end_[i];
801 }
802 //*************************************************************************************************
803 
804 
805 //*************************************************************************************************
816 template< typename Type // Data type of the sparse matrix
817  , bool SO > // Storage order
820 {
821  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
822  return end_[i];
823 }
824 //*************************************************************************************************
825 
826 
827 
828 
829 //=================================================================================================
830 //
831 // ASSIGNMENT OPERATORS
832 //
833 //=================================================================================================
834 
835 //*************************************************************************************************
844 template< typename Type // Data type of the sparse matrix
845  , bool SO > // Storage order
848 {
849  if( &rhs == this ) return *this;
850 
851  const size_t nonzeros( rhs.nonZeros() );
852 
853  if( rhs.m_ > capacity_ || nonzeros > capacity() )
854  {
855  Iterator* newBegin( new Iterator[2UL*rhs.m_+2UL] );
856  Iterator* newEnd ( newBegin+(rhs.m_+1UL) );
857 
858  newBegin[0UL] = allocate<Element>( nonzeros );
859  for( size_t i=0UL; i<rhs.m_; ++i ) {
860  newBegin[i+1UL] = newEnd[i] = std::copy( rhs.begin_[i], rhs.end_[i], newBegin[i] );
861  }
862  newEnd[rhs.m_] = newBegin[0UL]+nonzeros;
863 
864  std::swap( begin_, newBegin );
865  end_ = newEnd;
866  deallocate( newBegin[0UL] );
867  delete [] newBegin;
868  capacity_ = rhs.m_;
869  }
870  else {
871  for( size_t i=0UL; i<rhs.m_; ++i ) {
872  begin_[i+1UL] = end_[i] = std::copy( rhs.begin_[i], rhs.end_[i], begin_[i] );
873  }
874  }
875 
876  m_ = rhs.m_;
877  n_ = rhs.n_;
878 
879  return *this;
880 }
881 //*************************************************************************************************
882 
883 
884 //*************************************************************************************************
893 template< typename Type // Data type of the sparse matrix
894  , bool SO > // Storage order
895 template< typename MT // Type of the right-hand side dense matrix
896  , bool SO2 > // Storage order of the right-hand side dense matrix
899 {
900  using blaze::assign;
901 
902  if( (~rhs).canAlias( this ) ) {
903  CompressedMatrix tmp( rhs );
904  swap( tmp );
905  }
906  else {
907  resize( (~rhs).rows(), (~rhs).columns(), false );
908  assign( *this, ~rhs );
909  }
910 
911  return *this;
912 }
913 //*************************************************************************************************
914 
915 
916 //*************************************************************************************************
925 template< typename Type // Data type of the sparse matrix
926  , bool SO > // Storage order
927 template< typename MT // Type of the right-hand side sparse matrix
928  , bool SO2 > // Storage order of the right-hand side sparse matrix
931 {
932  using blaze::assign;
933 
934  if( (~rhs).canAlias( this ) ||
935  (~rhs).rows() > capacity_ ||
936  (~rhs).nonZeros() > capacity() ) {
937  CompressedMatrix tmp( rhs );
938  swap( tmp );
939  }
940  else {
941  resize( (~rhs).rows(), (~rhs).columns(), false );
942  reset();
943  assign( *this, ~rhs );
944  }
945 
946  return *this;
947 }
948 //*************************************************************************************************
949 
950 
951 //*************************************************************************************************
961 template< typename Type // Data type of the sparse matrix
962  , bool SO > // Storage order
963 template< typename MT // Type of the right-hand side matrix
964  , bool SO2 > // Storage order of the right-hand side matrix
967 {
968  using blaze::addAssign;
969 
970  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
971  throw std::invalid_argument( "Matrix sizes do not match" );
972 
973  addAssign( *this, ~rhs );
974  return *this;
975 }
976 //*************************************************************************************************
977 
978 
979 //*************************************************************************************************
989 template< typename Type // Data type of the sparse matrix
990  , bool SO > // Storage order
991 template< typename MT // Type of the right-hand side matrix
992  , bool SO2 > // Storage order of the right-hand side matrix
994 {
995  using blaze::subAssign;
996 
997  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
998  throw std::invalid_argument( "Matrix sizes do not match" );
999 
1000  subAssign( *this, ~rhs );
1001  return *this;
1002 }
1003 //*************************************************************************************************
1004 
1005 
1006 //*************************************************************************************************
1016 template< typename Type // Data type of the sparse matrix
1017  , bool SO > // Storage order
1018 template< typename MT // Type of the right-hand side matrix
1019  , bool SO2 > // Storage order of the right-hand side matrix
1022 {
1023  if( (~rhs).rows() != n_ )
1024  throw std::invalid_argument( "Matrix sizes do not match" );
1025 
1026  CompressedMatrix tmp( *this * (~rhs) );
1027  swap( tmp );
1028 
1029  return *this;
1030 }
1031 //*************************************************************************************************
1032 
1033 
1034 //*************************************************************************************************
1041 template< typename Type // Data type of the sparse matrix
1042  , bool SO > // Storage order
1043 template< typename Other > // Data type of the right-hand side scalar
1044 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,SO> >::Type&
1046 {
1047  for( size_t i=0UL; i<m_; ++i ) {
1048  const Iterator last( end(i) );
1049  for( Iterator element=begin(i); element!=last; ++element )
1050  element->value_ *= rhs;
1051  }
1052  return *this;
1053 }
1054 //*************************************************************************************************
1055 
1056 
1057 //*************************************************************************************************
1064 template< typename Type // Data type of the sparse matrix
1065  , bool SO > // Storage order
1066 template< typename Other > // Data type of the right-hand side scalar
1067 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,SO> >::Type&
1069 {
1070  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1071 
1072  typedef typename DivTrait<Type,Other>::Type DT;
1073  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
1074 
1075  // Depending on the two involved data types, an integer division is applied or a
1076  // floating point division is selected.
1078  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1079  for( size_t i=0UL; i<m_; ++i ) {
1080  const Iterator last( end(i) );
1081  for( Iterator element=begin(i); element!=last; ++element )
1082  element->value_ *= tmp;
1083  }
1084  }
1085  else {
1086  for( size_t i=0UL; i<m_; ++i ) {
1087  const Iterator last( end(i) );
1088  for( Iterator element=begin(i); element!=last; ++element )
1089  element->value_ /= rhs;
1090  }
1091  }
1092 
1093  return *this;
1094 }
1095 //*************************************************************************************************
1096 
1097 
1098 
1099 
1100 //=================================================================================================
1101 //
1102 // UTILITY FUNCTIONS
1103 //
1104 //=================================================================================================
1105 
1106 //*************************************************************************************************
1111 template< typename Type // Data type of the sparse matrix
1112  , bool SO > // Storage order
1113 inline size_t CompressedMatrix<Type,SO>::rows() const
1114 {
1115  return m_;
1116 }
1117 //*************************************************************************************************
1118 
1119 
1120 //*************************************************************************************************
1125 template< typename Type // Data type of the sparse matrix
1126  , bool SO > // Storage order
1128 {
1129  return n_;
1130 }
1131 //*************************************************************************************************
1132 
1133 
1134 //*************************************************************************************************
1139 template< typename Type // Data type of the sparse matrix
1140  , bool SO > // Storage order
1142 {
1143  return end_[m_] - begin_[0UL];
1144 }
1145 //*************************************************************************************************
1146 
1147 
1148 //*************************************************************************************************
1159 template< typename Type // Data type of the sparse matrix
1160  , bool SO > // Storage order
1161 inline size_t CompressedMatrix<Type,SO>::capacity( size_t i ) const
1162 {
1163  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1164  return begin_[i+1UL] - begin_[i];
1165 }
1166 //*************************************************************************************************
1167 
1168 
1169 //*************************************************************************************************
1174 template< typename Type // Data type of the sparse matrix
1175  , bool SO > // Storage order
1177 {
1178  size_t nonzeros( 0UL );
1179 
1180  for( size_t i=0UL; i<m_; ++i )
1181  nonzeros += nonZeros( i );
1182 
1183  return nonzeros;
1184 }
1185 //*************************************************************************************************
1186 
1187 
1188 //*************************************************************************************************
1199 template< typename Type // Data type of the sparse matrix
1200  , bool SO > // Storage order
1201 inline size_t CompressedMatrix<Type,SO>::nonZeros( size_t i ) const
1202 {
1203  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1204  return end_[i] - begin_[i];
1205 }
1206 //*************************************************************************************************
1207 
1208 
1209 //*************************************************************************************************
1214 template< typename Type // Data type of the sparse matrix
1215  , bool SO > // Storage order
1217 {
1218  for( size_t i=0UL; i<m_; ++i )
1219  end_[i] = begin_[i];
1220 }
1221 //*************************************************************************************************
1222 
1223 
1224 //*************************************************************************************************
1235 template< typename Type // Data type of the sparse matrix
1236  , bool SO > // Storage order
1237 inline void CompressedMatrix<Type,SO>::reset( size_t i )
1238 {
1239  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1240  end_[i] = begin_[i];
1241 }
1242 //*************************************************************************************************
1243 
1244 
1245 //*************************************************************************************************
1252 template< typename Type // Data type of the sparse matrix
1253  , bool SO > // Storage order
1255 {
1256  end_[0UL] = end_[m_];
1257  m_ = 0UL;
1258  n_ = 0UL;
1259 }
1260 //*************************************************************************************************
1261 
1262 
1263 //*************************************************************************************************
1276 template< typename Type // Data type of the sparse matrix
1277  , bool SO > // Storage order
1279  CompressedMatrix<Type,SO>::insert( size_t i, size_t j, const Type& value )
1280 {
1281  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1282  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1283 
1284  const Iterator pos( lowerBound( i, j ) );
1285 
1286  if( pos != end_[i] && pos->index_ == j )
1287  throw std::invalid_argument( "Bad access index" );
1288 
1289  if( begin_[i+1UL] - end_[i] != 0 ) {
1290  std::copy_backward( pos, end_[i], end_[i]+1 );
1291  pos->value_ = value;
1292  pos->index_ = j;
1293  ++end_[i];
1294 
1295  return pos;
1296  }
1297  else if( end_[m_] - begin_[m_] != 0 ) {
1298  std::copy_backward( pos, end_[m_-1UL], end_[m_-1UL]+1 );
1299 
1300  pos->value_ = value;
1301  pos->index_ = j;
1302 
1303  for( size_t k=i+1UL; k<m_+1UL; ++k ) {
1304  ++begin_[k];
1305  ++end_[k-1UL];
1306  }
1307 
1308  return pos;
1309  }
1310  else {
1311  size_t newCapacity( extendCapacity() );
1312 
1313  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1314  Iterator* newEnd = newBegin+capacity_+1UL;
1315 
1316  newBegin[0UL] = allocate<Element>( newCapacity );
1317 
1318  for( size_t k=0UL; k<i; ++k ) {
1319  const size_t nonzeros( end_[k] - begin_[k] );
1320  const size_t total( begin_[k+1UL] - begin_[k] );
1321  newEnd [k] = newBegin[k] + nonzeros;
1322  newBegin[k+1UL] = newBegin[k] + total;
1323  }
1324  newEnd [i] = newBegin[i] + ( end_[i] - begin_[i] ) + 1;
1325  newBegin[i+1UL] = newBegin[i] + ( begin_[i+1] - begin_[i] ) + 1;
1326  for( size_t k=i+1UL; k<m_; ++k ) {
1327  const size_t nonzeros( end_[k] - begin_[k] );
1328  const size_t total( begin_[k+1UL] - begin_[k] );
1329  newEnd [k] = newBegin[k] + nonzeros;
1330  newBegin[k+1UL] = newBegin[k] + total;
1331  }
1332 
1333  newEnd[m_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
1334 
1335  Iterator tmp = std::copy( begin_[0UL], pos, newBegin[0UL] );
1336  tmp->value_ = value;
1337  tmp->index_ = j;
1338  std::copy( pos, end_[m_-1UL], tmp+1UL );
1339 
1340  std::swap( newBegin, begin_ );
1341  end_ = newEnd;
1342  deallocate( newBegin[0UL] );
1343  delete [] newBegin;
1344 
1345  return tmp;
1346  }
1347 }
1348 //*************************************************************************************************
1349 
1350 
1351 //*************************************************************************************************
1360 template< typename Type // Data type of the sparse matrix
1361  , bool SO > // Storage order
1362 inline void CompressedMatrix<Type,SO>::erase( size_t i, size_t j )
1363 {
1364  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1365  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1366 
1367  const Iterator pos( find( i, j ) );
1368  if( pos != end_[i] )
1369  end_[i] = std::copy( pos+1, end_[i], pos );
1370 }
1371 //*************************************************************************************************
1372 
1373 
1374 //*************************************************************************************************
1385 template< typename Type // Data type of the sparse matrix
1386  , bool SO > // Storage order
1389 {
1390  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1391  BLAZE_USER_ASSERT( pos >= begin_[i] && pos <= end_[i], "Invalid compressed matrix iterator" );
1392 
1393  if( pos != end_[i] )
1394  end_[i] = std::copy( pos+1, end_[i], pos );
1395 
1396  return pos;
1397 }
1398 //*************************************************************************************************
1399 
1400 
1401 //*************************************************************************************************
1413 template< typename Type // Data type of the sparse matrix
1414  , bool SO > // Storage order
1417 {
1418  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1419  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
1420  BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i], "Invalid compressed matrix iterator" );
1421  BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i], "Invalid compressed matrix iterator" );
1422 
1423  if( first != last )
1424  end_[i] = std::copy( last, end_[i], first );
1425 
1426  return first;
1427 }
1428 //*************************************************************************************************
1429 
1430 
1431 //*************************************************************************************************
1446 template< typename Type // Data type of the sparse matrix
1447  , bool SO > // Storage order
1448 void CompressedMatrix<Type,SO>::resize( size_t m, size_t n, bool preserve )
1449 {
1450  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1451  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1452 
1453  if( m == m_ && n == n_ ) return;
1454 
1455  if( m > capacity_ )
1456  {
1457  Iterator* newBegin( new Iterator[2UL*m+2UL] );
1458  Iterator* newEnd ( newBegin+m+1UL );
1459 
1460  newBegin[0UL] = begin_[0UL];
1461 
1462  if( preserve ) {
1463  for( size_t i=0UL; i<m_; ++i ) {
1464  newEnd [i] = end_ [i];
1465  newBegin[i+1UL] = begin_[i+1UL];
1466  }
1467  for( size_t i=m_; i<m; ++i ) {
1468  newBegin[i+1UL] = newEnd[i] = begin_[m_];
1469  }
1470  }
1471  else {
1472  for( size_t i=0UL; i<m; ++i ) {
1473  newBegin[i+1UL] = newEnd[i] = begin_[0UL];
1474  }
1475  }
1476 
1477  newEnd[m] = end_[m_];
1478 
1479  std::swap( newBegin, begin_ );
1480  delete [] newBegin;
1481 
1482  end_ = newEnd;
1483  capacity_ = m;
1484  }
1485  else if( m > m_ )
1486  {
1487  end_[m] = end_[m_];
1488 
1489  if( !preserve ) {
1490  for( size_t i=0UL; i<m_; ++i )
1491  end_[i] = begin_[i];
1492  }
1493 
1494  for( size_t i=m_; i<m; ++i )
1495  begin_[i+1UL] = end_[i] = begin_[m_];
1496  }
1497  else
1498  {
1499  if( preserve ) {
1500  for( size_t i=0UL; i<m; ++i )
1501  end_[i] = lowerBound( i, n );
1502  }
1503  else {
1504  for( size_t i=0UL; i<m; ++i )
1505  end_[i] = begin_[i];
1506  }
1507 
1508  end_[m] = end_[m_];
1509  }
1510 
1511  m_ = m;
1512  n_ = n;
1513 }
1514 //*************************************************************************************************
1515 
1516 
1517 //*************************************************************************************************
1527 template< typename Type // Data type of the sparse matrix
1528  , bool SO > // Storage order
1529 inline void CompressedMatrix<Type,SO>::reserve( size_t nonzeros )
1530 {
1531  if( nonzeros > capacity() )
1532  reserveElements( nonzeros );
1533 }
1534 //*************************************************************************************************
1535 
1536 
1537 //*************************************************************************************************
1551 template< typename Type // Data type of the sparse matrix
1552  , bool SO > // Storage order
1553 void CompressedMatrix<Type,SO>::reserve( size_t i, size_t nonzeros )
1554 {
1555  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1556 
1557  const size_t current( capacity(i) );
1558 
1559  if( current >= nonzeros ) return;
1560 
1561  const ptrdiff_t additional( nonzeros - current );
1562 
1563  if( end_[m_] - begin_[m_] < additional )
1564  {
1565  const size_t newCapacity( begin_[m_] - begin_[0UL] + additional );
1566  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
1567 
1568  Iterator* newBegin( new Iterator[2UL*m_+2UL] );
1569  Iterator* newEnd ( newBegin+m_+1UL );
1570 
1571  newBegin[0UL] = allocate<Element>( newCapacity );
1572  newEnd [m_ ] = newBegin[0UL]+newCapacity;
1573 
1574  for( size_t k=0UL; k<i; ++k ) {
1575  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
1576  newBegin[k+1UL] = newBegin[k] + capacity(k);
1577  }
1578  newEnd [i ] = std::copy( begin_[i], end_[i], newBegin[i] );
1579  newBegin[i+1UL] = newBegin[i] + nonzeros;
1580  for( size_t k=i+1UL; k<m_; ++k ) {
1581  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
1582  newBegin[k+1UL] = newBegin[k] + capacity(k);
1583  }
1584 
1585  BLAZE_INTERNAL_ASSERT( newBegin[m_] == newEnd[m_], "Invalid pointer calculations" );
1586 
1587  std::swap( newBegin, begin_ );
1588  deallocate( newBegin[0UL] );
1589  delete [] newBegin;
1590  end_ = newEnd;
1591  }
1592  else
1593  {
1594  begin_[m_] += additional;
1595  for( size_t j=m_-1UL; j>i; --j ) {
1596  begin_[j] = std::copy_backward( begin_[j], end_[j], end_[j]+additional );
1597  end_ [j] += additional;
1598  }
1599  }
1600 }
1601 //*************************************************************************************************
1602 
1603 
1604 //*************************************************************************************************
1614 template< typename Type // Data type of the sparse matrix
1615  , bool SO > // Storage order
1617 {
1618  for( size_t i=0UL; i<m_; ++i )
1619  trim( i );
1620 }
1621 //*************************************************************************************************
1622 
1623 
1624 //*************************************************************************************************
1635 template< typename Type // Data type of the sparse matrix
1636  , bool SO > // Storage order
1638 {
1639  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1640 
1641  if( i < ( m_ - 1UL ) )
1642  end_[i+1] = std::copy( begin_[i+1], end_[i+1], end_[i] );
1643  begin_[i+1] = end_[i];
1644 }
1645 //*************************************************************************************************
1646 
1647 
1648 //*************************************************************************************************
1653 template< typename Type // Data type of the sparse matrix
1654  , bool SO > // Storage order
1656 {
1657  CompressedMatrix tmp( trans( *this ) );
1658  swap( tmp );
1659  return *this;
1660 }
1661 //*************************************************************************************************
1662 
1663 
1664 //*************************************************************************************************
1670 template< typename Type // Data type of the sparse matrix
1671  , bool SO > // Storage order
1672 template< typename Other > // Data type of the scalar value
1674 {
1675  for( size_t i=0UL; i<m_; ++i )
1676  for( Iterator element=begin_[i]; element!=end_[i]; ++element )
1677  element->value_ *= scalar;
1678 
1679  return *this;
1680 }
1681 //*************************************************************************************************
1682 
1683 
1684 //*************************************************************************************************
1690 template< typename Type // Data type of the sparse matrix
1691  , bool SO > // Storage order
1692 template< typename Other > // Data type of the scalar value
1694 {
1695  const size_t size( blaze::min( m_, n_ ) );
1696 
1697  for( size_t i=0UL; i<size; ++i ) {
1698  Iterator pos = lowerBound( i, i );
1699  if( pos != end_[i] && pos->index_ == i )
1700  pos->value_ *= scalar;
1701  }
1702 
1703  return *this;
1704 }
1705 //*************************************************************************************************
1706 
1707 
1708 //*************************************************************************************************
1715 template< typename Type // Data type of the sparse matrix
1716  , bool SO > // Storage order
1717 inline void CompressedMatrix<Type,SO>::swap( CompressedMatrix& sm ) /* throw() */
1718 {
1719  std::swap( m_, sm.m_ );
1720  std::swap( n_, sm.n_ );
1721  std::swap( capacity_, sm.capacity_ );
1722  std::swap( begin_, sm.begin_ );
1723  std::swap( end_ , sm.end_ );
1724 }
1725 //*************************************************************************************************
1726 
1727 
1728 //*************************************************************************************************
1736 template< typename Type // Data type of the sparse matrix
1737  , bool SO > // Storage order
1739 {
1740  size_t nonzeros( 2UL*capacity()+1UL );
1741  nonzeros = blaze::max( nonzeros, 7UL );
1742 
1743  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
1744 
1745  return nonzeros;
1746 }
1747 //*************************************************************************************************
1748 
1749 
1750 //*************************************************************************************************
1756 template< typename Type // Data type of the sparse matrix
1757  , bool SO > // Storage order
1759 {
1760  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1761  Iterator* newEnd = newBegin+capacity_+1UL;
1762 
1763  newBegin[0UL] = allocate<Element>( nonzeros );
1764 
1765  for( size_t k=0UL; k<m_; ++k ) {
1766  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid row pointers" );
1767  newEnd [k] = std::copy( begin_[k], end_[k], newBegin[k] );
1768  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
1769  }
1770 
1771  newEnd[m_] = newBegin[0UL]+nonzeros;
1772 
1773  std::swap( newBegin, begin_ );
1774  deallocate( newBegin[0UL] );
1775  delete [] newBegin;
1776  end_ = newEnd;
1777 }
1778 //*************************************************************************************************
1779 
1780 
1781 
1782 
1783 //=================================================================================================
1784 //
1785 // LOOKUP FUNCTIONS
1786 //
1787 //=================================================================================================
1788 
1789 //*************************************************************************************************
1804 template< typename Type // Data type of the sparse matrix
1805  , bool SO > // Storage order
1807  CompressedMatrix<Type,SO>::find( size_t i, size_t j )
1808 {
1809  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
1810 }
1811 //*************************************************************************************************
1812 
1813 
1814 //*************************************************************************************************
1829 template< typename Type // Data type of the sparse matrix
1830  , bool SO > // Storage order
1832  CompressedMatrix<Type,SO>::find( size_t i, size_t j ) const
1833 {
1834  const ConstIterator pos( lowerBound( i, j ) );
1835  if( pos != end_[i] && pos->index_ == j )
1836  return pos;
1837  else return end_[i];
1838 }
1839 //*************************************************************************************************
1840 
1841 
1842 //*************************************************************************************************
1857 template< typename Type // Data type of the sparse matrix
1858  , bool SO > // Storage order
1861 {
1862  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
1863 }
1864 //*************************************************************************************************
1865 
1866 
1867 //*************************************************************************************************
1882 template< typename Type // Data type of the sparse matrix
1883  , bool SO > // Storage order
1885  CompressedMatrix<Type,SO>::lowerBound( size_t i, size_t j ) const
1886 {
1887  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1888  return std::lower_bound( begin_[i], end_[i], j, FindIndex() );
1889 }
1890 //*************************************************************************************************
1891 
1892 
1893 //*************************************************************************************************
1908 template< typename Type // Data type of the sparse matrix
1909  , bool SO > // Storage order
1912 {
1913  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
1914 }
1915 //*************************************************************************************************
1916 
1917 
1918 //*************************************************************************************************
1933 template< typename Type // Data type of the sparse matrix
1934  , bool SO > // Storage order
1936  CompressedMatrix<Type,SO>::upperBound( size_t i, size_t j ) const
1937 {
1938  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1939  return std::upper_bound( begin_[i], end_[i], j, FindIndex() );
1940 }
1941 //*************************************************************************************************
1942 
1943 
1944 
1945 
1946 //=================================================================================================
1947 //
1948 // LOW-LEVEL UTILITY FUNCTIONS
1949 //
1950 //=================================================================================================
1951 
1952 //*************************************************************************************************
1995 template< typename Type // Data type of the sparse matrix
1996  , bool SO > // Storage order
1997 inline void CompressedMatrix<Type,SO>::append( size_t i, size_t j, const Type& value, bool check )
1998 {
1999  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2000  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
2001  BLAZE_USER_ASSERT( end_[i] < end_[m_], "Not enough reserved space left" );
2002  BLAZE_USER_ASSERT( begin_[i] == end_[i] || j > ( end_[i]-1UL )->index_, "Index is not strictly increasing" );
2003 
2004  end_[i]->value_ = value;
2005 
2006  if( !check || !isDefault( end_[i]->value_ ) ) {
2007  end_[i]->index_ = j;
2008  ++end_[i];
2009  }
2010 }
2011 //*************************************************************************************************
2012 
2013 
2014 //*************************************************************************************************
2027 template< typename Type // Data type of the sparse matrix
2028  , bool SO > // Storage order
2030 {
2031  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2032 
2033  begin_[i+1UL] = end_[i];
2034  if( i != m_-1UL )
2035  end_[i+1UL] = end_[i];
2036 }
2037 //*************************************************************************************************
2038 
2039 
2040 
2041 
2042 //=================================================================================================
2043 //
2044 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2045 //
2046 //=================================================================================================
2047 
2048 //*************************************************************************************************
2058 template< typename Type // Data type of the sparse matrix
2059  , bool SO > // Storage order
2060 template< typename Other > // Data type of the foreign expression
2061 inline bool CompressedMatrix<Type,SO>::canAlias( const Other* alias ) const
2062 {
2063  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2064 }
2065 //*************************************************************************************************
2066 
2067 
2068 //*************************************************************************************************
2078 template< typename Type // Data type of the sparse matrix
2079  , bool SO > // Storage order
2080 template< typename Other > // Data type of the foreign expression
2081 inline bool CompressedMatrix<Type,SO>::isAliased( const Other* alias ) const
2082 {
2083  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2084 }
2085 //*************************************************************************************************
2086 
2087 
2088 //*************************************************************************************************
2098 template< typename Type // Data type of the sparse matrix
2099  , bool SO > // Storage order
2101 {
2102  return false;
2103 }
2104 //*************************************************************************************************
2105 
2106 
2107 //*************************************************************************************************
2118 template< typename Type // Data type of the sparse matrix
2119  , bool SO > // Storage order
2120 template< typename MT // Type of the right-hand side dense matrix
2121  , bool SO2 > // Storage order of the right-hand side dense matrix
2123 {
2124  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2125  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2126 
2127  size_t nonzeros( 0UL );
2128 
2129  for( size_t i=1UL; i<=m_; ++i )
2130  begin_[i] = end_[i] = end_[m_];
2131 
2132  for( size_t i=0UL; i<m_; ++i )
2133  {
2134  begin_[i] = end_[i] = begin_[0UL]+nonzeros;
2135 
2136  for( size_t j=0UL; j<n_; ++j )
2137  {
2138  if( nonzeros == capacity() ) {
2139  reserveElements( extendCapacity() );
2140  for( size_t k=i+1UL; k<=m_; ++k )
2141  begin_[k] = end_[k] = end_[m_];
2142  }
2143 
2144  end_[i]->value_ = (~rhs)(i,j);
2145 
2146  if( !isDefault( end_[i]->value_ ) ) {
2147  end_[i]->index_ = j;
2148  ++end_[i];
2149  ++nonzeros;
2150  }
2151  }
2152  }
2153 
2154  begin_[m_] = begin_[0UL]+nonzeros;
2155 }
2156 //*************************************************************************************************
2157 
2158 
2159 //*************************************************************************************************
2170 template< typename Type // Data type of the sparse matrix
2171  , bool SO > // Storage order
2172 template< typename MT > // Type of the right-hand side sparse matrix
2174 {
2175  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2176  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2177  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2178 
2179  for( size_t i=0UL; i<(~rhs).rows(); ++i ) {
2180  begin_[i+1UL] = end_[i] = std::copy( (~rhs).begin(i), (~rhs).end(i), begin_[i] );
2181  }
2182 }
2183 //*************************************************************************************************
2184 
2185 
2186 //*************************************************************************************************
2197 template< typename Type // Data type of the sparse matrix
2198  , bool SO > // Storage order
2199 template< typename MT > // Type of the right-hand side sparse matrix
2201 {
2202  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2203  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2204  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2205 
2206  typedef typename MT::ConstIterator RhsIterator;
2207 
2208  // Counting the number of elements per row
2209  std::vector<size_t> rowLengths( m_, 0UL );
2210  for( size_t j=0UL; j<n_; ++j ) {
2211  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2212  ++rowLengths[element->index()];
2213  }
2214 
2215  // Resizing the sparse matrix
2216  for( size_t i=0UL; i<m_; ++i ) {
2217  begin_[i+1UL] = end_[i+1UL] = begin_[i] + rowLengths[i];
2218  }
2219 
2220  // Appending the elements to the rows of the sparse matrix
2221  for( size_t j=0UL; j<n_; ++j ) {
2222  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2223  append( element->index(), j, element->value() );
2224  }
2225 }
2226 //*************************************************************************************************
2227 
2228 
2229 //*************************************************************************************************
2240 template< typename Type // Data type of the sparse matrix
2241  , bool SO > // Storage order
2242 template< typename MT // Type of the right-hand side dense matrix
2243  , bool SO2 > // Storage order of the right-hand side dense matrix
2245 {
2246  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2247  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2248 
2249  CompressedMatrix tmp( serial( *this + (~rhs) ) );
2250  swap( tmp );
2251 }
2252 //*************************************************************************************************
2253 
2254 
2255 //*************************************************************************************************
2266 template< typename Type // Data type of the sparse matrix
2267  , bool SO > // Storage order
2268 template< typename MT // Type of the right-hand side sparse matrix
2269  , bool SO2 > // Storage order of the right-hand side sparse matrix
2271 {
2272  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2273  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2274 
2275  CompressedMatrix tmp( serial( *this + (~rhs) ) );
2276  swap( tmp );
2277 }
2278 //*************************************************************************************************
2279 
2280 
2281 //*************************************************************************************************
2292 template< typename Type // Data type of the sparse matrix
2293  , bool SO > // Storage order
2294 template< typename MT // Type of the right-hand side dense matrix
2295  , bool SO2 > // Storage order of the right-hand side dense matrix
2297 {
2298  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2299  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2300 
2301  CompressedMatrix tmp( serial( *this - (~rhs) ) );
2302  swap( tmp );
2303 }
2304 //*************************************************************************************************
2305 
2306 
2307 //*************************************************************************************************
2318 template< typename Type // Data type of the sparse matrix
2319  , bool SO > // Storage order
2320 template< typename MT // Type of the right-hand side sparse matrix
2321  , bool SO2 > // Storage order of the right-hand sparse matrix
2323 {
2324  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2325  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2326 
2327  CompressedMatrix tmp( serial( *this - (~rhs) ) );
2328  swap( tmp );
2329 }
2330 //*************************************************************************************************
2331 
2332 
2333 
2334 
2335 
2336 
2337 
2338 
2339 //=================================================================================================
2340 //
2341 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2342 //
2343 //=================================================================================================
2344 
2345 //*************************************************************************************************
2353 template< typename Type > // Data type of the sparse matrix
2354 class CompressedMatrix<Type,true> : public SparseMatrix< CompressedMatrix<Type,true>, true >
2355 {
2356  private:
2357  //**Type definitions****************************************************************************
2359  //**********************************************************************************************
2360 
2361  //**Private class Element***********************************************************************
2365  struct Element : public ElementBase
2366  {
2367  // This operator is required due to a bug in all versions of the the MSVC compiler.
2368  // A simple 'using ElementBase::operator=;' statement results in ambiguity problems.
2369  template< typename Other >
2370  inline Element& operator=( const Other& rhs )
2371  {
2372  ElementBase::operator=( rhs );
2373  return *this;
2374  }
2375 
2376  friend class CompressedMatrix;
2377  };
2379  //**********************************************************************************************
2380 
2381  //**Private class FindIndex*********************************************************************
2385  struct FindIndex : public std::binary_function<Element,size_t,bool>
2386  {
2387  inline bool operator()( const Element& element, size_t index ) const {
2388  return element.index() < index;
2389  }
2390  inline bool operator()( size_t index, const Element& element ) const {
2391  return index < element.index();
2392  }
2393  inline bool operator()( const Element& element1, const Element& element2 ) const {
2394  return element1.index() < element2.index();
2395  }
2396  };
2398  //**********************************************************************************************
2399 
2400  public:
2401  //**Type definitions****************************************************************************
2403  typedef This ResultType;
2406  typedef Type ElementType;
2407  typedef const Type& ReturnType;
2408  typedef const This& CompositeType;
2410  typedef const Type& ConstReference;
2411  typedef Element* Iterator;
2412  typedef const Element* ConstIterator;
2413  //**********************************************************************************************
2414 
2415  //**Compilation flags***************************************************************************
2417 
2420  enum { smpAssignable = !IsSMPAssignable<Type>::value };
2421  //**********************************************************************************************
2422 
2423  //**Constructors********************************************************************************
2426  explicit inline CompressedMatrix();
2427  explicit inline CompressedMatrix( size_t m, size_t n );
2428  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
2429  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
2430  inline CompressedMatrix( const CompressedMatrix& sm );
2431  template< typename MT, bool SO > inline CompressedMatrix( const DenseMatrix<MT,SO>& dm );
2432  template< typename MT, bool SO > inline CompressedMatrix( const SparseMatrix<MT,SO>& sm );
2434  //**********************************************************************************************
2435 
2436  //**Destructor**********************************************************************************
2439  inline ~CompressedMatrix();
2441  //**********************************************************************************************
2442 
2443  //**Data access functions***********************************************************************
2446  inline Reference operator()( size_t i, size_t j );
2447  inline ConstReference operator()( size_t i, size_t j ) const;
2448  inline Iterator begin ( size_t i );
2449  inline ConstIterator begin ( size_t i ) const;
2450  inline ConstIterator cbegin( size_t i ) const;
2451  inline Iterator end ( size_t i );
2452  inline ConstIterator end ( size_t i ) const;
2453  inline ConstIterator cend ( size_t i ) const;
2455  //**********************************************************************************************
2456 
2457  //**Assignment operators************************************************************************
2460  inline CompressedMatrix& operator= ( const CompressedMatrix& rhs );
2461  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO>& rhs );
2462  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO>& rhs );
2463  template< typename MT, bool SO > inline CompressedMatrix& operator+=( const Matrix<MT,SO>& rhs );
2464  template< typename MT, bool SO > inline CompressedMatrix& operator-=( const Matrix<MT,SO>& rhs );
2465  template< typename MT, bool SO > inline CompressedMatrix& operator*=( const Matrix<MT,SO>& rhs );
2466 
2467  template< typename Other >
2468  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
2469  operator*=( Other rhs );
2470 
2471  template< typename Other >
2472  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
2473  operator/=( Other rhs );
2475  //**********************************************************************************************
2476 
2477  //**Utility functions***************************************************************************
2480  inline size_t rows() const;
2481  inline size_t columns() const;
2482  inline size_t capacity() const;
2483  inline size_t capacity( size_t j ) const;
2484  inline size_t nonZeros() const;
2485  inline size_t nonZeros( size_t j ) const;
2486  inline void reset();
2487  inline void reset( size_t j );
2488  inline void clear();
2489  Iterator insert ( size_t i, size_t j, const Type& value );
2490  inline void erase ( size_t i, size_t j );
2491  inline Iterator erase ( size_t j, Iterator pos );
2492  inline Iterator erase ( size_t j, Iterator first, Iterator last );
2493  void resize ( size_t m, size_t n, bool preserve=true );
2494  inline void reserve( size_t nonzeros );
2495  void reserve( size_t j, size_t nonzeros );
2496  inline void trim ();
2497  inline void trim ( size_t j );
2498  inline CompressedMatrix& transpose();
2499  template< typename Other > inline CompressedMatrix& scale( Other scalar );
2500  template< typename Other > inline CompressedMatrix& scaleDiagonal( Other scalar );
2501  inline void swap( CompressedMatrix& sm ) /* throw() */;
2503  //**********************************************************************************************
2504 
2505  //**Lookup functions****************************************************************************
2508  inline Iterator find ( size_t i, size_t j );
2509  inline ConstIterator find ( size_t i, size_t j ) const;
2510  inline Iterator lowerBound( size_t i, size_t j );
2511  inline ConstIterator lowerBound( size_t i, size_t j ) const;
2512  inline Iterator upperBound( size_t i, size_t j );
2513  inline ConstIterator upperBound( size_t i, size_t j ) const;
2515  //**********************************************************************************************
2516 
2517  //**Low-level utility functions*****************************************************************
2520  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
2521  inline void finalize( size_t j );
2523  //**********************************************************************************************
2524 
2525  //**Expression template evaluation functions****************************************************
2528  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2529  template< typename Other > inline bool isAliased( const Other* alias ) const;
2530 
2531  inline bool canSMPAssign() const;
2532 
2533  template< typename MT, bool SO > inline void assign ( const DenseMatrix<MT,SO>& rhs );
2534  template< typename MT > inline void assign ( const SparseMatrix<MT,true>& rhs );
2535  template< typename MT > inline void assign ( const SparseMatrix<MT,false>& rhs );
2536  template< typename MT, bool SO > inline void addAssign( const DenseMatrix<MT,SO>& rhs );
2537  template< typename MT, bool SO > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
2538  template< typename MT, bool SO > inline void subAssign( const DenseMatrix<MT,SO>& rhs );
2539  template< typename MT, bool SO > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
2541  //**********************************************************************************************
2542 
2543  private:
2544  //**Utility functions***************************************************************************
2547  inline size_t extendCapacity() const;
2548  void reserveElements( size_t nonzeros );
2550  //**********************************************************************************************
2551 
2552  //**Member variables****************************************************************************
2555  size_t m_;
2556  size_t n_;
2557  size_t capacity_;
2560 
2561  static const Type zero_;
2562 
2563  //**********************************************************************************************
2564 
2565  //**Compile time checks*************************************************************************
2573  //**********************************************************************************************
2574 };
2576 //*************************************************************************************************
2577 
2578 
2579 
2580 
2581 //=================================================================================================
2582 //
2583 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
2584 //
2585 //=================================================================================================
2586 
2587 template< typename Type >
2588 const Type CompressedMatrix<Type,true>::zero_ = Type();
2589 
2590 
2591 
2592 
2593 //=================================================================================================
2594 //
2595 // CONSTRUCTORS
2596 //
2597 //=================================================================================================
2598 
2599 //*************************************************************************************************
2603 template< typename Type > // Data type of the sparse matrix
2605  : m_ ( 0UL ) // The current number of rows of the sparse matrix
2606  , n_ ( 0UL ) // The current number of columns of the sparse matrix
2607  , capacity_( 0UL ) // The current capacity of the pointer array
2608  , begin_( new Iterator[2UL] ) // Pointers to the first non-zero element of each column
2609  , end_ ( begin_+1UL ) // Pointers one past the last non-zero element of each column
2610 {
2611  begin_[0UL] = end_[0UL] = NULL;
2612 }
2614 //*************************************************************************************************
2615 
2616 
2617 //*************************************************************************************************
2626 template< typename Type > // Data type of the sparse matrix
2627 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n )
2628  : m_ ( m ) // The current number of rows of the sparse matrix
2629  , n_ ( n ) // The current number of columns of the sparse matrix
2630  , capacity_( n ) // The current capacity of the pointer array
2631  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
2632  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
2633 {
2634  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
2635  begin_[j] = NULL;
2636 }
2638 //*************************************************************************************************
2639 
2640 
2641 //*************************************************************************************************
2651 template< typename Type > // Data type of the sparse matrix
2652 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
2653  : m_ ( m ) // The current number of rows of the sparse matrix
2654  , n_ ( n ) // The current number of columns of the sparse matrix
2655  , capacity_( n ) // The current capacity of the pointer array
2656  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
2657  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
2658 {
2659  begin_[0UL] = allocate<Element>( nonzeros );
2660  for( size_t j=1UL; j<(2UL*n_+1UL); ++j )
2661  begin_[j] = begin_[0UL];
2662  end_[n_] = begin_[0UL]+nonzeros;
2663 }
2665 //*************************************************************************************************
2666 
2667 
2668 //*************************************************************************************************
2678 template< typename Type > // Data type of the sparse matrix
2679 CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
2680  : m_ ( m ) // The current number of rows of the sparse matrix
2681  , n_ ( n ) // The current number of columns of the sparse matrix
2682  , capacity_( n ) // The current capacity of the pointer array
2683  , begin_( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2684  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2685 {
2686  BLAZE_USER_ASSERT( nonzeros.size() == n, "Size of capacity vector and number of columns don't match" );
2687 
2688  size_t newCapacity( 0UL );
2689  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
2690  newCapacity += *it;
2691 
2692  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
2693  for( size_t j=0UL; j<n_; ++j ) {
2694  begin_[j+1UL] = end_[j+1UL] = begin_[j] + nonzeros[j];
2695  }
2696 }
2698 //*************************************************************************************************
2699 
2700 
2701 //*************************************************************************************************
2707 template< typename Type > // Data type of the sparse matrix
2708 inline CompressedMatrix<Type,true>::CompressedMatrix( const CompressedMatrix& sm )
2709  : m_ ( sm.m_ ) // The current number of rows of the sparse matrix
2710  , n_ ( sm.n_ ) // The current number of columns of the sparse matrix
2711  , capacity_( sm.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  const size_t nonzeros( sm.nonZeros() );
2716 
2717  begin_[0UL] = allocate<Element>( nonzeros );
2718  for( size_t j=0UL; j<n_; ++j )
2719  begin_[j+1UL] = end_[j] = std::copy( sm.begin(j), sm.end(j), begin_[j] );
2720  end_[n_] = begin_[0UL]+nonzeros;
2721 }
2723 //*************************************************************************************************
2724 
2725 
2726 //*************************************************************************************************
2732 template< typename Type > // Data type of the sparse matrix
2733 template< typename MT // Type of the foreign dense matrix
2734  , bool SO > // Storage order of the foreign dense matrix
2735 inline CompressedMatrix<Type,true>::CompressedMatrix( const DenseMatrix<MT,SO>& dm )
2736  : m_ ( (~dm).rows() ) // The current number of rows of the sparse matrix
2737  , n_ ( (~dm).columns() ) // The current number of columns of the sparse matrix
2738  , capacity_( n_ ) // The current capacity of the pointer array
2739  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2740  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2741 {
2742  using blaze::assign;
2743 
2744  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
2745  begin_[j] = NULL;
2746 
2747  assign( *this, ~dm );
2748 }
2750 //*************************************************************************************************
2751 
2752 
2753 //*************************************************************************************************
2759 template< typename Type > // Data type of the sparse matrix
2760 template< typename MT // Type of the foreign sparse matrix
2761  , bool SO > // Storage order of the foreign sparse matrix
2762 inline CompressedMatrix<Type,true>::CompressedMatrix( const SparseMatrix<MT,SO>& sm )
2763  : m_ ( (~sm).rows() ) // The current number of rows of the sparse matrix
2764  , n_ ( (~sm).columns() ) // The current number of columns of the sparse matrix
2765  , capacity_( n_ ) // The current capacity of the pointer array
2766  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2767  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2768 {
2769  using blaze::assign;
2770 
2771  const size_t nonzeros( (~sm).nonZeros() );
2772 
2773  begin_[0UL] = allocate<Element>( nonzeros );
2774  for( size_t j=0UL; j<n_; ++j )
2775  begin_[j+1UL] = end_[j] = begin_[0UL];
2776  end_[n_] = begin_[0UL]+nonzeros;
2777 
2778  assign( *this, ~sm );
2779 }
2781 //*************************************************************************************************
2782 
2783 
2784 
2785 
2786 //=================================================================================================
2787 //
2788 // DESTRUCTOR
2789 //
2790 //=================================================================================================
2791 
2792 //*************************************************************************************************
2796 template< typename Type > // Data type of the sparse matrix
2797 inline CompressedMatrix<Type,true>::~CompressedMatrix()
2798 {
2799  deallocate( begin_[0UL] );
2800  delete [] begin_;
2801 }
2803 //*************************************************************************************************
2804 
2805 
2806 
2807 
2808 //=================================================================================================
2809 //
2810 // DATA ACCESS FUNCTIONS
2811 //
2812 //=================================================================================================
2813 
2814 //*************************************************************************************************
2822 template< typename Type > // Data type of the sparse matrix
2824  CompressedMatrix<Type,true>::operator()( size_t i, size_t j )
2825 {
2826  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2827  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2828 
2829  return Reference( *this, i, j );
2830 }
2832 //*************************************************************************************************
2833 
2834 
2835 //*************************************************************************************************
2843 template< typename Type > // Data type of the sparse matrix
2845  CompressedMatrix<Type,true>::operator()( size_t i, size_t j ) const
2846 {
2847  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2848  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2849 
2850  const ConstIterator pos( lowerBound( i, j ) );
2851 
2852  if( pos == end_[j] || pos->index_ != i )
2853  return zero_;
2854  else
2855  return pos->value_;
2856 }
2858 //*************************************************************************************************
2859 
2860 
2861 //*************************************************************************************************
2868 template< typename Type > // Data type of the sparse matrix
2870  CompressedMatrix<Type,true>::begin( size_t j )
2871 {
2872  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2873  return begin_[j];
2874 }
2876 //*************************************************************************************************
2877 
2878 
2879 //*************************************************************************************************
2886 template< typename Type > // Data type of the sparse matrix
2888  CompressedMatrix<Type,true>::begin( size_t j ) const
2889 {
2890  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2891  return begin_[j];
2892 }
2894 //*************************************************************************************************
2895 
2896 
2897 //*************************************************************************************************
2904 template< typename Type > // Data type of the sparse matrix
2906  CompressedMatrix<Type,true>::cbegin( size_t j ) const
2907 {
2908  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2909  return begin_[j];
2910 }
2912 //*************************************************************************************************
2913 
2914 
2915 //*************************************************************************************************
2922 template< typename Type > // Data type of the sparse matrix
2924  CompressedMatrix<Type,true>::end( size_t j )
2925 {
2926  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2927  return end_[j];
2928 }
2930 //*************************************************************************************************
2931 
2932 
2933 //*************************************************************************************************
2940 template< typename Type > // Data type of the sparse matrix
2942  CompressedMatrix<Type,true>::end( size_t j ) const
2943 {
2944  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2945  return end_[j];
2946 }
2948 //*************************************************************************************************
2949 
2950 
2951 //*************************************************************************************************
2958 template< typename Type > // Data type of the sparse matrix
2960  CompressedMatrix<Type,true>::cend( size_t j ) const
2961 {
2962  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2963  return end_[j];
2964 }
2966 //*************************************************************************************************
2967 
2968 
2969 
2970 
2971 //=================================================================================================
2972 //
2973 // ASSIGNMENT OPERATORS
2974 //
2975 //=================================================================================================
2976 
2977 //*************************************************************************************************
2987 template< typename Type > // Data type of the sparse matrix
2988 inline CompressedMatrix<Type,true>&
2989  CompressedMatrix<Type,true>::operator=( const CompressedMatrix& rhs )
2990 {
2991  if( &rhs == this ) return *this;
2992 
2993  const size_t nonzeros( rhs.nonZeros() );
2994 
2995  if( rhs.n_ > capacity_ || nonzeros > capacity() )
2996  {
2997  Iterator* newBegin( new Iterator[2UL*rhs.n_+2UL] );
2998  Iterator* newEnd ( newBegin+(rhs.n_+1UL) );
2999 
3000  newBegin[0UL] = allocate<Element>( nonzeros );
3001  for( size_t j=0UL; j<rhs.n_; ++j ) {
3002  newBegin[j+1UL] = newEnd[j] = std::copy( rhs.begin_[j], rhs.end_[j], newBegin[j] );
3003  }
3004  newEnd[rhs.n_] = newBegin[0UL]+nonzeros;
3005 
3006  std::swap( begin_, newBegin );
3007  end_ = newEnd;
3008  deallocate( newBegin[0UL] );
3009  delete [] newBegin;
3010  capacity_ = rhs.n_;
3011  }
3012  else {
3013  for( size_t j=0UL; j<rhs.n_; ++j ) {
3014  begin_[j+1UL] = end_[j] = std::copy( rhs.begin_[j], rhs.end_[j], begin_[j] );
3015  }
3016  }
3017 
3018  m_ = rhs.m_;
3019  n_ = rhs.n_;
3020 
3021  return *this;
3022 }
3024 //*************************************************************************************************
3025 
3026 
3027 //*************************************************************************************************
3037 template< typename Type > // Data type of the sparse matrix
3038 template< typename MT // Type of the right-hand side dense matrix
3039  , bool SO > // Storage order of the right-hand side dense matrix
3040 inline CompressedMatrix<Type,true>&
3041  CompressedMatrix<Type,true>::operator=( const DenseMatrix<MT,SO>& rhs )
3042 {
3043  using blaze::assign;
3044 
3045  if( (~rhs).canAlias( this ) ) {
3046  CompressedMatrix tmp( rhs );
3047  swap( tmp );
3048  }
3049  else {
3050  resize( (~rhs).rows(), (~rhs).columns(), false );
3051  assign( *this, ~rhs );
3052  }
3053 
3054  return *this;
3055 }
3057 //*************************************************************************************************
3058 
3059 
3060 //*************************************************************************************************
3070 template< typename Type > // Data type of the sparse matrix
3071 template< typename MT // Type of the right-hand side sparse matrix
3072  , bool SO > // Storage order of the right-hand side sparse matrix
3073 inline CompressedMatrix<Type,true>&
3074  CompressedMatrix<Type,true>::operator=( const SparseMatrix<MT,SO>& rhs )
3075 {
3076  using blaze::assign;
3077 
3078  if( (~rhs).canAlias( this ) ||
3079  (~rhs).columns() > capacity_ ||
3080  (~rhs).nonZeros() > capacity() ) {
3081  CompressedMatrix tmp( rhs );
3082  swap( tmp );
3083  }
3084  else {
3085  resize( (~rhs).rows(), (~rhs).columns(), false );
3086  reset();
3087  assign( *this, ~rhs );
3088  }
3089 
3090  return *this;
3091 }
3093 //*************************************************************************************************
3094 
3095 
3096 //*************************************************************************************************
3107 template< typename Type > // Data type of the sparse matrix
3108 template< typename MT // Type of the right-hand side matrix
3109  , bool SO > // Storage order of the right-hand side matrix
3110 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator+=( const Matrix<MT,SO>& rhs )
3111 {
3112  using blaze::addAssign;
3113 
3114  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
3115  throw std::invalid_argument( "Matrix sizes do not match" );
3116 
3117  addAssign( *this, ~rhs );
3118  return *this;
3119 }
3121 //*************************************************************************************************
3122 
3123 
3124 //*************************************************************************************************
3135 template< typename Type > // Data type of the sparse matrix
3136 template< typename MT // Type of the right-hand side matrix
3137  , bool SO > // Storage order of the right-hand side matrix
3138 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator-=( const Matrix<MT,SO>& rhs )
3139 {
3140  using blaze::subAssign;
3141 
3142  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
3143  throw std::invalid_argument( "Matrix sizes do not match" );
3144 
3145  subAssign( *this, ~rhs );
3146  return *this;
3147 }
3149 //*************************************************************************************************
3150 
3151 
3152 //*************************************************************************************************
3163 template< typename Type > // Data type of the sparse matrix
3164 template< typename MT // Type of the right-hand side matrix
3165  , bool SO > // Storage order of the right-hand side matrix
3166 inline CompressedMatrix<Type,true>&
3167  CompressedMatrix<Type,true>::operator*=( const Matrix<MT,SO>& rhs )
3168 {
3169  if( (~rhs).rows() != n_ )
3170  throw std::invalid_argument( "Matrix sizes do not match" );
3171 
3172  CompressedMatrix tmp( *this * (~rhs) );
3173  swap( tmp );
3174 
3175  return *this;
3176 }
3178 //*************************************************************************************************
3179 
3180 
3181 //*************************************************************************************************
3189 template< typename Type > // Data type of the sparse matrix
3190 template< typename Other > // Data type of the right-hand side scalar
3191 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,true> >::Type&
3192  CompressedMatrix<Type,true>::operator*=( Other rhs )
3193 {
3194  for( size_t j=0UL; j<n_; ++j ) {
3195  const Iterator last( end(j) );
3196  for( Iterator element=begin(j); element!=last; ++element )
3197  element->value_ *= rhs;
3198  }
3199  return *this;
3200 }
3202 //*************************************************************************************************
3203 
3204 
3205 //*************************************************************************************************
3213 template< typename Type > // Data type of the sparse matrix
3214 template< typename Other > // Data type of the right-hand side scalar
3215 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,true> >::Type&
3216  CompressedMatrix<Type,true>::operator/=( Other rhs )
3217 {
3218  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3219 
3220  typedef typename DivTrait<Type,Other>::Type DT;
3221  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
3222 
3223  // Depending on the two involved data types, an integer division is applied or a
3224  // floating point division is selected.
3225  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
3226  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
3227  for( size_t j=0UL; j<n_; ++j ) {
3228  const Iterator last( end(j) );
3229  for( Iterator element=begin(j); element!=last; ++element )
3230  element->value_ *= tmp;
3231  }
3232  }
3233  else {
3234  for( size_t j=0UL; j<n_; ++j ) {
3235  const Iterator last( end(j) );
3236  for( Iterator element=begin(j); element!=last; ++element )
3237  element->value_ /= rhs;
3238  }
3239  }
3240 
3241  return *this;
3242 }
3244 //*************************************************************************************************
3245 
3246 
3247 
3248 
3249 //=================================================================================================
3250 //
3251 // UTILITY FUNCTIONS
3252 //
3253 //=================================================================================================
3254 
3255 //*************************************************************************************************
3261 template< typename Type > // Data type of the sparse matrix
3262 inline size_t CompressedMatrix<Type,true>::rows() const
3263 {
3264  return m_;
3265 }
3267 //*************************************************************************************************
3268 
3269 
3270 //*************************************************************************************************
3276 template< typename Type > // Data type of the sparse matrix
3277 inline size_t CompressedMatrix<Type,true>::columns() const
3278 {
3279  return n_;
3280 }
3282 //*************************************************************************************************
3283 
3284 
3285 //*************************************************************************************************
3291 template< typename Type > // Data type of the sparse matrix
3292 inline size_t CompressedMatrix<Type,true>::capacity() const
3293 {
3294  return end_[n_] - begin_[0UL];
3295 }
3297 //*************************************************************************************************
3298 
3299 
3300 //*************************************************************************************************
3307 template< typename Type > // Data type of the sparse matrix
3308 inline size_t CompressedMatrix<Type,true>::capacity( size_t j ) const
3309 {
3310  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3311  return begin_[j+1UL] - begin_[j];
3312 }
3314 //*************************************************************************************************
3315 
3316 
3317 //*************************************************************************************************
3323 template< typename Type > // Data type of the sparse matrix
3324 inline size_t CompressedMatrix<Type,true>::nonZeros() const
3325 {
3326  size_t nonzeros( 0UL );
3327 
3328  for( size_t j=0UL; j<n_; ++j )
3329  nonzeros += nonZeros( j );
3330 
3331  return nonzeros;
3332 }
3334 //*************************************************************************************************
3335 
3336 
3337 //*************************************************************************************************
3344 template< typename Type > // Data type of the sparse matrix
3345 inline size_t CompressedMatrix<Type,true>::nonZeros( size_t j ) const
3346 {
3347  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3348  return end_[j] - begin_[j];
3349 }
3351 //*************************************************************************************************
3352 
3353 
3354 //*************************************************************************************************
3360 template< typename Type > // Data type of the sparse matrix
3362 {
3363  for( size_t j=0UL; j<n_; ++j )
3364  end_[j] = begin_[j];
3365 }
3367 //*************************************************************************************************
3368 
3369 
3370 //*************************************************************************************************
3380 template< typename Type > // Data type of the sparse matrix
3381 inline void CompressedMatrix<Type,true>::reset( size_t j )
3382 {
3383  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3384  end_[j] = begin_[j];
3385 }
3387 //*************************************************************************************************
3388 
3389 
3390 //*************************************************************************************************
3398 template< typename Type > // Data type of the sparse matrix
3400 {
3401  end_[0UL] = end_[n_];
3402  m_ = 0UL;
3403  n_ = 0UL;
3404 }
3406 //*************************************************************************************************
3407 
3408 
3409 //*************************************************************************************************
3423 template< typename Type > // Data type of the sparse matrix
3425  CompressedMatrix<Type,true>::insert( size_t i, size_t j, const Type& value )
3426 {
3427  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3428  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3429 
3430  const Iterator pos( lowerBound( i, j ) );
3431 
3432  if( pos != end_[j] && pos->index_ == i )
3433  throw std::invalid_argument( "Bad access index" );
3434 
3435  if( begin_[j+1UL] - end_[j] != 0 ) {
3436  std::copy_backward( pos, end_[j], end_[j]+1 );
3437  pos->value_ = value;
3438  pos->index_ = i;
3439  ++end_[j];
3440 
3441  return pos;
3442  }
3443  else if( end_[n_] - begin_[n_] != 0 ) {
3444  std::copy_backward( pos, end_[n_-1UL], end_[n_-1]+1 );
3445 
3446  pos->value_ = value;
3447  pos->index_ = i;
3448 
3449  for( size_t k=j+1UL; k<n_+1UL; ++k ) {
3450  ++begin_[k];
3451  ++end_[k-1UL];
3452  }
3453 
3454  return pos;
3455  }
3456  else {
3457  size_t newCapacity( extendCapacity() );
3458 
3459  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
3460  Iterator* newEnd = newBegin+capacity_+1UL;
3461 
3462  newBegin[0UL] = allocate<Element>( newCapacity );
3463 
3464  for( size_t k=0UL; k<j; ++k ) {
3465  const size_t nonzeros( end_[k] - begin_[k] );
3466  const size_t total( begin_[k+1UL] - begin_[k] );
3467  newEnd [k] = newBegin[k] + nonzeros;
3468  newBegin[k+1UL] = newBegin[k] + total;
3469  }
3470  newEnd [j] = newBegin[j] + ( end_[j] - begin_[j] ) + 1;
3471  newBegin[j+1UL] = newBegin[j] + ( begin_[j+1UL] - begin_[j] ) + 1;
3472  for( size_t k=j+1UL; k<n_; ++k ) {
3473  const size_t nonzeros( end_[k] - begin_[k] );
3474  const size_t total( begin_[k+1UL] - begin_[k] );
3475  newEnd [k] = newBegin[k] + nonzeros;
3476  newBegin[k+1UL] = newBegin[k] + total;
3477  }
3478 
3479  newEnd[n_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
3480 
3481  Iterator tmp = std::copy( begin_[0UL], pos, newBegin[0UL] );
3482  tmp->value_ = value;
3483  tmp->index_ = i;
3484  std::copy( pos, end_[n_-1UL], tmp+1UL );
3485 
3486  std::swap( newBegin, begin_ );
3487  end_ = newEnd;
3488  deallocate( newBegin[0UL] );
3489  delete [] newBegin;
3490 
3491  return tmp;
3492  }
3493 }
3495 //*************************************************************************************************
3496 
3497 
3498 //*************************************************************************************************
3508 template< typename Type > // Data type of the sparse matrix
3509 inline void CompressedMatrix<Type,true>::erase( size_t i, size_t j )
3510 {
3511  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3512  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3513 
3514  const Iterator pos( find( i, j ) );
3515  if( pos != end_[j] )
3516  end_[j] = std::copy( pos+1, end_[j], pos );
3517 }
3519 //*************************************************************************************************
3520 
3521 
3522 //*************************************************************************************************
3532 template< typename Type > // Data type of the sparse matrix
3534  CompressedMatrix<Type,true>::erase( size_t j, Iterator pos )
3535 {
3536  BLAZE_USER_ASSERT( j < columns() , "Invalid row access index" );
3537  BLAZE_USER_ASSERT( pos >= begin_[j] && pos <= end_[j], "Invalid compressed matrix iterator" );
3538 
3539  if( pos != end_[j] )
3540  end_[j] = std::copy( pos+1, end_[j], pos );
3541 
3542  return pos;
3543 }
3545 //*************************************************************************************************
3546 
3547 
3548 //*************************************************************************************************
3559 template< typename Type > // Data type of the sparse matrix
3561  CompressedMatrix<Type,true>::erase( size_t j, Iterator first, Iterator last )
3562 {
3563  BLAZE_USER_ASSERT( j < columns(), "Invalid row access index" );
3564  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
3565  BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j], "Invalid compressed matrix iterator" );
3566  BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j], "Invalid compressed matrix iterator" );
3567 
3568  if( first != last )
3569  end_[j] = std::copy( last, end_[j], first );
3570 
3571  return first;
3572 }
3574 //*************************************************************************************************
3575 
3576 
3577 //*************************************************************************************************
3593 template< typename Type > // Data type of the sparse matrix
3594 void CompressedMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
3595 {
3596  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
3597  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
3598 
3599  if( m == m_ && n == n_ ) return;
3600 
3601  if( n > capacity_ )
3602  {
3603  Iterator* newBegin( new Iterator[2UL*n+2UL] );
3604  Iterator* newEnd ( newBegin+n+1UL );
3605 
3606  newBegin[0UL] = begin_[0UL];
3607 
3608  if( preserve ) {
3609  for( size_t j=0UL; j<n_; ++j ) {
3610  newEnd [j] = end_ [j];
3611  newBegin[j+1UL] = begin_[j+1UL];
3612  }
3613  for( size_t j=n_; j<n; ++j ) {
3614  newBegin[j+1UL] = newEnd[j] = begin_[n_];
3615  }
3616  }
3617  else {
3618  for( size_t j=0UL; j<n; ++j ) {
3619  newBegin[j+1UL] = newEnd[j] = begin_[0UL];
3620  }
3621  }
3622 
3623  newEnd[n] = end_[n_];
3624 
3625  std::swap( newBegin, begin_ );
3626  delete [] newBegin;
3627 
3628  end_ = newEnd;
3629  capacity_ = n;
3630  }
3631  else if( n > n_ )
3632  {
3633  end_[n] = end_[n_];
3634 
3635  if( !preserve ) {
3636  for( size_t j=0UL; j<n_; ++j )
3637  end_[j] = begin_[j];
3638  }
3639 
3640  for( size_t j=n_; j<n; ++j )
3641  begin_[j+1UL] = end_[j] = begin_[n_];
3642  }
3643  else
3644  {
3645  if( preserve ) {
3646  for( size_t j=0UL; j<n; ++j )
3647  end_[j] = lowerBound( m, j );
3648  }
3649  else {
3650  for( size_t j=0UL; j<n; ++j )
3651  end_[j] = begin_[j];
3652  }
3653 
3654  end_[n] = end_[n_];
3655  }
3656 
3657  m_ = m;
3658  n_ = n;
3659 }
3661 //*************************************************************************************************
3662 
3663 
3664 //*************************************************************************************************
3675 template< typename Type > // Data type of the sparse matrix
3676 inline void CompressedMatrix<Type,true>::reserve( size_t nonzeros )
3677 {
3678  if( nonzeros > capacity() )
3679  reserveElements( nonzeros );
3680 }
3682 //*************************************************************************************************
3683 
3684 
3685 //*************************************************************************************************
3697 template< typename Type > // Data type of the sparse matrix
3698 void CompressedMatrix<Type,true>::reserve( size_t j, size_t nonzeros )
3699 {
3700  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3701 
3702  const size_t current( capacity(j) );
3703 
3704  if( current >= nonzeros ) return;
3705 
3706  const ptrdiff_t additional( nonzeros - current );
3707 
3708  if( end_[n_] - begin_[n_] < additional )
3709  {
3710  const size_t newCapacity( begin_[n_] - begin_[0UL] + additional );
3711  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
3712 
3713  Iterator* newBegin( new Iterator[2UL*n_+2UL] );
3714  Iterator* newEnd ( newBegin+n_+1UL );
3715 
3716  newBegin[0UL] = allocate<Element>( newCapacity );
3717  newEnd [n_ ] = newBegin[0UL]+newCapacity;
3718 
3719  for( size_t k=0UL; k<j; ++k ) {
3720  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
3721  newBegin[k+1UL] = newBegin[k] + capacity(k);
3722  }
3723  newEnd [j ] = std::copy( begin_[j], end_[j], newBegin[j] );
3724  newBegin[j+1UL] = newBegin[j] + nonzeros;
3725  for( size_t k=j+1UL; k<n_; ++k ) {
3726  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
3727  newBegin[k+1UL] = newBegin[k] + capacity(k);
3728  }
3729 
3730  BLAZE_INTERNAL_ASSERT( newBegin[n_] == newEnd[n_], "Invalid pointer calculations" );
3731 
3732  std::swap( newBegin, begin_ );
3733  deallocate( newBegin[0UL] );
3734  delete [] newBegin;
3735  end_ = newEnd;
3736  }
3737  else
3738  {
3739  begin_[n_] += additional;
3740  for( size_t k=n_-1UL; k>j; --k ) {
3741  begin_[k] = std::copy_backward( begin_[k], end_[k], end_[k]+additional );
3742  end_ [k] += additional;
3743  }
3744  }
3745 }
3747 //*************************************************************************************************
3748 
3749 
3750 //*************************************************************************************************
3760 template< typename Type > // Data type of the sparse matrix
3761 void CompressedMatrix<Type,true>::trim()
3762 {
3763  for( size_t j=0UL; j<n_; ++j )
3764  trim( j );
3765 }
3767 //*************************************************************************************************
3768 
3769 
3770 //*************************************************************************************************
3781 template< typename Type > // Data type of the sparse matrix
3782 void CompressedMatrix<Type,true>::trim( size_t j )
3783 {
3784  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3785 
3786  if( j < ( n_ - 1UL ) )
3787  end_[j+1] = std::copy( begin_[j+1], end_[j+1], end_[j] );
3788  begin_[j+1] = end_[j];
3789 }
3791 //*************************************************************************************************
3792 
3793 
3794 //*************************************************************************************************
3800 template< typename Type > // Data type of the sparse matrix
3801 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::transpose()
3802 {
3803  CompressedMatrix tmp( trans( *this ) );
3804  swap( tmp );
3805  return *this;
3806 }
3808 //*************************************************************************************************
3809 
3810 
3811 //*************************************************************************************************
3818 template< typename Type > // Data type of the sparse matrix
3819 template< typename Other > // Data type of the scalar value
3820 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scale( Other scalar )
3821 {
3822  for( size_t j=0UL; j<n_; ++j )
3823  for( Iterator element=begin_[j]; element!=end_[j]; ++element )
3824  element->value_ *= scalar;
3825 
3826  return *this;
3827 }
3829 //*************************************************************************************************
3830 
3831 
3832 //*************************************************************************************************
3839 template< typename Type > // Data type of the sparse matrix
3840 template< typename Other > // Data type of the scalar value
3841 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scaleDiagonal( Other scalar )
3842 {
3843  const size_t size( blaze::min( m_, n_ ) );
3844 
3845  for( size_t j=0UL; j<size; ++j ) {
3846  Iterator pos = lowerBound( j, j );
3847  if( pos != end_[j] && pos->index_ == j )
3848  pos->value_ *= scalar;
3849  }
3850 
3851  return *this;
3852 }
3854 //*************************************************************************************************
3855 
3856 
3857 //*************************************************************************************************
3865 template< typename Type > // Data type of the sparse matrix
3866 inline void CompressedMatrix<Type,true>::swap( CompressedMatrix& sm ) /* throw() */
3867 {
3868  std::swap( m_, sm.m_ );
3869  std::swap( n_, sm.n_ );
3870  std::swap( capacity_, sm.capacity_ );
3871  std::swap( begin_, sm.begin_ );
3872  std::swap( end_ , sm.end_ );
3873 }
3875 //*************************************************************************************************
3876 
3877 
3878 //*************************************************************************************************
3887 template< typename Type > // Data type of the sparse matrix
3888 inline size_t CompressedMatrix<Type,true>::extendCapacity() const
3889 {
3890  size_t nonzeros( 2UL*capacity()+1UL );
3891  nonzeros = blaze::max( nonzeros, 7UL );
3892 
3893  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
3894 
3895  return nonzeros;
3896 }
3898 //*************************************************************************************************
3899 
3900 
3901 //*************************************************************************************************
3908 template< typename Type > // Data type of the sparse matrix
3909 void CompressedMatrix<Type,true>::reserveElements( size_t nonzeros )
3910 {
3911  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
3912  Iterator* newEnd = newBegin+capacity_+1UL;
3913 
3914  newBegin[0UL] = allocate<Element>( nonzeros );
3915 
3916  for( size_t k=0UL; k<n_; ++k ) {
3917  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid column pointers" );
3918  newEnd [k] = std::copy( begin_[k], end_[k], newBegin[k] );
3919  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
3920  }
3921 
3922  newEnd[n_] = newBegin[0UL]+nonzeros;
3923 
3924  std::swap( newBegin, begin_ );
3925  deallocate( newBegin[0UL] );
3926  delete [] newBegin;
3927  end_ = newEnd;
3928 }
3930 //*************************************************************************************************
3931 
3932 
3933 
3934 
3935 //=================================================================================================
3936 //
3937 // LOOKUP FUNCTIONS
3938 //
3939 //=================================================================================================
3940 
3941 //*************************************************************************************************
3956 template< typename Type > // Data type of the sparse matrix
3958  CompressedMatrix<Type,true>::find( size_t i, size_t j )
3959 {
3960  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
3961 }
3963 //*************************************************************************************************
3964 
3965 
3966 //*************************************************************************************************
3981 template< typename Type > // Data type of the sparse matrix
3983  CompressedMatrix<Type,true>::find( size_t i, size_t j ) const
3984 {
3985  const ConstIterator pos( lowerBound( i, j ) );
3986  if( pos != end_[j] && pos->index_ == i )
3987  return pos;
3988  else return end_[j];
3989 }
3991 //*************************************************************************************************
3992 
3993 
3994 //*************************************************************************************************
4008 template< typename Type > // Data type of the sparse matrix
4010  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j )
4011 {
4012  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
4013 }
4015 //*************************************************************************************************
4016 
4017 
4018 //*************************************************************************************************
4032 template< typename Type > // Data type of the sparse matrix
4034  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j ) const
4035 {
4036  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4037  return std::lower_bound( begin_[j], end_[j], i, FindIndex() );
4038 }
4040 //*************************************************************************************************
4041 
4042 
4043 //*************************************************************************************************
4057 template< typename Type > // Data type of the sparse matrix
4059  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j )
4060 {
4061  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
4062 }
4064 //*************************************************************************************************
4065 
4066 
4067 //*************************************************************************************************
4081 template< typename Type > // Data type of the sparse matrix
4083  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j ) const
4084 {
4085  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4086  return std::upper_bound( begin_[j], end_[j], i, FindIndex() );
4087 }
4089 //*************************************************************************************************
4090 
4091 
4092 
4093 
4094 //=================================================================================================
4095 //
4096 // LOW-LEVEL UTILITY FUNCTIONS
4097 //
4098 //=================================================================================================
4099 
4100 //*************************************************************************************************
4141 template< typename Type > // Data type of the sparse matrix
4142 inline void CompressedMatrix<Type,true>::append( size_t i, size_t j, const Type& value, bool check )
4143 {
4144  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
4145  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
4146  BLAZE_USER_ASSERT( end_[j] < end_[n_], "Not enough reserved space left" );
4147  BLAZE_USER_ASSERT( begin_[j] == end_[j] || i > ( end_[j]-1UL )->index_, "Index is not strictly increasing" );
4148 
4149  end_[j]->value_ = value;
4150 
4151  if( !check || !isDefault( end_[j]->value_ ) ) {
4152  end_[j]->index_ = i;
4153  ++end_[j];
4154  }
4155 }
4157 //*************************************************************************************************
4158 
4159 
4160 //*************************************************************************************************
4174 template< typename Type > // Data type of the sparse matrix
4175 inline void CompressedMatrix<Type,true>::finalize( size_t j )
4176 {
4177  BLAZE_USER_ASSERT( j < n_, "Invalid row access index" );
4178 
4179  begin_[j+1UL] = end_[j];
4180  if( j != n_-1UL )
4181  end_[j+1UL] = end_[j];
4182 }
4184 //*************************************************************************************************
4185 
4186 
4187 
4188 
4189 //=================================================================================================
4190 //
4191 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4192 //
4193 //=================================================================================================
4194 
4195 //*************************************************************************************************
4206 template< typename Type > // Data type of the sparse matrix
4207 template< typename Other > // Data type of the foreign expression
4208 inline bool CompressedMatrix<Type,true>::canAlias( const Other* alias ) const
4209 {
4210  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4211 }
4213 //*************************************************************************************************
4214 
4215 
4216 //*************************************************************************************************
4227 template< typename Type > // Data type of the sparse matrix
4228 template< typename Other > // Data type of the foreign expression
4229 inline bool CompressedMatrix<Type,true>::isAliased( const Other* alias ) const
4230 {
4231  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4232 }
4234 //*************************************************************************************************
4235 
4236 
4237 //*************************************************************************************************
4248 template< typename Type > // Data type of the sparse matrix
4249 inline bool CompressedMatrix<Type,true>::canSMPAssign() const
4250 {
4251  return false;
4252 }
4254 //*************************************************************************************************
4255 
4256 
4257 //*************************************************************************************************
4269 template< typename Type > // Data type of the sparse matrix
4270 template< typename MT // Type of the right-hand side dense matrix
4271  , bool SO > // Storage order of the right-hand side dense matrix
4272 inline void CompressedMatrix<Type,true>::assign( const DenseMatrix<MT,SO>& rhs )
4273 {
4274  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4275  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4276 
4277  size_t nonzeros( 0UL );
4278 
4279  for( size_t j=1UL; j<=n_; ++j )
4280  begin_[j] = end_[j] = end_[n_];
4281 
4282  for( size_t j=0UL; j<n_; ++j )
4283  {
4284  begin_[j] = end_[j] = begin_[0UL]+nonzeros;
4285 
4286  for( size_t i=0UL; i<m_; ++i )
4287  {
4288  if( nonzeros == capacity() ) {
4289  reserveElements( extendCapacity() );
4290  for( size_t k=j+1UL; k<=n_; ++k )
4291  begin_[k] = end_[k] = end_[n_];
4292  }
4293 
4294  end_[j]->value_ = (~rhs)(i,j);
4295 
4296  if( !isDefault( end_[j]->value_ ) ) {
4297  end_[j]->index_ = i;
4298  ++end_[j];
4299  ++nonzeros;
4300  }
4301  }
4302  }
4303 
4304  begin_[n_] = begin_[0UL]+nonzeros;
4305 }
4307 //*************************************************************************************************
4308 
4309 
4310 //*************************************************************************************************
4322 template< typename Type > // Data type of the sparse matrix
4323 template< typename MT > // Type of the right-hand side sparse matrix
4324 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,true>& rhs )
4325 {
4326  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4327  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4328  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4329 
4330  for( size_t j=0UL; j<(~rhs).columns(); ++j ) {
4331  begin_[j+1UL] = end_[j] = std::copy( (~rhs).begin(j), (~rhs).end(j), begin_[j] );
4332  }
4333 }
4335 //*************************************************************************************************
4336 
4337 
4338 //*************************************************************************************************
4350 template< typename Type > // Data type of the sparse matrix
4351 template< typename MT > // Type of the right-hand side sparse matrix
4352 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,false>& rhs )
4353 {
4354  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4355  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4356  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4357 
4358  typedef typename MT::ConstIterator RhsIterator;
4359 
4360  // Counting the number of elements per column
4361  std::vector<size_t> columnLengths( n_, 0UL );
4362  for( size_t i=0UL; i<m_; ++i ) {
4363  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4364  ++columnLengths[element->index()];
4365  }
4366 
4367  // Resizing the sparse matrix
4368  for( size_t j=0UL; j<n_; ++j ) {
4369  begin_[j+1UL] = end_[j+1UL] = begin_[j] + columnLengths[j];
4370  }
4371 
4372  // Appending the elements to the columns of the sparse matrix
4373  for( size_t i=0UL; i<m_; ++i ) {
4374  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4375  append( i, element->index(), element->value() );
4376  }
4377 }
4379 //*************************************************************************************************
4380 
4381 
4382 //*************************************************************************************************
4394 template< typename Type > // Data type of the sparse matrix
4395 template< typename MT // Type of the right-hand side dense matrix
4396  , bool SO > // Storage order of the right-hand side dense matrix
4397 inline void CompressedMatrix<Type,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
4398 {
4399  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4400  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4401 
4402  CompressedMatrix tmp( serial( *this + (~rhs) ) );
4403  swap( tmp );
4404 }
4406 //*************************************************************************************************
4407 
4408 
4409 //*************************************************************************************************
4421 template< typename Type > // Data type of the sparse matrix
4422 template< typename MT // Type of the right-hand side sparse matrix
4423  , bool SO > // Storage order of the right-hand side sparse matrix
4424 inline void CompressedMatrix<Type,true>::addAssign( const SparseMatrix<MT,SO>& rhs )
4425 {
4426  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4427  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4428 
4429  CompressedMatrix tmp( serial( *this + (~rhs) ) );
4430  swap( tmp );
4431 }
4433 //*************************************************************************************************
4434 
4435 
4436 //*************************************************************************************************
4448 template< typename Type > // Data type of the sparse matrix
4449 template< typename MT // Type of the right-hand side dense matrix
4450  , bool SO > // Storage order of the right-hand side dense matrix
4451 inline void CompressedMatrix<Type,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
4452 {
4453  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4454  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4455 
4456  CompressedMatrix tmp( serial( *this - (~rhs) ) );
4457  swap( tmp );
4458 }
4460 //*************************************************************************************************
4461 
4462 
4463 //*************************************************************************************************
4475 template< typename Type > // Data type of the sparse matrix
4476 template< typename MT // Type of the right-hand side sparse matrix
4477  , bool SO > // Storage order of the right-hand side sparse matrix
4478 inline void CompressedMatrix<Type,true>::subAssign( const SparseMatrix<MT,SO>& rhs )
4479 {
4480  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4481  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4482 
4483  CompressedMatrix tmp( serial( *this - (~rhs) ) );
4484  swap( tmp );
4485 }
4487 //*************************************************************************************************
4488 
4489 
4490 
4491 
4492 
4493 
4494 
4495 
4496 //=================================================================================================
4497 //
4498 // COMPRESSEDMATRIX OPERATORS
4499 //
4500 //=================================================================================================
4501 
4502 //*************************************************************************************************
4505 template< typename Type, bool SO >
4506 inline void reset( CompressedMatrix<Type,SO>& m );
4507 
4508 template< typename Type, bool SO >
4509 inline void clear( CompressedMatrix<Type,SO>& m );
4510 
4511 template< typename Type, bool SO >
4512 inline bool isDefault( const CompressedMatrix<Type,SO>& m );
4513 
4514 template< typename Type, bool SO >
4515 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) /* throw() */;
4517 //*************************************************************************************************
4518 
4519 
4520 //*************************************************************************************************
4527 template< typename Type // Data type of the sparse matrix
4528  , bool SO > // Storage order
4529 inline void reset( CompressedMatrix<Type,SO>& m )
4530 {
4531  m.reset();
4532 }
4533 //*************************************************************************************************
4534 
4535 
4536 //*************************************************************************************************
4543 template< typename Type // Data type of the sparse matrix
4544  , bool SO > // Storage order
4545 inline void clear( CompressedMatrix<Type,SO>& m )
4546 {
4547  m.clear();
4548 }
4549 //*************************************************************************************************
4550 
4551 
4552 //*************************************************************************************************
4570 template< typename Type // Data type of the sparse matrix
4571  , bool SO > // Storage order
4572 inline bool isDefault( const CompressedMatrix<Type,SO>& m )
4573 {
4575 
4576  if( SO == rowMajor ) {
4577  for( size_t i=0UL; i<m.rows(); ++i ) {
4578  for( ConstIterator element=m.begin(i); element!=m.end(i); ++element )
4579  if( !isDefault( element->value() ) ) return false;
4580  }
4581  }
4582  else {
4583  for( size_t j=0UL; j<m.columns(); ++j ) {
4584  for( ConstIterator element=m.begin(j); element!=m.end(j); ++element )
4585  if( !isDefault( element->value() ) ) return false;
4586  }
4587  }
4588 
4589  return true;
4590 }
4591 //*************************************************************************************************
4592 
4593 
4594 //*************************************************************************************************
4603 template< typename Type // Data type of the sparse matrix
4604  , bool SO > // Storage order
4605 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) /* throw() */
4606 {
4607  a.swap( b );
4608 }
4609 //*************************************************************************************************
4610 
4611 
4612 
4613 
4614 //=================================================================================================
4615 //
4616 // ISRESIZABLE SPECIALIZATIONS
4617 //
4618 //=================================================================================================
4619 
4620 //*************************************************************************************************
4622 template< typename T, bool SO >
4623 struct IsResizable< CompressedMatrix<T,SO> > : public TrueType
4624 {
4625  enum { value = 1 };
4626  typedef TrueType Type;
4627 };
4628 
4629 template< typename T, bool SO >
4630 struct IsResizable< const CompressedMatrix<T,SO> > : public TrueType
4631 {
4632  enum { value = 1 };
4633  typedef TrueType Type;
4634 };
4635 
4636 template< typename T, bool SO >
4637 struct IsResizable< volatile CompressedMatrix<T,SO> > : public TrueType
4638 {
4639  enum { value = 1 };
4640  typedef TrueType Type;
4641 };
4642 
4643 template< typename T, bool SO >
4644 struct IsResizable< const volatile CompressedMatrix<T,SO> > : public TrueType
4645 {
4646  enum { value = 1 };
4647  typedef TrueType Type;
4648 };
4650 //*************************************************************************************************
4651 
4652 
4653 
4654 
4655 //=================================================================================================
4656 //
4657 // ADDTRAIT SPECIALIZATIONS
4658 //
4659 //=================================================================================================
4660 
4661 //*************************************************************************************************
4663 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4664 struct AddTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4665 {
4666  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4667 };
4668 
4669 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4670 struct AddTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4671 {
4672  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
4673 };
4674 
4675 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4676 struct AddTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4677 {
4678  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4679 };
4680 
4681 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4682 struct AddTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4683 {
4684  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
4685 };
4686 
4687 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4688 struct AddTrait< CompressedMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
4689 {
4690  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4691 };
4692 
4693 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4694 struct AddTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
4695 {
4696  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
4697 };
4698 
4699 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4700 struct AddTrait< HybridMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4701 {
4702  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4703 };
4704 
4705 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4706 struct AddTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4707 {
4708  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
4709 };
4710 
4711 template< typename T1, bool SO, typename T2 >
4712 struct AddTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4713 {
4714  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4715 };
4716 
4717 template< typename T1, bool SO1, typename T2, bool SO2 >
4718 struct AddTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4719 {
4720  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4721 };
4722 
4723 template< typename T1, bool SO, typename T2 >
4724 struct AddTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4725 {
4726  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4727 };
4728 
4729 template< typename T1, bool SO1, typename T2, bool SO2 >
4730 struct AddTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4731 {
4732  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4733 };
4734 
4735 template< typename T1, bool SO, typename T2 >
4736 struct AddTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4737 {
4738  typedef CompressedMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4739 };
4740 
4741 template< typename T1, bool SO1, typename T2, bool SO2 >
4742 struct AddTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4743 {
4744  typedef CompressedMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4745 };
4747 //*************************************************************************************************
4748 
4749 
4750 
4751 
4752 //=================================================================================================
4753 //
4754 // SUBTRAIT SPECIALIZATIONS
4755 //
4756 //=================================================================================================
4757 
4758 //*************************************************************************************************
4760 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4761 struct SubTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4762 {
4763  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4764 };
4765 
4766 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4767 struct SubTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4768 {
4769  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
4770 };
4771 
4772 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4773 struct SubTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4774 {
4775  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4776 };
4777 
4778 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4779 struct SubTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4780 {
4781  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
4782 };
4783 
4784 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4785 struct SubTrait< CompressedMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
4786 {
4787  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4788 };
4789 
4790 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4791 struct SubTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
4792 {
4793  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
4794 };
4795 
4796 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4797 struct SubTrait< HybridMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4798 {
4799  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4800 };
4801 
4802 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4803 struct SubTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4804 {
4805  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
4806 };
4807 
4808 template< typename T1, bool SO, typename T2 >
4809 struct SubTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4810 {
4811  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4812 };
4813 
4814 template< typename T1, bool SO1, typename T2, bool SO2 >
4815 struct SubTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4816 {
4817  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , false > Type;
4818 };
4819 
4820 template< typename T1, bool SO, typename T2 >
4821 struct SubTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4822 {
4823  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4824 };
4825 
4826 template< typename T1, bool SO1, typename T2, bool SO2 >
4827 struct SubTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4828 {
4829  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , false > Type;
4830 };
4831 
4832 template< typename T1, bool SO, typename T2 >
4833 struct SubTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4834 {
4835  typedef CompressedMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4836 };
4837 
4838 template< typename T1, bool SO1, typename T2, bool SO2 >
4839 struct SubTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4840 {
4841  typedef CompressedMatrix< typename SubTrait<T1,T2>::Type , false > Type;
4842 };
4844 //*************************************************************************************************
4845 
4846 
4847 
4848 
4849 //=================================================================================================
4850 //
4851 // MULTTRAIT SPECIALIZATIONS
4852 //
4853 //=================================================================================================
4854 
4855 //*************************************************************************************************
4857 template< typename T1, bool SO, typename T2 >
4858 struct MultTrait< CompressedMatrix<T1,SO>, T2 >
4859 {
4860  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
4862 };
4863 
4864 template< typename T1, typename T2, bool SO >
4865 struct MultTrait< T1, CompressedMatrix<T2,SO> >
4866 {
4867  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
4869 };
4870 
4871 template< typename T1, bool SO, typename T2, size_t N >
4872 struct MultTrait< CompressedMatrix<T1,SO>, StaticVector<T2,N,false> >
4873 {
4874  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4875 };
4876 
4877 template< typename T1, size_t N, typename T2, bool SO >
4878 struct MultTrait< StaticVector<T1,N,true>, CompressedMatrix<T2,SO> >
4879 {
4880  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4881 };
4882 
4883 template< typename T1, bool SO, typename T2, size_t N >
4884 struct MultTrait< CompressedMatrix<T1,SO>, HybridVector<T2,N,false> >
4885 {
4886  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4887 };
4888 
4889 template< typename T1, size_t N, typename T2, bool SO >
4890 struct MultTrait< HybridVector<T1,N,true>, CompressedMatrix<T2,SO> >
4891 {
4892  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4893 };
4894 
4895 template< typename T1, bool SO, typename T2 >
4896 struct MultTrait< CompressedMatrix<T1,SO>, DynamicVector<T2,false> >
4897 {
4898  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4899 };
4900 
4901 template< typename T1, typename T2, bool SO >
4902 struct MultTrait< DynamicVector<T1,true>, CompressedMatrix<T2,SO> >
4903 {
4904  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4905 };
4906 
4907 template< typename T1, bool SO, typename T2 >
4908 struct MultTrait< CompressedMatrix<T1,SO>, CompressedVector<T2,false> >
4909 {
4910  typedef CompressedVector< typename MultTrait<T1,T2>::Type, false > Type;
4911 };
4912 
4913 template< typename T1, typename T2, bool SO >
4914 struct MultTrait< CompressedVector<T1,true>, CompressedMatrix<T2,SO> >
4915 {
4916  typedef CompressedVector< typename MultTrait<T1,T2>::Type, true > Type;
4917 };
4918 
4919 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4920 struct MultTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4921 {
4922  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4923 };
4924 
4925 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4926 struct MultTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4927 {
4928  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4929 };
4930 
4931 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4932 struct MultTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
4933 {
4934  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4935 };
4936 
4937 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4938 struct MultTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4939 {
4940  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4941 };
4942 
4943 template< typename T1, bool SO1, typename T2, bool SO2 >
4944 struct MultTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4945 {
4946  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4947 };
4948 
4949 template< typename T1, bool SO1, typename T2, bool SO2 >
4950 struct MultTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4951 {
4952  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4953 };
4954 
4955 template< typename T1, bool SO1, typename T2, bool SO2 >
4956 struct MultTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4957 {
4958  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4959 };
4961 //*************************************************************************************************
4962 
4963 
4964 
4965 
4966 //=================================================================================================
4967 //
4968 // DIVTRAIT SPECIALIZATIONS
4969 //
4970 //=================================================================================================
4971 
4972 //*************************************************************************************************
4974 template< typename T1, bool SO, typename T2 >
4975 struct DivTrait< CompressedMatrix<T1,SO>, T2 >
4976 {
4977  typedef CompressedMatrix< typename DivTrait<T1,T2>::Type, SO > Type;
4979 };
4981 //*************************************************************************************************
4982 
4983 
4984 
4985 
4986 //=================================================================================================
4987 //
4988 // MATHTRAIT SPECIALIZATIONS
4989 //
4990 //=================================================================================================
4991 
4992 //*************************************************************************************************
4994 template< typename T1, bool SO, typename T2 >
4995 struct MathTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4996 {
4997  typedef CompressedMatrix< typename MathTrait<T1,T2>::HighType, SO > HighType;
4998  typedef CompressedMatrix< typename MathTrait<T1,T2>::LowType , SO > LowType;
4999 };
5001 //*************************************************************************************************
5002 
5003 
5004 
5005 
5006 //=================================================================================================
5007 //
5008 // SUBMATRIXTRAIT SPECIALIZATIONS
5009 //
5010 //=================================================================================================
5011 
5012 //*************************************************************************************************
5014 template< typename T1, bool SO >
5015 struct SubmatrixTrait< CompressedMatrix<T1,SO> >
5016 {
5017  typedef CompressedMatrix<T1,SO> Type;
5018 };
5020 //*************************************************************************************************
5021 
5022 
5023 
5024 
5025 //=================================================================================================
5026 //
5027 // ROWTRAIT SPECIALIZATIONS
5028 //
5029 //=================================================================================================
5030 
5031 //*************************************************************************************************
5033 template< typename T1, bool SO >
5034 struct RowTrait< CompressedMatrix<T1,SO> >
5035 {
5036  typedef CompressedVector<T1,true> Type;
5037 };
5039 //*************************************************************************************************
5040 
5041 
5042 
5043 
5044 //=================================================================================================
5045 //
5046 // COLUMNTRAIT SPECIALIZATIONS
5047 //
5048 //=================================================================================================
5049 
5050 //*************************************************************************************************
5052 template< typename T1, bool SO >
5053 struct ColumnTrait< CompressedMatrix<T1,SO> >
5054 {
5055  typedef CompressedVector<T1,false> Type;
5056 };
5058 //*************************************************************************************************
5059 
5060 } // namespace blaze
5061 
5062 #endif
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
Definition: Const.h:116
Pointer difference type of the Blaze library.
size_t rows() const
Returns the current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:1113
void reserveElements(size_t nonzeros)
Reserving the specified number of sparse matrix elements.
Definition: CompressedMatrix.h:1758
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:404
Header file for mathematical functions.
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4599
#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:254
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:255
const bool defaultStorageOrder
The default storage order for all matrices of the Blaze library.This value specifies the default stor...
Definition: StorageOrder.h:56
Header file for the row trait.
Header file for the IsSparseMatrix type trait.
CompressedMatrix()
The default constructor for CompressedMatrix.
Definition: CompressedMatrix.h:448
bool isDefault(const DynamicMatrix< Type, SO > &m)
Returns whether the given dense matrix is in default state.
Definition: DynamicMatrix.h:4642
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:199
size_t extendCapacity() const
Calculating a new matrix capacity.
Definition: CompressedMatrix.h:1738
const blaze::Null NULL
Global NULL pointer.This instance of the Null class replaces the NULL macro to ensure a type-safe NUL...
Definition: Null.h:300
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2555
void clear()
Clearing the sparse matrix.
Definition: CompressedMatrix.h:1254
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:251
Header file for a safe C++ NULL pointer implementation.
void clear(CompressedMatrix< Type, SO > &m)
Clearing the given sparse matrix.
Definition: CompressedMatrix.h:4545
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2402
CompressedMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:249
#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:634
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:690
void reset(CompressedMatrix< Type, SO > &m)
Resetting the given sparse matrix.
Definition: CompressedMatrix.h:4529
Access proxy for sparse, matrices.The MatrixAccessProxy provides safe access to the elements of a no...
Definition: MatrixAccessProxy.h:86
Header file for memory allocation and deallocation functionality.
bool isAliased(const Other *alias) const
Returns whether the matrix is aliased with the given address alias.
Definition: CompressedMatrix.h:2081
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:406
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:252
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:1176
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:2557
Header file for the SparseMatrix base class.
void deallocate(T *address)
Deallocation of memory.
Definition: Memory.h:115
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:402
void reserve(size_t nonzeros)
Setting the minimum capacity of the sparse matrix.
Definition: CompressedMatrix.h:1529
void reset()
Reset to the default initial values.
Definition: CompressedMatrix.h:1216
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:253
Header file for the ValueIndexPair class.
bool isDefault(const CompressedMatrix< Type, SO > &m)
Returns whether the given sparse matrix is in default state.
Definition: CompressedMatrix.h:4572
Header file for the multiplication trait.
Header file for the If class template.
Header file for the IsFloatingPoint type trait.
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b)
Swapping the contents of two sparse matrices.
Definition: CompressedMatrix.h:4605
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:2412
#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:1362
Iterator * end_
Pointers one past the last non-zero element of each column.
Definition: CompressedMatrix.h:2559
size_t nonZeros(const Matrix< MT, SO > &m)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:224
#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:203
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:271
Constraint on the data type.
Header file for the default storage order for all vectors of the Blaze library.
Iterator insert(size_t i, size_t j, const Type &value)
Inserting an element into the sparse matrix.
Definition: CompressedMatrix.h:1279
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
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2410
void subAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the subtraction assignment of a dense matrix.
Definition: CompressedMatrix.h:2296
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:1717
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:257
bool canSMPAssign() const
Returns whether the matrix can be used in SMP assignments.
Definition: CompressedMatrix.h:2100
Header file for the equal shim.
size_t capacity() const
Returns the maximum capacity of the sparse matrix.
Definition: CompressedMatrix.h:1141
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the sparse matrix.
Definition: CompressedMatrix.h:1448
Header file for the IsNumeric type trait.
CompressedMatrix & operator=(const CompressedMatrix &rhs)
Copy assignment operator for CompressedMatrix.
Definition: CompressedMatrix.h:847
Reference operator()(size_t i, size_t j)
2D-access to the sparse matrix elements.
Definition: CompressedMatrix.h:660
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:775
CompressedMatrix & transpose()
Transposing the matrix.
Definition: CompressedMatrix.h:1655
Header file for the division trait.
void swap(DynamicMatrix< Type, SO > &a, DynamicMatrix< Type, SO > &b)
Swapping the contents of two matrices.
Definition: DynamicMatrix.h:4671
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:301
void trim()
Removing all excessive capacity from all rows/columns.
Definition: CompressedMatrix.h:1616
Header file for the submatrix trait.
Constraint on the data type.
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
#define BLAZE_CONSTRAINT_MUST_BE_NUMERIC_TYPE(T)
Constraint on the data type.In case the given data type T is not a numeric (integral or floating poin...
Definition: Numeric.h:79
void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:331
const VT::ElementType max(const SparseVector< VT, TF > &sv)
Returns the largest element of the sparse vector.
Definition: SparseVector.h:408
#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:2411
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
size_t columns() const
Returns the current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:1127
Constraint on the data type.
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:248
Iterator * begin_
Pointers to the first non-zero element of each column.
Definition: CompressedMatrix.h:2558
void assign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the assignment of a row-major dense matrix.
Definition: CompressedMatrix.h:2122
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:256
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:1997
void finalize(size_t i)
Finalizing the element insertion of a row/column.
Definition: CompressedMatrix.h:2029
bool canAlias(const Other *alias) const
Returns whether the matrix can alias with the given address alias.
Definition: CompressedMatrix.h:2061
Base template for the DivTrait class.
Definition: DivTrait.h:141
CompressedMatrix< Type, SO > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:247
Iterator find(size_t i, size_t j)
Searches for a specific matrix element.
Definition: CompressedMatrix.h:1807
Header file for the mathematical trait.
Iterator * begin_
Pointers to the first non-zero element of each row.
Definition: CompressedMatrix.h:403
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2556
Index-value-pair for sparse vectors and matrices.The ValueIndexPair class represents a single index-v...
Definition: ValueIndexPair.h:69
Constraint on the size of two data types.
void addAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the addition assignment of a dense matrix.
Definition: CompressedMatrix.h:2244
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:907
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:250
Iterator lowerBound(size_t i, size_t j)
Returns an iterator to the first index not less then the given index.
Definition: CompressedMatrix.h:1860
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:2561
Iterator upperBound(size_t i, size_t j)
Returns an iterator to the first index greater then the given index.
Definition: CompressedMatrix.h:1911
size_t columns(const Matrix< MT, SO > &m)
Returns the current number of columns of the matrix.
Definition: Matrix.h:170
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:753
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2409
const VT::ElementType min(const SparseVector< VT, TF > &sv)
Returns the smallest element of the sparse vector.
Definition: SparseVector.h:351
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:401
ConstIterator cend(size_t i) const
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:819
Header file for the IsResizable type trait.
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:400
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
size_t rows(const Matrix< MT, SO > &m)
Returns the current number of rows of the matrix.
Definition: Matrix.h:154
#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
size_t capacity(const Matrix< MT, SO > &m)
Returns the maximum capacity of the matrix.
Definition: Matrix.h:186
Iterator begin(size_t i)
Returns an iterator to the first non-zero element of row/column i.
Definition: CompressedMatrix.h:709