CompressedMatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_SPARSE_COMPRESSEDMATRIX_H_
36 #define _BLAZE_MATH_SPARSE_COMPRESSEDMATRIX_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <functional>
45 #include <stdexcept>
46 #include <vector>
49 #include <blaze/math/Forward.h>
50 #include <blaze/math/Functions.h>
51 #include <blaze/math/shims/Equal.h>
73 #include <blaze/util/Assert.h>
80 #include <blaze/util/EnableIf.h>
81 #include <blaze/util/Memory.h>
82 #include <blaze/util/mpl/If.h>
83 #include <blaze/util/Null.h>
84 #include <blaze/util/Types.h>
87 
88 
89 namespace blaze {
90 
91 //=================================================================================================
92 //
93 // CLASS DEFINITION
94 //
95 //=================================================================================================
96 
97 //*************************************************************************************************
207 template< typename Type // Data type of the sparse matrix
208  , bool SO = defaultStorageOrder > // Storage order
209 class CompressedMatrix : public SparseMatrix< CompressedMatrix<Type,SO>, SO >
210 {
211  private:
212  //**Type definitions****************************************************************************
214  //**********************************************************************************************
215 
216  //**Private class Element***********************************************************************
220  struct Element : public ElementBase
221  {
222  // This operator is required due to a bug in all versions of the the MSVC compiler.
223  // A simple 'using ElementBase::operator=;' statement results in ambiguity problems.
224  template< typename Other >
225  inline Element& operator=( const Other& rhs )
226  {
227  ElementBase::operator=( rhs );
228  return *this;
229  }
230 
231  friend class CompressedMatrix;
232  };
234  //**********************************************************************************************
235 
236  //**Private class FindIndex*********************************************************************
240  struct FindIndex : public std::binary_function<Element,size_t,bool>
241  {
242  inline bool operator()( const Element& element, size_t index ) const {
243  return element.index() < index;
244  }
245  inline bool operator()( size_t index, const Element& element ) const {
246  return index < element.index();
247  }
248  inline bool operator()( const Element& element1, const Element& element2 ) const {
249  return element1.index() < element2.index();
250  }
251  };
253  //**********************************************************************************************
254 
255  public:
256  //**Type definitions****************************************************************************
258  typedef This ResultType;
261  typedef Type ElementType;
262  typedef const Type& ReturnType;
263  typedef const This& CompositeType;
265  typedef const Type& ConstReference;
266  typedef Element* Iterator;
267  typedef const Element* ConstIterator;
268  //**********************************************************************************************
269 
270  //**Rebind struct definition********************************************************************
273  template< typename ET > // Data type of the other matrix
274  struct Rebind {
276  };
277  //**********************************************************************************************
278 
279  //**Compilation flags***************************************************************************
281 
284  enum { smpAssignable = !IsSMPAssignable<Type>::value };
285  //**********************************************************************************************
286 
287  //**Constructors********************************************************************************
290  explicit inline CompressedMatrix();
291  explicit inline CompressedMatrix( size_t m, size_t n );
292  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
293  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
294  inline CompressedMatrix( const CompressedMatrix& sm );
295  template< typename MT, bool SO2 > inline CompressedMatrix( const DenseMatrix<MT,SO2>& dm );
296  template< typename MT, bool SO2 > inline CompressedMatrix( const SparseMatrix<MT,SO2>& sm );
298  //**********************************************************************************************
299 
300  //**Destructor**********************************************************************************
303  inline ~CompressedMatrix();
305  //**********************************************************************************************
306 
307  //**Data access functions***********************************************************************
310  inline Reference operator()( size_t i, size_t j );
311  inline ConstReference operator()( size_t i, size_t j ) const;
312  inline Iterator begin ( size_t i );
313  inline ConstIterator begin ( size_t i ) const;
314  inline ConstIterator cbegin( size_t i ) const;
315  inline Iterator end ( size_t i );
316  inline ConstIterator end ( size_t i ) const;
317  inline ConstIterator cend ( size_t i ) const;
319  //**********************************************************************************************
320 
321  //**Assignment operators************************************************************************
324  inline CompressedMatrix& operator= ( const CompressedMatrix& rhs );
325  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO2>& rhs );
326  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO2>& rhs );
327  template< typename MT, bool SO2 > inline CompressedMatrix& operator+=( const Matrix<MT,SO2>& rhs );
328  template< typename MT, bool SO2 > inline CompressedMatrix& operator-=( const Matrix<MT,SO2>& rhs );
329  template< typename MT, bool SO2 > inline CompressedMatrix& operator*=( const Matrix<MT,SO2>& rhs );
330 
331  template< typename Other >
332  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
333  operator*=( Other rhs );
334 
335  template< typename Other >
336  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
337  operator/=( Other rhs );
339  //**********************************************************************************************
340 
341  //**Utility functions***************************************************************************
344  inline size_t rows() const;
345  inline size_t columns() const;
346  inline size_t capacity() const;
347  inline size_t capacity( size_t i ) const;
348  inline size_t nonZeros() const;
349  inline size_t nonZeros( size_t i ) const;
350  inline void reset();
351  inline void reset( size_t i );
352  inline void clear();
353  inline Iterator set ( size_t i, size_t j, const Type& value );
354  inline Iterator insert ( size_t i, size_t j, const Type& value );
355  inline void erase ( size_t i, size_t j );
356  inline Iterator erase ( size_t i, Iterator pos );
357  inline Iterator erase ( size_t i, Iterator first, Iterator last );
358  void resize ( size_t m, size_t n, bool preserve=true );
359  inline void reserve( size_t nonzeros );
360  void reserve( size_t i, size_t nonzeros );
361  inline void trim ();
362  inline void trim ( size_t i );
363  inline CompressedMatrix& transpose();
364  template< typename Other > inline CompressedMatrix& scale( const Other& scalar );
365  template< typename Other > inline CompressedMatrix& scaleDiagonal( Other scalar );
366  inline void swap( CompressedMatrix& sm ) /* throw() */;
368  //**********************************************************************************************
369 
370  //**Lookup functions****************************************************************************
373  inline Iterator find ( size_t i, size_t j );
374  inline ConstIterator find ( size_t i, size_t j ) const;
375  inline Iterator lowerBound( size_t i, size_t j );
376  inline ConstIterator lowerBound( size_t i, size_t j ) const;
377  inline Iterator upperBound( size_t i, size_t j );
378  inline ConstIterator upperBound( size_t i, size_t j ) const;
380  //**********************************************************************************************
381 
382  //**Low-level utility functions*****************************************************************
385  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
386  inline void finalize( size_t i );
388  //**********************************************************************************************
389 
390  //**Expression template evaluation functions****************************************************
393  template< typename Other > inline bool canAlias ( const Other* alias ) const;
394  template< typename Other > inline bool isAliased( const Other* alias ) const;
395 
396  inline bool canSMPAssign() const;
397 
398  template< typename MT, bool SO2 > inline void assign ( const DenseMatrix<MT,SO2>& rhs );
399  template< typename MT > inline void assign ( const SparseMatrix<MT,SO>& rhs );
400  template< typename MT > inline void assign ( const SparseMatrix<MT,!SO>& rhs );
401  template< typename MT, bool SO2 > inline void addAssign( const DenseMatrix<MT,SO2>& rhs );
402  template< typename MT, bool SO2 > inline void addAssign( const SparseMatrix<MT,SO2>& rhs );
403  template< typename MT, bool SO2 > inline void subAssign( const DenseMatrix<MT,SO2>& rhs );
404  template< typename MT, bool SO2 > inline void subAssign( const SparseMatrix<MT,SO2>& rhs );
406  //**********************************************************************************************
407 
408  private:
409  //**Utility functions***************************************************************************
412  Iterator insert( Iterator pos, size_t i, size_t j, const Type& value );
413  inline size_t extendCapacity() const;
414  void reserveElements( size_t nonzeros );
416  //**********************************************************************************************
417 
418  //**Member variables****************************************************************************
421  size_t m_;
422  size_t n_;
423  size_t capacity_;
424  Iterator* begin_;
425  Iterator* end_;
426 
427  static const Type zero_;
428 
429  //**********************************************************************************************
430 
431  //**Compile time checks*************************************************************************
437  BLAZE_CONSTRAINT_MUST_HAVE_SAME_SIZE ( ElementBase, Element );
439  //**********************************************************************************************
440 };
441 //*************************************************************************************************
442 
443 
444 
445 
446 //=================================================================================================
447 //
448 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
449 //
450 //=================================================================================================
451 
452 template< typename Type, bool SO >
453 const Type CompressedMatrix<Type,SO>::zero_ = Type();
454 
455 
456 
457 
458 //=================================================================================================
459 //
460 // CONSTRUCTORS
461 //
462 //=================================================================================================
463 
464 //*************************************************************************************************
467 template< typename Type // Data type of the sparse matrix
468  , bool SO > // Storage order
470  : m_ ( 0UL ) // The current number of rows of the sparse matrix
471  , n_ ( 0UL ) // The current number of columns of the sparse matrix
472  , capacity_( 0UL ) // The current capacity of the pointer array
473  , begin_( new Iterator[2] ) // Pointers to the first non-zero element of each row
474  , end_ ( begin_+1 ) // Pointers one past the last non-zero element of each row
475 {
476  begin_[0] = end_[0] = NULL;
477 }
478 //*************************************************************************************************
479 
480 
481 //*************************************************************************************************
489 template< typename Type // Data type of the sparse matrix
490  , bool SO > // Storage order
492  : m_ ( m ) // The current number of rows of the sparse matrix
493  , n_ ( n ) // The current number of columns of the sparse matrix
494  , capacity_( m ) // The current capacity of the pointer array
495  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
496  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
497 {
498  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
499  begin_[i] = NULL;
500 }
501 //*************************************************************************************************
502 
503 
504 //*************************************************************************************************
513 template< typename Type // Data type of the sparse matrix
514  , bool SO > // Storage order
515 inline CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
516  : m_ ( m ) // The current number of rows of the sparse matrix
517  , n_ ( n ) // The current number of columns of the sparse matrix
518  , capacity_( m ) // The current capacity of the pointer array
519  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
520  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
521 {
522  begin_[0UL] = allocate<Element>( nonzeros );
523  for( size_t i=1UL; i<(2UL*m_+1UL); ++i )
524  begin_[i] = begin_[0UL];
525  end_[m_] = begin_[0UL]+nonzeros;
526 }
527 //*************************************************************************************************
528 
529 
530 //*************************************************************************************************
541 template< typename Type // Data type of the sparse matrix
542  , bool SO > // Storage order
543 CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
544  : m_ ( m ) // The current number of rows of the sparse matrix
545  , n_ ( n ) // The current number of columns of the sparse matrix
546  , capacity_( m ) // The current capacity of the pointer array
547  , begin_( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
548  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
549 {
550  BLAZE_USER_ASSERT( nonzeros.size() == m, "Size of capacity vector and number of rows don't match" );
551 
552  size_t newCapacity( 0UL );
553  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
554  newCapacity += *it;
555 
556  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
557  for( size_t i=0UL; i<m_; ++i ) {
558  begin_[i+1UL] = end_[i+1UL] = begin_[i] + nonzeros[i];
559  }
560 }
561 //*************************************************************************************************
562 
563 
564 //*************************************************************************************************
569 template< typename Type // Data type of the sparse matrix
570  , bool SO > // Storage order
572  : m_ ( sm.m_ ) // The current number of rows of the sparse matrix
573  , n_ ( sm.n_ ) // The current number of columns of the sparse matrix
574  , capacity_( sm.m_ ) // The current capacity of the pointer array
575  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
576  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
577 {
578  const size_t nonzeros( sm.nonZeros() );
579 
580  begin_[0UL] = allocate<Element>( nonzeros );
581  for( size_t i=0UL; i<m_; ++i )
582  begin_[i+1UL] = end_[i] = std::copy( sm.begin(i), sm.end(i), begin_[i] );
583  end_[m_] = begin_[0UL]+nonzeros;
584 }
585 //*************************************************************************************************
586 
587 
588 //*************************************************************************************************
593 template< typename Type // Data type of the sparse matrix
594  , bool SO > // Storage order
595 template< typename MT // Type of the foreign dense matrix
596  , bool SO2 > // Storage order of the foreign dense matrix
598  : m_ ( (~dm).rows() ) // The current number of rows of the sparse matrix
599  , n_ ( (~dm).columns() ) // The current number of columns of the sparse matrix
600  , capacity_( m_ ) // The current capacity of the pointer array
601  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
602  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
603 {
604  using blaze::assign;
605 
606  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
607  begin_[i] = NULL;
608 
609  assign( *this, ~dm );
610 }
611 //*************************************************************************************************
612 
613 
614 //*************************************************************************************************
619 template< typename Type // Data type of the sparse matrix
620  , bool SO > // Storage order
621 template< typename MT // Type of the foreign sparse matrix
622  , bool SO2 > // Storage order of the foreign sparse matrix
624  : m_ ( (~sm).rows() ) // The current number of rows of the sparse matrix
625  , n_ ( (~sm).columns() ) // The current number of columns of the sparse matrix
626  , capacity_( m_ ) // The current capacity of the pointer array
627  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
628  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
629 {
630  using blaze::assign;
631 
632  const size_t nonzeros( (~sm).nonZeros() );
633 
634  begin_[0UL] = allocate<Element>( nonzeros );
635  for( size_t i=0UL; i<m_; ++i )
636  begin_[i+1UL] = end_[i] = begin_[0UL];
637  end_[m_] = begin_[0UL]+nonzeros;
638 
639  assign( *this, ~sm );
640 }
641 //*************************************************************************************************
642 
643 
644 
645 
646 //=================================================================================================
647 //
648 // DESTRUCTOR
649 //
650 //=================================================================================================
651 
652 //*************************************************************************************************
655 template< typename Type // Data type of the sparse matrix
656  , bool SO > // Storage order
658 {
659  deallocate( begin_[0UL] );
660  delete [] begin_;
661 }
662 //*************************************************************************************************
663 
664 
665 
666 
667 //=================================================================================================
668 //
669 // DATA ACCESS FUNCTIONS
670 //
671 //=================================================================================================
672 
673 //*************************************************************************************************
680 template< typename Type // Data type of the sparse matrix
681  , bool SO > // Storage order
684 {
685  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
686  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
687 
688  return Reference( *this, i, j );
689 }
690 //*************************************************************************************************
691 
692 
693 //*************************************************************************************************
700 template< typename Type // Data type of the sparse matrix
701  , bool SO > // Storage order
703  CompressedMatrix<Type,SO>::operator()( size_t i, size_t j ) const
704 {
705  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
706  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
707 
708  const ConstIterator pos( lowerBound( i, j ) );
709 
710  if( pos == end_[i] || pos->index_ != j )
711  return zero_;
712  else
713  return pos->value_;
714 }
715 //*************************************************************************************************
716 
717 
718 //*************************************************************************************************
729 template< typename Type // Data type of the sparse matrix
730  , bool SO > // Storage order
733 {
734  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
735  return begin_[i];
736 }
737 //*************************************************************************************************
738 
739 
740 //*************************************************************************************************
751 template< typename Type // Data type of the sparse matrix
752  , bool SO > // Storage order
755 {
756  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
757  return begin_[i];
758 }
759 //*************************************************************************************************
760 
761 
762 //*************************************************************************************************
773 template< typename Type // Data type of the sparse matrix
774  , bool SO > // Storage order
777 {
778  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
779  return begin_[i];
780 }
781 //*************************************************************************************************
782 
783 
784 //*************************************************************************************************
795 template< typename Type // Data type of the sparse matrix
796  , bool SO > // Storage order
799 {
800  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
801  return end_[i];
802 }
803 //*************************************************************************************************
804 
805 
806 //*************************************************************************************************
817 template< typename Type // Data type of the sparse matrix
818  , bool SO > // Storage order
821 {
822  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
823  return end_[i];
824 }
825 //*************************************************************************************************
826 
827 
828 //*************************************************************************************************
839 template< typename Type // Data type of the sparse matrix
840  , bool SO > // Storage order
843 {
844  BLAZE_USER_ASSERT( i < m_, "Invalid sparse matrix row access index" );
845  return end_[i];
846 }
847 //*************************************************************************************************
848 
849 
850 
851 
852 //=================================================================================================
853 //
854 // ASSIGNMENT OPERATORS
855 //
856 //=================================================================================================
857 
858 //*************************************************************************************************
867 template< typename Type // Data type of the sparse matrix
868  , bool SO > // Storage order
871 {
872  if( &rhs == this ) return *this;
873 
874  const size_t nonzeros( rhs.nonZeros() );
875 
876  if( rhs.m_ > capacity_ || nonzeros > capacity() )
877  {
878  Iterator* newBegin( new Iterator[2UL*rhs.m_+2UL] );
879  Iterator* newEnd ( newBegin+(rhs.m_+1UL) );
880 
881  newBegin[0UL] = allocate<Element>( nonzeros );
882  for( size_t i=0UL; i<rhs.m_; ++i ) {
883  newBegin[i+1UL] = newEnd[i] = std::copy( rhs.begin_[i], rhs.end_[i], newBegin[i] );
884  }
885  newEnd[rhs.m_] = newBegin[0UL]+nonzeros;
886 
887  std::swap( begin_, newBegin );
888  end_ = newEnd;
889  deallocate( newBegin[0UL] );
890  delete [] newBegin;
891  capacity_ = rhs.m_;
892  }
893  else {
894  for( size_t i=0UL; i<rhs.m_; ++i ) {
895  begin_[i+1UL] = end_[i] = std::copy( rhs.begin_[i], rhs.end_[i], begin_[i] );
896  }
897  }
898 
899  m_ = rhs.m_;
900  n_ = rhs.n_;
901 
902  return *this;
903 }
904 //*************************************************************************************************
905 
906 
907 //*************************************************************************************************
916 template< typename Type // Data type of the sparse matrix
917  , bool SO > // Storage order
918 template< typename MT // Type of the right-hand side dense matrix
919  , bool SO2 > // Storage order of the right-hand side dense matrix
922 {
923  using blaze::assign;
924 
925  if( (~rhs).canAlias( this ) ) {
926  CompressedMatrix tmp( ~rhs );
927  swap( tmp );
928  }
929  else {
930  resize( (~rhs).rows(), (~rhs).columns(), false );
931  assign( *this, ~rhs );
932  }
933 
934  return *this;
935 }
936 //*************************************************************************************************
937 
938 
939 //*************************************************************************************************
948 template< typename Type // Data type of the sparse matrix
949  , bool SO > // Storage order
950 template< typename MT // Type of the right-hand side sparse matrix
951  , bool SO2 > // Storage order of the right-hand side sparse matrix
954 {
955  using blaze::assign;
956 
957  if( (~rhs).canAlias( this ) ||
958  (~rhs).rows() > capacity_ ||
959  (~rhs).nonZeros() > capacity() ) {
960  CompressedMatrix tmp( ~rhs );
961  swap( tmp );
962  }
963  else {
964  resize( (~rhs).rows(), (~rhs).columns(), false );
965  reset();
966  assign( *this, ~rhs );
967  }
968 
969  return *this;
970 }
971 //*************************************************************************************************
972 
973 
974 //*************************************************************************************************
984 template< typename Type // Data type of the sparse matrix
985  , bool SO > // Storage order
986 template< typename MT // Type of the right-hand side matrix
987  , bool SO2 > // Storage order of the right-hand side matrix
990 {
991  using blaze::addAssign;
992 
993  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
994  throw std::invalid_argument( "Matrix sizes do not match" );
995 
996  addAssign( *this, ~rhs );
997  return *this;
998 }
999 //*************************************************************************************************
1000 
1001 
1002 //*************************************************************************************************
1012 template< typename Type // Data type of the sparse matrix
1013  , bool SO > // Storage order
1014 template< typename MT // Type of the right-hand side matrix
1015  , bool SO2 > // Storage order of the right-hand side matrix
1017 {
1018  using blaze::subAssign;
1019 
1020  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
1021  throw std::invalid_argument( "Matrix sizes do not match" );
1022 
1023  subAssign( *this, ~rhs );
1024  return *this;
1025 }
1026 //*************************************************************************************************
1027 
1028 
1029 //*************************************************************************************************
1039 template< typename Type // Data type of the sparse matrix
1040  , bool SO > // Storage order
1041 template< typename MT // Type of the right-hand side matrix
1042  , bool SO2 > // Storage order of the right-hand side matrix
1045 {
1046  if( (~rhs).rows() != n_ )
1047  throw std::invalid_argument( "Matrix sizes do not match" );
1048 
1049  CompressedMatrix tmp( *this * (~rhs) );
1050  swap( tmp );
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  for( size_t i=0UL; i<m_; ++i ) {
1071  const Iterator last( end(i) );
1072  for( Iterator element=begin(i); element!=last; ++element )
1073  element->value_ *= rhs;
1074  }
1075  return *this;
1076 }
1077 //*************************************************************************************************
1078 
1079 
1080 //*************************************************************************************************
1087 template< typename Type // Data type of the sparse matrix
1088  , bool SO > // Storage order
1089 template< typename Other > // Data type of the right-hand side scalar
1090 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,SO> >::Type&
1092 {
1093  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1094 
1095  typedef typename DivTrait<Type,Other>::Type DT;
1096  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
1097 
1098  // Depending on the two involved data types, an integer division is applied or a
1099  // floating point division is selected.
1101  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1102  for( size_t i=0UL; i<m_; ++i ) {
1103  const Iterator last( end(i) );
1104  for( Iterator element=begin(i); element!=last; ++element )
1105  element->value_ *= tmp;
1106  }
1107  }
1108  else {
1109  for( size_t i=0UL; i<m_; ++i ) {
1110  const Iterator last( end(i) );
1111  for( Iterator element=begin(i); element!=last; ++element )
1112  element->value_ /= rhs;
1113  }
1114  }
1115 
1116  return *this;
1117 }
1118 //*************************************************************************************************
1119 
1120 
1121 
1122 
1123 //=================================================================================================
1124 //
1125 // UTILITY FUNCTIONS
1126 //
1127 //=================================================================================================
1128 
1129 //*************************************************************************************************
1134 template< typename Type // Data type of the sparse matrix
1135  , bool SO > // Storage order
1136 inline size_t CompressedMatrix<Type,SO>::rows() const
1137 {
1138  return m_;
1139 }
1140 //*************************************************************************************************
1141 
1142 
1143 //*************************************************************************************************
1148 template< typename Type // Data type of the sparse matrix
1149  , bool SO > // Storage order
1151 {
1152  return n_;
1153 }
1154 //*************************************************************************************************
1155 
1156 
1157 //*************************************************************************************************
1162 template< typename Type // Data type of the sparse matrix
1163  , bool SO > // Storage order
1165 {
1166  return end_[m_] - begin_[0UL];
1167 }
1168 //*************************************************************************************************
1169 
1170 
1171 //*************************************************************************************************
1182 template< typename Type // Data type of the sparse matrix
1183  , bool SO > // Storage order
1184 inline size_t CompressedMatrix<Type,SO>::capacity( size_t i ) const
1185 {
1186  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1187  return begin_[i+1UL] - begin_[i];
1188 }
1189 //*************************************************************************************************
1190 
1191 
1192 //*************************************************************************************************
1197 template< typename Type // Data type of the sparse matrix
1198  , bool SO > // Storage order
1200 {
1201  size_t nonzeros( 0UL );
1202 
1203  for( size_t i=0UL; i<m_; ++i )
1204  nonzeros += nonZeros( i );
1205 
1206  return nonzeros;
1207 }
1208 //*************************************************************************************************
1209 
1210 
1211 //*************************************************************************************************
1222 template< typename Type // Data type of the sparse matrix
1223  , bool SO > // Storage order
1224 inline size_t CompressedMatrix<Type,SO>::nonZeros( size_t i ) const
1225 {
1226  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1227  return end_[i] - begin_[i];
1228 }
1229 //*************************************************************************************************
1230 
1231 
1232 //*************************************************************************************************
1237 template< typename Type // Data type of the sparse matrix
1238  , bool SO > // Storage order
1240 {
1241  for( size_t i=0UL; i<m_; ++i )
1242  end_[i] = begin_[i];
1243 }
1244 //*************************************************************************************************
1245 
1246 
1247 //*************************************************************************************************
1258 template< typename Type // Data type of the sparse matrix
1259  , bool SO > // Storage order
1260 inline void CompressedMatrix<Type,SO>::reset( size_t i )
1261 {
1262  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1263  end_[i] = begin_[i];
1264 }
1265 //*************************************************************************************************
1266 
1267 
1268 //*************************************************************************************************
1275 template< typename Type // Data type of the sparse matrix
1276  , bool SO > // Storage order
1278 {
1279  end_[0UL] = end_[m_];
1280  m_ = 0UL;
1281  n_ = 0UL;
1282 }
1283 //*************************************************************************************************
1284 
1285 
1286 //*************************************************************************************************
1298 template< typename Type // Data type of the sparse matrix
1299  , bool SO > // Storage order
1301  CompressedMatrix<Type,SO>::set( size_t i, size_t j, const Type& value )
1302 {
1303  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1304  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1305 
1306  const Iterator pos( lowerBound( i, j ) );
1307 
1308  if( pos != end_[i] && pos->index_ == j ) {
1309  pos->value() = value;
1310  return pos;
1311  }
1312  else return insert( pos, i, j, value );
1313 }
1314 //*************************************************************************************************
1315 
1316 
1317 //*************************************************************************************************
1330 template< typename Type // Data type of the sparse matrix
1331  , bool SO > // Storage order
1333  CompressedMatrix<Type,SO>::insert( size_t i, size_t j, const Type& value )
1334 {
1335  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1336  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1337 
1338  const Iterator pos( lowerBound( i, j ) );
1339 
1340  if( pos != end_[i] && pos->index_ == j )
1341  throw std::invalid_argument( "Bad access index" );
1342 
1343  return insert( pos, i, j, value );
1344 }
1345 //*************************************************************************************************
1346 
1347 
1348 //*************************************************************************************************
1358 template< typename Type // Data type of the sparse matrix
1359  , bool SO > // Storage order
1361  CompressedMatrix<Type,SO>::insert( Iterator pos, size_t i, size_t j, const Type& value )
1362 {
1363  if( begin_[i+1UL] - end_[i] != 0 ) {
1364  std::copy_backward( pos, end_[i], end_[i]+1 );
1365  pos->value_ = value;
1366  pos->index_ = j;
1367  ++end_[i];
1368 
1369  return pos;
1370  }
1371  else if( end_[m_] - begin_[m_] != 0 ) {
1372  std::copy_backward( pos, end_[m_-1UL], end_[m_-1UL]+1 );
1373 
1374  pos->value_ = value;
1375  pos->index_ = j;
1376 
1377  for( size_t k=i+1UL; k<m_+1UL; ++k ) {
1378  ++begin_[k];
1379  ++end_[k-1UL];
1380  }
1381 
1382  return pos;
1383  }
1384  else {
1385  size_t newCapacity( extendCapacity() );
1386 
1387  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1388  Iterator* newEnd = newBegin+capacity_+1UL;
1389 
1390  newBegin[0UL] = allocate<Element>( newCapacity );
1391 
1392  for( size_t k=0UL; k<i; ++k ) {
1393  const size_t nonzeros( end_[k] - begin_[k] );
1394  const size_t total( begin_[k+1UL] - begin_[k] );
1395  newEnd [k] = newBegin[k] + nonzeros;
1396  newBegin[k+1UL] = newBegin[k] + total;
1397  }
1398  newEnd [i] = newBegin[i] + ( end_[i] - begin_[i] ) + 1;
1399  newBegin[i+1UL] = newBegin[i] + ( begin_[i+1] - begin_[i] ) + 1;
1400  for( size_t k=i+1UL; k<m_; ++k ) {
1401  const size_t nonzeros( end_[k] - begin_[k] );
1402  const size_t total( begin_[k+1UL] - begin_[k] );
1403  newEnd [k] = newBegin[k] + nonzeros;
1404  newBegin[k+1UL] = newBegin[k] + total;
1405  }
1406 
1407  newEnd[m_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
1408 
1409  Iterator tmp = std::copy( begin_[0UL], pos, newBegin[0UL] );
1410  tmp->value_ = value;
1411  tmp->index_ = j;
1412  std::copy( pos, end_[m_-1UL], tmp+1UL );
1413 
1414  std::swap( newBegin, begin_ );
1415  end_ = newEnd;
1416  deallocate( newBegin[0UL] );
1417  delete [] newBegin;
1418 
1419  return tmp;
1420  }
1421 }
1422 //*************************************************************************************************
1423 
1424 
1425 //*************************************************************************************************
1434 template< typename Type // Data type of the sparse matrix
1435  , bool SO > // Storage order
1436 inline void CompressedMatrix<Type,SO>::erase( size_t i, size_t j )
1437 {
1438  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1439  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1440 
1441  const Iterator pos( find( i, j ) );
1442  if( pos != end_[i] )
1443  end_[i] = std::copy( pos+1, end_[i], pos );
1444 }
1445 //*************************************************************************************************
1446 
1447 
1448 //*************************************************************************************************
1459 template< typename Type // Data type of the sparse matrix
1460  , bool SO > // Storage order
1463 {
1464  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1465  BLAZE_USER_ASSERT( pos >= begin_[i] && pos <= end_[i], "Invalid compressed matrix iterator" );
1466 
1467  if( pos != end_[i] )
1468  end_[i] = std::copy( pos+1, end_[i], pos );
1469 
1470  return pos;
1471 }
1472 //*************************************************************************************************
1473 
1474 
1475 //*************************************************************************************************
1487 template< typename Type // Data type of the sparse matrix
1488  , bool SO > // Storage order
1491 {
1492  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1493  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
1494  BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i], "Invalid compressed matrix iterator" );
1495  BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i], "Invalid compressed matrix iterator" );
1496 
1497  if( first != last )
1498  end_[i] = std::copy( last, end_[i], first );
1499 
1500  return first;
1501 }
1502 //*************************************************************************************************
1503 
1504 
1505 //*************************************************************************************************
1520 template< typename Type // Data type of the sparse matrix
1521  , bool SO > // Storage order
1522 void CompressedMatrix<Type,SO>::resize( size_t m, size_t n, bool preserve )
1523 {
1524  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1525  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1526 
1527  if( m == m_ && n == n_ ) return;
1528 
1529  if( m > capacity_ )
1530  {
1531  Iterator* newBegin( new Iterator[2UL*m+2UL] );
1532  Iterator* newEnd ( newBegin+m+1UL );
1533 
1534  newBegin[0UL] = begin_[0UL];
1535 
1536  if( preserve ) {
1537  for( size_t i=0UL; i<m_; ++i ) {
1538  newEnd [i] = end_ [i];
1539  newBegin[i+1UL] = begin_[i+1UL];
1540  }
1541  for( size_t i=m_; i<m; ++i ) {
1542  newBegin[i+1UL] = newEnd[i] = begin_[m_];
1543  }
1544  }
1545  else {
1546  for( size_t i=0UL; i<m; ++i ) {
1547  newBegin[i+1UL] = newEnd[i] = begin_[0UL];
1548  }
1549  }
1550 
1551  newEnd[m] = end_[m_];
1552 
1553  std::swap( newBegin, begin_ );
1554  delete [] newBegin;
1555 
1556  end_ = newEnd;
1557  capacity_ = m;
1558  }
1559  else if( m > m_ )
1560  {
1561  end_[m] = end_[m_];
1562 
1563  if( !preserve ) {
1564  for( size_t i=0UL; i<m_; ++i )
1565  end_[i] = begin_[i];
1566  }
1567 
1568  for( size_t i=m_; i<m; ++i )
1569  begin_[i+1UL] = end_[i] = begin_[m_];
1570  }
1571  else
1572  {
1573  if( preserve ) {
1574  for( size_t i=0UL; i<m; ++i )
1575  end_[i] = lowerBound( i, n );
1576  }
1577  else {
1578  for( size_t i=0UL; i<m; ++i )
1579  end_[i] = begin_[i];
1580  }
1581 
1582  end_[m] = end_[m_];
1583  }
1584 
1585  m_ = m;
1586  n_ = n;
1587 
1588  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1589  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1590 }
1591 //*************************************************************************************************
1592 
1593 
1594 //*************************************************************************************************
1604 template< typename Type // Data type of the sparse matrix
1605  , bool SO > // Storage order
1606 inline void CompressedMatrix<Type,SO>::reserve( size_t nonzeros )
1607 {
1608  if( nonzeros > capacity() )
1609  reserveElements( nonzeros );
1610 }
1611 //*************************************************************************************************
1612 
1613 
1614 //*************************************************************************************************
1628 template< typename Type // Data type of the sparse matrix
1629  , bool SO > // Storage order
1630 void CompressedMatrix<Type,SO>::reserve( size_t i, size_t nonzeros )
1631 {
1632  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1633 
1634  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1635  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1636 
1637  const size_t current( capacity(i) );
1638 
1639  if( current >= nonzeros ) return;
1640 
1641  const ptrdiff_t additional( nonzeros - current );
1642 
1643  if( end_[m_] - begin_[m_] < additional )
1644  {
1645  const size_t newCapacity( begin_[m_] - begin_[0UL] + additional );
1646  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
1647 
1648  Iterator* newBegin( new Iterator[2UL*m_+2UL] );
1649  Iterator* newEnd ( newBegin+m_+1UL );
1650 
1651  newBegin[0UL] = allocate<Element>( newCapacity );
1652  newEnd [m_ ] = newBegin[0UL]+newCapacity;
1653 
1654  for( size_t k=0UL; k<i; ++k ) {
1655  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
1656  newBegin[k+1UL] = newBegin[k] + capacity(k);
1657  }
1658  newEnd [i ] = std::copy( begin_[i], end_[i], newBegin[i] );
1659  newBegin[i+1UL] = newBegin[i] + nonzeros;
1660  for( size_t k=i+1UL; k<m_; ++k ) {
1661  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
1662  newBegin[k+1UL] = newBegin[k] + capacity(k);
1663  }
1664 
1665  BLAZE_INTERNAL_ASSERT( newBegin[m_] == newEnd[m_], "Invalid pointer calculations" );
1666 
1667  std::swap( newBegin, begin_ );
1668  deallocate( newBegin[0UL] );
1669  delete [] newBegin;
1670  end_ = newEnd;
1671  capacity_ = m_;
1672  }
1673  else
1674  {
1675  begin_[m_] += additional;
1676  for( size_t j=m_-1UL; j>i; --j ) {
1677  begin_[j] = std::copy_backward( begin_[j], end_[j], end_[j]+additional );
1678  end_ [j] += additional;
1679  }
1680  }
1681 
1682  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1683  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1684 }
1685 //*************************************************************************************************
1686 
1687 
1688 //*************************************************************************************************
1698 template< typename Type // Data type of the sparse matrix
1699  , bool SO > // Storage order
1701 {
1702  for( size_t i=0UL; i<m_; ++i )
1703  trim( i );
1704 }
1705 //*************************************************************************************************
1706 
1707 
1708 //*************************************************************************************************
1719 template< typename Type // Data type of the sparse matrix
1720  , bool SO > // Storage order
1721 inline void CompressedMatrix<Type,SO>::trim( size_t i )
1722 {
1723  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1724 
1725  if( i < ( m_ - 1UL ) )
1726  end_[i+1] = std::copy( begin_[i+1], end_[i+1], end_[i] );
1727  begin_[i+1] = end_[i];
1728 }
1729 //*************************************************************************************************
1730 
1731 
1732 //*************************************************************************************************
1737 template< typename Type // Data type of the sparse matrix
1738  , bool SO > // Storage order
1740 {
1741  CompressedMatrix tmp( trans( *this ) );
1742  swap( tmp );
1743  return *this;
1744 }
1745 //*************************************************************************************************
1746 
1747 
1748 //*************************************************************************************************
1754 template< typename Type // Data type of the sparse matrix
1755  , bool SO > // Storage order
1756 template< typename Other > // Data type of the scalar value
1758 {
1759  for( size_t i=0UL; i<m_; ++i )
1760  for( Iterator element=begin_[i]; element!=end_[i]; ++element )
1761  element->value_ *= scalar;
1762 
1763  return *this;
1764 }
1765 //*************************************************************************************************
1766 
1767 
1768 //*************************************************************************************************
1774 template< typename Type // Data type of the sparse matrix
1775  , bool SO > // Storage order
1776 template< typename Other > // Data type of the scalar value
1778 {
1779  const size_t size( blaze::min( m_, n_ ) );
1780 
1781  for( size_t i=0UL; i<size; ++i ) {
1782  Iterator pos = lowerBound( i, i );
1783  if( pos != end_[i] && pos->index_ == i )
1784  pos->value_ *= scalar;
1785  }
1786 
1787  return *this;
1788 }
1789 //*************************************************************************************************
1790 
1791 
1792 //*************************************************************************************************
1799 template< typename Type // Data type of the sparse matrix
1800  , bool SO > // Storage order
1801 inline void CompressedMatrix<Type,SO>::swap( CompressedMatrix& sm ) /* throw() */
1802 {
1803  std::swap( m_, sm.m_ );
1804  std::swap( n_, sm.n_ );
1805  std::swap( capacity_, sm.capacity_ );
1806  std::swap( begin_, sm.begin_ );
1807  std::swap( end_ , sm.end_ );
1808 }
1809 //*************************************************************************************************
1810 
1811 
1812 //*************************************************************************************************
1820 template< typename Type // Data type of the sparse matrix
1821  , bool SO > // Storage order
1823 {
1824  size_t nonzeros( 2UL*capacity()+1UL );
1825  nonzeros = blaze::max( nonzeros, 7UL );
1826 
1827  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
1828 
1829  return nonzeros;
1830 }
1831 //*************************************************************************************************
1832 
1833 
1834 //*************************************************************************************************
1840 template< typename Type // Data type of the sparse matrix
1841  , bool SO > // Storage order
1843 {
1844  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1845  Iterator* newEnd = newBegin+capacity_+1UL;
1846 
1847  newBegin[0UL] = allocate<Element>( nonzeros );
1848 
1849  for( size_t k=0UL; k<m_; ++k ) {
1850  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid row pointers" );
1851  newEnd [k] = std::copy( begin_[k], end_[k], newBegin[k] );
1852  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
1853  }
1854 
1855  newEnd[m_] = newBegin[0UL]+nonzeros;
1856 
1857  std::swap( newBegin, begin_ );
1858  deallocate( newBegin[0UL] );
1859  delete [] newBegin;
1860  end_ = newEnd;
1861 }
1862 //*************************************************************************************************
1863 
1864 
1865 
1866 
1867 //=================================================================================================
1868 //
1869 // LOOKUP FUNCTIONS
1870 //
1871 //=================================================================================================
1872 
1873 //*************************************************************************************************
1888 template< typename Type // Data type of the sparse matrix
1889  , bool SO > // Storage order
1891  CompressedMatrix<Type,SO>::find( size_t i, size_t j )
1892 {
1893  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
1894 }
1895 //*************************************************************************************************
1896 
1897 
1898 //*************************************************************************************************
1913 template< typename Type // Data type of the sparse matrix
1914  , bool SO > // Storage order
1916  CompressedMatrix<Type,SO>::find( size_t i, size_t j ) const
1917 {
1918  const ConstIterator pos( lowerBound( i, j ) );
1919  if( pos != end_[i] && pos->index_ == j )
1920  return pos;
1921  else return end_[i];
1922 }
1923 //*************************************************************************************************
1924 
1925 
1926 //*************************************************************************************************
1941 template< typename Type // Data type of the sparse matrix
1942  , bool SO > // Storage order
1945 {
1946  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
1947 }
1948 //*************************************************************************************************
1949 
1950 
1951 //*************************************************************************************************
1966 template< typename Type // Data type of the sparse matrix
1967  , bool SO > // Storage order
1969  CompressedMatrix<Type,SO>::lowerBound( size_t i, size_t j ) const
1970 {
1971  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1972  return std::lower_bound( begin_[i], end_[i], j, FindIndex() );
1973 }
1974 //*************************************************************************************************
1975 
1976 
1977 //*************************************************************************************************
1992 template< typename Type // Data type of the sparse matrix
1993  , bool SO > // Storage order
1996 {
1997  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
1998 }
1999 //*************************************************************************************************
2000 
2001 
2002 //*************************************************************************************************
2017 template< typename Type // Data type of the sparse matrix
2018  , bool SO > // Storage order
2020  CompressedMatrix<Type,SO>::upperBound( size_t i, size_t j ) const
2021 {
2022  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2023  return std::upper_bound( begin_[i], end_[i], j, FindIndex() );
2024 }
2025 //*************************************************************************************************
2026 
2027 
2028 
2029 
2030 //=================================================================================================
2031 //
2032 // LOW-LEVEL UTILITY FUNCTIONS
2033 //
2034 //=================================================================================================
2035 
2036 //*************************************************************************************************
2080 template< typename Type // Data type of the sparse matrix
2081  , bool SO > // Storage order
2082 inline void CompressedMatrix<Type,SO>::append( size_t i, size_t j, const Type& value, bool check )
2083 {
2084  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2085  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
2086  BLAZE_USER_ASSERT( end_[i] < end_[m_], "Not enough reserved capacity left" );
2087  BLAZE_USER_ASSERT( begin_[i] == end_[i] || j > ( end_[i]-1UL )->index_, "Index is not strictly increasing" );
2088 
2089  end_[i]->value_ = value;
2090 
2091  if( !check || !isDefault( end_[i]->value_ ) ) {
2092  end_[i]->index_ = j;
2093  ++end_[i];
2094  }
2095 }
2096 //*************************************************************************************************
2097 
2098 
2099 //*************************************************************************************************
2112 template< typename Type // Data type of the sparse matrix
2113  , bool SO > // Storage order
2115 {
2116  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2117 
2118  begin_[i+1UL] = end_[i];
2119  if( i != m_-1UL )
2120  end_[i+1UL] = end_[i];
2121 }
2122 //*************************************************************************************************
2123 
2124 
2125 
2126 
2127 //=================================================================================================
2128 //
2129 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2130 //
2131 //=================================================================================================
2132 
2133 //*************************************************************************************************
2143 template< typename Type // Data type of the sparse matrix
2144  , bool SO > // Storage order
2145 template< typename Other > // Data type of the foreign expression
2146 inline bool CompressedMatrix<Type,SO>::canAlias( const Other* alias ) const
2147 {
2148  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2149 }
2150 //*************************************************************************************************
2151 
2152 
2153 //*************************************************************************************************
2163 template< typename Type // Data type of the sparse matrix
2164  , bool SO > // Storage order
2165 template< typename Other > // Data type of the foreign expression
2166 inline bool CompressedMatrix<Type,SO>::isAliased( const Other* alias ) const
2167 {
2168  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2169 }
2170 //*************************************************************************************************
2171 
2172 
2173 //*************************************************************************************************
2183 template< typename Type // Data type of the sparse matrix
2184  , bool SO > // Storage order
2186 {
2187  return false;
2188 }
2189 //*************************************************************************************************
2190 
2191 
2192 //*************************************************************************************************
2203 template< typename Type // Data type of the sparse matrix
2204  , bool SO > // Storage order
2205 template< typename MT // Type of the right-hand side dense matrix
2206  , bool SO2 > // Storage order of the right-hand side dense matrix
2208 {
2209  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2210  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2211 
2212  size_t nonzeros( 0UL );
2213 
2214  for( size_t i=1UL; i<=m_; ++i )
2215  begin_[i] = end_[i] = end_[m_];
2216 
2217  for( size_t i=0UL; i<m_; ++i )
2218  {
2219  begin_[i] = end_[i] = begin_[0UL]+nonzeros;
2220 
2221  const size_t jbegin( ( IsUpper<MT>::value )
2222  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2223  :( 0UL ) );
2224  const size_t jend ( ( IsLower<MT>::value )
2225  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2226  :( n_ ) );
2227 
2228  for( size_t j=jbegin; j<jend; ++j )
2229  {
2230  if( nonzeros == capacity() ) {
2231  reserveElements( extendCapacity() );
2232  for( size_t k=i+1UL; k<=m_; ++k )
2233  begin_[k] = end_[k] = end_[m_];
2234  }
2235 
2236  end_[i]->value_ = (~rhs)(i,j);
2237 
2238  if( !isDefault( end_[i]->value_ ) ) {
2239  end_[i]->index_ = j;
2240  ++end_[i];
2241  ++nonzeros;
2242  }
2243  }
2244  }
2245 
2246  begin_[m_] = begin_[0UL]+nonzeros;
2247 }
2248 //*************************************************************************************************
2249 
2250 
2251 //*************************************************************************************************
2262 template< typename Type // Data type of the sparse matrix
2263  , bool SO > // Storage order
2264 template< typename MT > // Type of the right-hand side sparse matrix
2266 {
2267  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2268  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2269  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2270  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
2271 
2272  if( m_ == 0UL || begin_[0] == NULL )
2273  return;
2274 
2275  for( size_t i=0UL; i<m_; ++i ) {
2276  begin_[i+1UL] = end_[i] = std::copy( (~rhs).begin(i), (~rhs).end(i), begin_[i] );
2277  }
2278 }
2279 //*************************************************************************************************
2280 
2281 
2282 //*************************************************************************************************
2293 template< typename Type // Data type of the sparse matrix
2294  , bool SO > // Storage order
2295 template< typename MT > // Type of the right-hand side sparse matrix
2297 {
2299 
2300  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2301  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2302  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2303  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
2304 
2305  typedef typename MT::ConstIterator RhsIterator;
2306 
2307  // Counting the number of elements per row
2308  std::vector<size_t> rowLengths( m_, 0UL );
2309  for( size_t j=0UL; j<n_; ++j ) {
2310  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2311  ++rowLengths[element->index()];
2312  }
2313 
2314  // Resizing the sparse matrix
2315  for( size_t i=0UL; i<m_; ++i ) {
2316  begin_[i+1UL] = end_[i+1UL] = begin_[i] + rowLengths[i];
2317  }
2318 
2319  // Appending the elements to the rows of the sparse matrix
2320  for( size_t j=0UL; j<n_; ++j ) {
2321  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2322  append( element->index(), j, element->value() );
2323  }
2324 }
2325 //*************************************************************************************************
2326 
2327 
2328 //*************************************************************************************************
2339 template< typename Type // Data type of the sparse matrix
2340  , bool SO > // Storage order
2341 template< typename MT // Type of the right-hand side dense matrix
2342  , bool SO2 > // Storage order of the right-hand side dense matrix
2344 {
2345  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2346  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2347 
2348  CompressedMatrix tmp( serial( *this + (~rhs) ) );
2349  swap( tmp );
2350 }
2351 //*************************************************************************************************
2352 
2353 
2354 //*************************************************************************************************
2365 template< typename Type // Data type of the sparse matrix
2366  , bool SO > // Storage order
2367 template< typename MT // Type of the right-hand side sparse matrix
2368  , bool SO2 > // Storage order of the right-hand side sparse matrix
2370 {
2371  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2372  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2373 
2374  CompressedMatrix tmp( serial( *this + (~rhs) ) );
2375  swap( tmp );
2376 }
2377 //*************************************************************************************************
2378 
2379 
2380 //*************************************************************************************************
2391 template< typename Type // Data type of the sparse matrix
2392  , bool SO > // Storage order
2393 template< typename MT // Type of the right-hand side dense matrix
2394  , bool SO2 > // Storage order of the right-hand side dense matrix
2396 {
2397  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2398  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2399 
2400  CompressedMatrix tmp( serial( *this - (~rhs) ) );
2401  swap( tmp );
2402 }
2403 //*************************************************************************************************
2404 
2405 
2406 //*************************************************************************************************
2417 template< typename Type // Data type of the sparse matrix
2418  , bool SO > // Storage order
2419 template< typename MT // Type of the right-hand side sparse matrix
2420  , bool SO2 > // Storage order of the right-hand sparse matrix
2422 {
2423  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2424  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2425 
2426  CompressedMatrix tmp( serial( *this - (~rhs) ) );
2427  swap( tmp );
2428 }
2429 //*************************************************************************************************
2430 
2431 
2432 
2433 
2434 
2435 
2436 
2437 
2438 //=================================================================================================
2439 //
2440 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2441 //
2442 //=================================================================================================
2443 
2444 //*************************************************************************************************
2452 template< typename Type > // Data type of the sparse matrix
2453 class CompressedMatrix<Type,true> : public SparseMatrix< CompressedMatrix<Type,true>, true >
2454 {
2455  private:
2456  //**Type definitions****************************************************************************
2458  //**********************************************************************************************
2459 
2460  //**Private class Element***********************************************************************
2464  struct Element : public ElementBase
2465  {
2466  // This operator is required due to a bug in all versions of the the MSVC compiler.
2467  // A simple 'using ElementBase::operator=;' statement results in ambiguity problems.
2468  template< typename Other >
2469  inline Element& operator=( const Other& rhs )
2470  {
2471  ElementBase::operator=( rhs );
2472  return *this;
2473  }
2474 
2475  friend class CompressedMatrix;
2476  };
2478  //**********************************************************************************************
2479 
2480  //**Private class FindIndex*********************************************************************
2484  struct FindIndex : public std::binary_function<Element,size_t,bool>
2485  {
2486  inline bool operator()( const Element& element, size_t index ) const {
2487  return element.index() < index;
2488  }
2489  inline bool operator()( size_t index, const Element& element ) const {
2490  return index < element.index();
2491  }
2492  inline bool operator()( const Element& element1, const Element& element2 ) const {
2493  return element1.index() < element2.index();
2494  }
2495  };
2497  //**********************************************************************************************
2498 
2499  public:
2500  //**Type definitions****************************************************************************
2502  typedef This ResultType;
2505  typedef Type ElementType;
2506  typedef const Type& ReturnType;
2507  typedef const This& CompositeType;
2509  typedef const Type& ConstReference;
2510  typedef Element* Iterator;
2511  typedef const Element* ConstIterator;
2512  //**********************************************************************************************
2513 
2514  //**Rebind struct definition********************************************************************
2517  template< typename ET > // Data type of the other matrix
2518  struct Rebind {
2520  };
2521  //**********************************************************************************************
2522 
2523  //**Compilation flags***************************************************************************
2525 
2528  enum { smpAssignable = !IsSMPAssignable<Type>::value };
2529  //**********************************************************************************************
2530 
2531  //**Constructors********************************************************************************
2534  explicit inline CompressedMatrix();
2535  explicit inline CompressedMatrix( size_t m, size_t n );
2536  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
2537  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
2538  inline CompressedMatrix( const CompressedMatrix& sm );
2539  template< typename MT, bool SO > inline CompressedMatrix( const DenseMatrix<MT,SO>& dm );
2540  template< typename MT, bool SO > inline CompressedMatrix( const SparseMatrix<MT,SO>& sm );
2542  //**********************************************************************************************
2543 
2544  //**Destructor**********************************************************************************
2547  inline ~CompressedMatrix();
2549  //**********************************************************************************************
2550 
2551  //**Data access functions***********************************************************************
2554  inline Reference operator()( size_t i, size_t j );
2555  inline ConstReference operator()( size_t i, size_t j ) const;
2556  inline Iterator begin ( size_t i );
2557  inline ConstIterator begin ( size_t i ) const;
2558  inline ConstIterator cbegin( size_t i ) const;
2559  inline Iterator end ( size_t i );
2560  inline ConstIterator end ( size_t i ) const;
2561  inline ConstIterator cend ( size_t i ) const;
2563  //**********************************************************************************************
2564 
2565  //**Assignment operators************************************************************************
2568  inline CompressedMatrix& operator= ( const CompressedMatrix& rhs );
2569  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO>& rhs );
2570  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO>& rhs );
2571  template< typename MT, bool SO > inline CompressedMatrix& operator+=( const Matrix<MT,SO>& rhs );
2572  template< typename MT, bool SO > inline CompressedMatrix& operator-=( const Matrix<MT,SO>& rhs );
2573  template< typename MT, bool SO > inline CompressedMatrix& operator*=( const Matrix<MT,SO>& rhs );
2574 
2575  template< typename Other >
2576  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
2577  operator*=( Other rhs );
2578 
2579  template< typename Other >
2580  inline typename EnableIf< IsNumeric<Other>, CompressedMatrix >::Type&
2581  operator/=( Other rhs );
2583  //**********************************************************************************************
2584 
2585  //**Utility functions***************************************************************************
2588  inline size_t rows() const;
2589  inline size_t columns() const;
2590  inline size_t capacity() const;
2591  inline size_t capacity( size_t j ) const;
2592  inline size_t nonZeros() const;
2593  inline size_t nonZeros( size_t j ) const;
2594  inline void reset();
2595  inline void reset( size_t j );
2596  inline void clear();
2597  inline Iterator set ( size_t i, size_t j, const Type& value );
2598  inline Iterator insert ( size_t i, size_t j, const Type& value );
2599  inline void erase ( size_t i, size_t j );
2600  inline Iterator erase ( size_t j, Iterator pos );
2601  inline Iterator erase ( size_t j, Iterator first, Iterator last );
2602  void resize ( size_t m, size_t n, bool preserve=true );
2603  inline void reserve( size_t nonzeros );
2604  void reserve( size_t j, size_t nonzeros );
2605  inline void trim ();
2606  inline void trim ( size_t j );
2607  inline CompressedMatrix& transpose();
2608  template< typename Other > inline CompressedMatrix& scale( const Other& scalar );
2609  template< typename Other > inline CompressedMatrix& scaleDiagonal( Other scalar );
2610  inline void swap( CompressedMatrix& sm ) /* throw() */;
2612  //**********************************************************************************************
2613 
2614  //**Lookup functions****************************************************************************
2617  inline Iterator find ( size_t i, size_t j );
2618  inline ConstIterator find ( size_t i, size_t j ) const;
2619  inline Iterator lowerBound( size_t i, size_t j );
2620  inline ConstIterator lowerBound( size_t i, size_t j ) const;
2621  inline Iterator upperBound( size_t i, size_t j );
2622  inline ConstIterator upperBound( size_t i, size_t j ) const;
2624  //**********************************************************************************************
2625 
2626  //**Low-level utility functions*****************************************************************
2629  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
2630  inline void finalize( size_t j );
2632  //**********************************************************************************************
2633 
2634  //**Expression template evaluation functions****************************************************
2637  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2638  template< typename Other > inline bool isAliased( const Other* alias ) const;
2639 
2640  inline bool canSMPAssign() const;
2641 
2642  template< typename MT, bool SO > inline void assign ( const DenseMatrix<MT,SO>& rhs );
2643  template< typename MT > inline void assign ( const SparseMatrix<MT,true>& rhs );
2644  template< typename MT > inline void assign ( const SparseMatrix<MT,false>& rhs );
2645  template< typename MT, bool SO > inline void addAssign( const DenseMatrix<MT,SO>& rhs );
2646  template< typename MT, bool SO > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
2647  template< typename MT, bool SO > inline void subAssign( const DenseMatrix<MT,SO>& rhs );
2648  template< typename MT, bool SO > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
2650  //**********************************************************************************************
2651 
2652  private:
2653  //**Utility functions***************************************************************************
2656  Iterator insert( Iterator pos, size_t i, size_t j, const Type& value );
2657  inline size_t extendCapacity() const;
2658  void reserveElements( size_t nonzeros );
2660  //**********************************************************************************************
2661 
2662  //**Member variables****************************************************************************
2665  size_t m_;
2666  size_t n_;
2667  size_t capacity_;
2668  Iterator* begin_;
2669  Iterator* end_;
2670 
2671  static const Type zero_;
2672 
2673  //**********************************************************************************************
2674 
2675  //**Compile time checks*************************************************************************
2681  BLAZE_CONSTRAINT_MUST_HAVE_SAME_SIZE ( ElementBase, Element );
2683  //**********************************************************************************************
2684 };
2686 //*************************************************************************************************
2687 
2688 
2689 
2690 
2691 //=================================================================================================
2692 //
2693 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
2694 //
2695 //=================================================================================================
2696 
2697 template< typename Type >
2698 const Type CompressedMatrix<Type,true>::zero_ = Type();
2699 
2700 
2701 
2702 
2703 //=================================================================================================
2704 //
2705 // CONSTRUCTORS
2706 //
2707 //=================================================================================================
2708 
2709 //*************************************************************************************************
2713 template< typename Type > // Data type of the sparse matrix
2715  : m_ ( 0UL ) // The current number of rows of the sparse matrix
2716  , n_ ( 0UL ) // The current number of columns of the sparse matrix
2717  , capacity_( 0UL ) // The current capacity of the pointer array
2718  , begin_( new Iterator[2UL] ) // Pointers to the first non-zero element of each column
2719  , end_ ( begin_+1UL ) // Pointers one past the last non-zero element of each column
2720 {
2721  begin_[0UL] = end_[0UL] = NULL;
2722 }
2724 //*************************************************************************************************
2725 
2726 
2727 //*************************************************************************************************
2736 template< typename Type > // Data type of the sparse matrix
2737 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n )
2738  : m_ ( m ) // The current number of rows of the sparse matrix
2739  , n_ ( n ) // The current number of columns of the sparse matrix
2740  , capacity_( n ) // The current capacity of the pointer array
2741  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
2742  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
2743 {
2744  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
2745  begin_[j] = NULL;
2746 }
2748 //*************************************************************************************************
2749 
2750 
2751 //*************************************************************************************************
2761 template< typename Type > // Data type of the sparse matrix
2762 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
2763  : m_ ( m ) // The current number of rows of the sparse matrix
2764  , n_ ( n ) // 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  begin_[0UL] = allocate<Element>( nonzeros );
2770  for( size_t j=1UL; j<(2UL*n_+1UL); ++j )
2771  begin_[j] = begin_[0UL];
2772  end_[n_] = begin_[0UL]+nonzeros;
2773 }
2775 //*************************************************************************************************
2776 
2777 
2778 //*************************************************************************************************
2789 template< typename Type > // Data type of the sparse matrix
2790 CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
2791  : m_ ( m ) // The current number of rows of the sparse matrix
2792  , n_ ( n ) // The current number of columns of the sparse matrix
2793  , capacity_( n ) // The current capacity of the pointer array
2794  , begin_( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2795  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2796 {
2797  BLAZE_USER_ASSERT( nonzeros.size() == n, "Size of capacity vector and number of columns don't match" );
2798 
2799  size_t newCapacity( 0UL );
2800  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
2801  newCapacity += *it;
2802 
2803  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
2804  for( size_t j=0UL; j<n_; ++j ) {
2805  begin_[j+1UL] = end_[j+1UL] = begin_[j] + nonzeros[j];
2806  }
2807 }
2809 //*************************************************************************************************
2810 
2811 
2812 //*************************************************************************************************
2818 template< typename Type > // Data type of the sparse matrix
2819 inline CompressedMatrix<Type,true>::CompressedMatrix( const CompressedMatrix& sm )
2820  : m_ ( sm.m_ ) // The current number of rows of the sparse matrix
2821  , n_ ( sm.n_ ) // The current number of columns of the sparse matrix
2822  , capacity_( sm.n_ ) // The current capacity of the pointer array
2823  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2824  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2825 {
2826  const size_t nonzeros( sm.nonZeros() );
2827 
2828  begin_[0UL] = allocate<Element>( nonzeros );
2829  for( size_t j=0UL; j<n_; ++j )
2830  begin_[j+1UL] = end_[j] = std::copy( sm.begin(j), sm.end(j), begin_[j] );
2831  end_[n_] = begin_[0UL]+nonzeros;
2832 }
2834 //*************************************************************************************************
2835 
2836 
2837 //*************************************************************************************************
2843 template< typename Type > // Data type of the sparse matrix
2844 template< typename MT // Type of the foreign dense matrix
2845  , bool SO > // Storage order of the foreign dense matrix
2846 inline CompressedMatrix<Type,true>::CompressedMatrix( const DenseMatrix<MT,SO>& dm )
2847  : m_ ( (~dm).rows() ) // The current number of rows of the sparse matrix
2848  , n_ ( (~dm).columns() ) // The current number of columns of the sparse matrix
2849  , capacity_( n_ ) // The current capacity of the pointer array
2850  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2851  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2852 {
2853  using blaze::assign;
2854 
2855  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
2856  begin_[j] = NULL;
2857 
2858  assign( *this, ~dm );
2859 }
2861 //*************************************************************************************************
2862 
2863 
2864 //*************************************************************************************************
2870 template< typename Type > // Data type of the sparse matrix
2871 template< typename MT // Type of the foreign sparse matrix
2872  , bool SO > // Storage order of the foreign sparse matrix
2873 inline CompressedMatrix<Type,true>::CompressedMatrix( const SparseMatrix<MT,SO>& sm )
2874  : m_ ( (~sm).rows() ) // The current number of rows of the sparse matrix
2875  , n_ ( (~sm).columns() ) // The current number of columns of the sparse matrix
2876  , capacity_( n_ ) // The current capacity of the pointer array
2877  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
2878  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
2879 {
2880  using blaze::assign;
2881 
2882  const size_t nonzeros( (~sm).nonZeros() );
2883 
2884  begin_[0UL] = allocate<Element>( nonzeros );
2885  for( size_t j=0UL; j<n_; ++j )
2886  begin_[j+1UL] = end_[j] = begin_[0UL];
2887  end_[n_] = begin_[0UL]+nonzeros;
2888 
2889  assign( *this, ~sm );
2890 }
2892 //*************************************************************************************************
2893 
2894 
2895 
2896 
2897 //=================================================================================================
2898 //
2899 // DESTRUCTOR
2900 //
2901 //=================================================================================================
2902 
2903 //*************************************************************************************************
2907 template< typename Type > // Data type of the sparse matrix
2908 inline CompressedMatrix<Type,true>::~CompressedMatrix()
2909 {
2910  deallocate( begin_[0UL] );
2911  delete [] begin_;
2912 }
2914 //*************************************************************************************************
2915 
2916 
2917 
2918 
2919 //=================================================================================================
2920 //
2921 // DATA ACCESS FUNCTIONS
2922 //
2923 //=================================================================================================
2924 
2925 //*************************************************************************************************
2933 template< typename Type > // Data type of the sparse matrix
2935  CompressedMatrix<Type,true>::operator()( size_t i, size_t j )
2936 {
2937  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2938  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2939 
2940  return Reference( *this, i, j );
2941 }
2943 //*************************************************************************************************
2944 
2945 
2946 //*************************************************************************************************
2954 template< typename Type > // Data type of the sparse matrix
2956  CompressedMatrix<Type,true>::operator()( size_t i, size_t j ) const
2957 {
2958  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2959  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2960 
2961  const ConstIterator pos( lowerBound( i, j ) );
2962 
2963  if( pos == end_[j] || pos->index_ != i )
2964  return zero_;
2965  else
2966  return pos->value_;
2967 }
2969 //*************************************************************************************************
2970 
2971 
2972 //*************************************************************************************************
2979 template< typename Type > // Data type of the sparse matrix
2981  CompressedMatrix<Type,true>::begin( size_t j )
2982 {
2983  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
2984  return begin_[j];
2985 }
2987 //*************************************************************************************************
2988 
2989 
2990 //*************************************************************************************************
2997 template< typename Type > // Data type of the sparse matrix
2999  CompressedMatrix<Type,true>::begin( size_t j ) const
3000 {
3001  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
3002  return begin_[j];
3003 }
3005 //*************************************************************************************************
3006 
3007 
3008 //*************************************************************************************************
3015 template< typename Type > // Data type of the sparse matrix
3017  CompressedMatrix<Type,true>::cbegin( size_t j ) const
3018 {
3019  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
3020  return begin_[j];
3021 }
3023 //*************************************************************************************************
3024 
3025 
3026 //*************************************************************************************************
3033 template< typename Type > // Data type of the sparse matrix
3035  CompressedMatrix<Type,true>::end( size_t j )
3036 {
3037  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
3038  return end_[j];
3039 }
3041 //*************************************************************************************************
3042 
3043 
3044 //*************************************************************************************************
3051 template< typename Type > // Data type of the sparse matrix
3053  CompressedMatrix<Type,true>::end( size_t j ) const
3054 {
3055  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
3056  return end_[j];
3057 }
3059 //*************************************************************************************************
3060 
3061 
3062 //*************************************************************************************************
3069 template< typename Type > // Data type of the sparse matrix
3071  CompressedMatrix<Type,true>::cend( size_t j ) const
3072 {
3073  BLAZE_USER_ASSERT( j < n_, "Invalid sparse matrix column access index" );
3074  return end_[j];
3075 }
3077 //*************************************************************************************************
3078 
3079 
3080 
3081 
3082 //=================================================================================================
3083 //
3084 // ASSIGNMENT OPERATORS
3085 //
3086 //=================================================================================================
3087 
3088 //*************************************************************************************************
3098 template< typename Type > // Data type of the sparse matrix
3099 inline CompressedMatrix<Type,true>&
3100  CompressedMatrix<Type,true>::operator=( const CompressedMatrix& rhs )
3101 {
3102  if( &rhs == this ) return *this;
3103 
3104  const size_t nonzeros( rhs.nonZeros() );
3105 
3106  if( rhs.n_ > capacity_ || nonzeros > capacity() )
3107  {
3108  Iterator* newBegin( new Iterator[2UL*rhs.n_+2UL] );
3109  Iterator* newEnd ( newBegin+(rhs.n_+1UL) );
3110 
3111  newBegin[0UL] = allocate<Element>( nonzeros );
3112  for( size_t j=0UL; j<rhs.n_; ++j ) {
3113  newBegin[j+1UL] = newEnd[j] = std::copy( rhs.begin_[j], rhs.end_[j], newBegin[j] );
3114  }
3115  newEnd[rhs.n_] = newBegin[0UL]+nonzeros;
3116 
3117  std::swap( begin_, newBegin );
3118  end_ = newEnd;
3119  deallocate( newBegin[0UL] );
3120  delete [] newBegin;
3121  capacity_ = rhs.n_;
3122  }
3123  else {
3124  for( size_t j=0UL; j<rhs.n_; ++j ) {
3125  begin_[j+1UL] = end_[j] = std::copy( rhs.begin_[j], rhs.end_[j], begin_[j] );
3126  }
3127  }
3128 
3129  m_ = rhs.m_;
3130  n_ = rhs.n_;
3131 
3132  return *this;
3133 }
3135 //*************************************************************************************************
3136 
3137 
3138 //*************************************************************************************************
3148 template< typename Type > // Data type of the sparse matrix
3149 template< typename MT // Type of the right-hand side dense matrix
3150  , bool SO > // Storage order of the right-hand side dense matrix
3151 inline CompressedMatrix<Type,true>&
3152  CompressedMatrix<Type,true>::operator=( const DenseMatrix<MT,SO>& rhs )
3153 {
3154  using blaze::assign;
3155 
3156  if( (~rhs).canAlias( this ) ) {
3157  CompressedMatrix tmp( ~rhs );
3158  swap( tmp );
3159  }
3160  else {
3161  resize( (~rhs).rows(), (~rhs).columns(), false );
3162  assign( *this, ~rhs );
3163  }
3164 
3165  return *this;
3166 }
3168 //*************************************************************************************************
3169 
3170 
3171 //*************************************************************************************************
3181 template< typename Type > // Data type of the sparse matrix
3182 template< typename MT // Type of the right-hand side sparse matrix
3183  , bool SO > // Storage order of the right-hand side sparse matrix
3184 inline CompressedMatrix<Type,true>&
3185  CompressedMatrix<Type,true>::operator=( const SparseMatrix<MT,SO>& rhs )
3186 {
3187  using blaze::assign;
3188 
3189  if( (~rhs).canAlias( this ) ||
3190  (~rhs).columns() > capacity_ ||
3191  (~rhs).nonZeros() > capacity() ) {
3192  CompressedMatrix tmp( ~rhs );
3193  swap( tmp );
3194  }
3195  else {
3196  resize( (~rhs).rows(), (~rhs).columns(), false );
3197  reset();
3198  assign( *this, ~rhs );
3199  }
3200 
3201  return *this;
3202 }
3204 //*************************************************************************************************
3205 
3206 
3207 //*************************************************************************************************
3218 template< typename Type > // Data type of the sparse matrix
3219 template< typename MT // Type of the right-hand side matrix
3220  , bool SO > // Storage order of the right-hand side matrix
3221 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator+=( const Matrix<MT,SO>& rhs )
3222 {
3223  using blaze::addAssign;
3224 
3225  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
3226  throw std::invalid_argument( "Matrix sizes do not match" );
3227 
3228  addAssign( *this, ~rhs );
3229  return *this;
3230 }
3232 //*************************************************************************************************
3233 
3234 
3235 //*************************************************************************************************
3246 template< typename Type > // Data type of the sparse matrix
3247 template< typename MT // Type of the right-hand side matrix
3248  , bool SO > // Storage order of the right-hand side matrix
3249 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator-=( const Matrix<MT,SO>& rhs )
3250 {
3251  using blaze::subAssign;
3252 
3253  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
3254  throw std::invalid_argument( "Matrix sizes do not match" );
3255 
3256  subAssign( *this, ~rhs );
3257  return *this;
3258 }
3260 //*************************************************************************************************
3261 
3262 
3263 //*************************************************************************************************
3274 template< typename Type > // Data type of the sparse matrix
3275 template< typename MT // Type of the right-hand side matrix
3276  , bool SO > // Storage order of the right-hand side matrix
3277 inline CompressedMatrix<Type,true>&
3278  CompressedMatrix<Type,true>::operator*=( const Matrix<MT,SO>& rhs )
3279 {
3280  if( (~rhs).rows() != n_ )
3281  throw std::invalid_argument( "Matrix sizes do not match" );
3282 
3283  CompressedMatrix tmp( *this * (~rhs) );
3284  swap( tmp );
3285 
3286  return *this;
3287 }
3289 //*************************************************************************************************
3290 
3291 
3292 //*************************************************************************************************
3300 template< typename Type > // Data type of the sparse matrix
3301 template< typename Other > // Data type of the right-hand side scalar
3302 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,true> >::Type&
3303  CompressedMatrix<Type,true>::operator*=( Other rhs )
3304 {
3305  for( size_t j=0UL; j<n_; ++j ) {
3306  const Iterator last( end(j) );
3307  for( Iterator element=begin(j); element!=last; ++element )
3308  element->value_ *= rhs;
3309  }
3310  return *this;
3311 }
3313 //*************************************************************************************************
3314 
3315 
3316 //*************************************************************************************************
3324 template< typename Type > // Data type of the sparse matrix
3325 template< typename Other > // Data type of the right-hand side scalar
3326 inline typename EnableIf< IsNumeric<Other>, CompressedMatrix<Type,true> >::Type&
3327  CompressedMatrix<Type,true>::operator/=( Other rhs )
3328 {
3329  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3330 
3331  typedef typename DivTrait<Type,Other>::Type DT;
3332  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
3333 
3334  // Depending on the two involved data types, an integer division is applied or a
3335  // floating point division is selected.
3336  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
3337  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
3338  for( size_t j=0UL; j<n_; ++j ) {
3339  const Iterator last( end(j) );
3340  for( Iterator element=begin(j); element!=last; ++element )
3341  element->value_ *= tmp;
3342  }
3343  }
3344  else {
3345  for( size_t j=0UL; j<n_; ++j ) {
3346  const Iterator last( end(j) );
3347  for( Iterator element=begin(j); element!=last; ++element )
3348  element->value_ /= rhs;
3349  }
3350  }
3351 
3352  return *this;
3353 }
3355 //*************************************************************************************************
3356 
3357 
3358 
3359 
3360 //=================================================================================================
3361 //
3362 // UTILITY FUNCTIONS
3363 //
3364 //=================================================================================================
3365 
3366 //*************************************************************************************************
3372 template< typename Type > // Data type of the sparse matrix
3373 inline size_t CompressedMatrix<Type,true>::rows() const
3374 {
3375  return m_;
3376 }
3378 //*************************************************************************************************
3379 
3380 
3381 //*************************************************************************************************
3387 template< typename Type > // Data type of the sparse matrix
3388 inline size_t CompressedMatrix<Type,true>::columns() const
3389 {
3390  return n_;
3391 }
3393 //*************************************************************************************************
3394 
3395 
3396 //*************************************************************************************************
3402 template< typename Type > // Data type of the sparse matrix
3403 inline size_t CompressedMatrix<Type,true>::capacity() const
3404 {
3405  return end_[n_] - begin_[0UL];
3406 }
3408 //*************************************************************************************************
3409 
3410 
3411 //*************************************************************************************************
3418 template< typename Type > // Data type of the sparse matrix
3419 inline size_t CompressedMatrix<Type,true>::capacity( size_t j ) const
3420 {
3421  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3422  return begin_[j+1UL] - begin_[j];
3423 }
3425 //*************************************************************************************************
3426 
3427 
3428 //*************************************************************************************************
3434 template< typename Type > // Data type of the sparse matrix
3435 inline size_t CompressedMatrix<Type,true>::nonZeros() const
3436 {
3437  size_t nonzeros( 0UL );
3438 
3439  for( size_t j=0UL; j<n_; ++j )
3440  nonzeros += nonZeros( j );
3441 
3442  return nonzeros;
3443 }
3445 //*************************************************************************************************
3446 
3447 
3448 //*************************************************************************************************
3455 template< typename Type > // Data type of the sparse matrix
3456 inline size_t CompressedMatrix<Type,true>::nonZeros( size_t j ) const
3457 {
3458  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3459  return end_[j] - begin_[j];
3460 }
3462 //*************************************************************************************************
3463 
3464 
3465 //*************************************************************************************************
3471 template< typename Type > // Data type of the sparse matrix
3473 {
3474  for( size_t j=0UL; j<n_; ++j )
3475  end_[j] = begin_[j];
3476 }
3478 //*************************************************************************************************
3479 
3480 
3481 //*************************************************************************************************
3491 template< typename Type > // Data type of the sparse matrix
3492 inline void CompressedMatrix<Type,true>::reset( size_t j )
3493 {
3494  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3495  end_[j] = begin_[j];
3496 }
3498 //*************************************************************************************************
3499 
3500 
3501 //*************************************************************************************************
3509 template< typename Type > // Data type of the sparse matrix
3511 {
3512  end_[0UL] = end_[n_];
3513  m_ = 0UL;
3514  n_ = 0UL;
3515 }
3517 //*************************************************************************************************
3518 
3519 
3520 //*************************************************************************************************
3533 template< typename Type > // Data type of the sparse matrix
3535  CompressedMatrix<Type,true>::set( size_t i, size_t j, const Type& value )
3536 {
3537  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3538  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3539 
3540  const Iterator pos( lowerBound( i, j ) );
3541 
3542  if( pos != end_[j] && pos->index_ == i ) {
3543  pos->value() = value;
3544  return pos;
3545  }
3546  else return insert( pos, i, j, value );
3547 }
3549 //*************************************************************************************************
3550 
3551 
3552 //*************************************************************************************************
3566 template< typename Type > // Data type of the sparse matrix
3568  CompressedMatrix<Type,true>::insert( size_t i, size_t j, const Type& value )
3569 {
3570  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3571  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3572 
3573  const Iterator pos( lowerBound( i, j ) );
3574 
3575  if( pos != end_[j] && pos->index_ == i )
3576  throw std::invalid_argument( "Bad access index" );
3577 
3578  return insert( pos, i, j, value );
3579 }
3581 //*************************************************************************************************
3582 
3583 
3584 //*************************************************************************************************
3595 template< typename Type > // Data type of the sparse matrix
3597  CompressedMatrix<Type,true>::insert( Iterator pos, size_t i, size_t j, const Type& value )
3598 {
3599  if( begin_[j+1UL] - end_[j] != 0 ) {
3600  std::copy_backward( pos, end_[j], end_[j]+1 );
3601  pos->value_ = value;
3602  pos->index_ = i;
3603  ++end_[j];
3604 
3605  return pos;
3606  }
3607  else if( end_[n_] - begin_[n_] != 0 ) {
3608  std::copy_backward( pos, end_[n_-1UL], end_[n_-1]+1 );
3609 
3610  pos->value_ = value;
3611  pos->index_ = i;
3612 
3613  for( size_t k=j+1UL; k<n_+1UL; ++k ) {
3614  ++begin_[k];
3615  ++end_[k-1UL];
3616  }
3617 
3618  return pos;
3619  }
3620  else {
3621  size_t newCapacity( extendCapacity() );
3622 
3623  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
3624  Iterator* newEnd = newBegin+capacity_+1UL;
3625 
3626  newBegin[0UL] = allocate<Element>( newCapacity );
3627 
3628  for( size_t k=0UL; k<j; ++k ) {
3629  const size_t nonzeros( end_[k] - begin_[k] );
3630  const size_t total( begin_[k+1UL] - begin_[k] );
3631  newEnd [k] = newBegin[k] + nonzeros;
3632  newBegin[k+1UL] = newBegin[k] + total;
3633  }
3634  newEnd [j] = newBegin[j] + ( end_[j] - begin_[j] ) + 1;
3635  newBegin[j+1UL] = newBegin[j] + ( begin_[j+1UL] - begin_[j] ) + 1;
3636  for( size_t k=j+1UL; k<n_; ++k ) {
3637  const size_t nonzeros( end_[k] - begin_[k] );
3638  const size_t total( begin_[k+1UL] - begin_[k] );
3639  newEnd [k] = newBegin[k] + nonzeros;
3640  newBegin[k+1UL] = newBegin[k] + total;
3641  }
3642 
3643  newEnd[n_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
3644 
3645  Iterator tmp = std::copy( begin_[0UL], pos, newBegin[0UL] );
3646  tmp->value_ = value;
3647  tmp->index_ = i;
3648  std::copy( pos, end_[n_-1UL], tmp+1UL );
3649 
3650  std::swap( newBegin, begin_ );
3651  end_ = newEnd;
3652  deallocate( newBegin[0UL] );
3653  delete [] newBegin;
3654 
3655  return tmp;
3656  }
3657 }
3659 //*************************************************************************************************
3660 
3661 
3662 //*************************************************************************************************
3672 template< typename Type > // Data type of the sparse matrix
3673 inline void CompressedMatrix<Type,true>::erase( size_t i, size_t j )
3674 {
3675  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3676  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3677 
3678  const Iterator pos( find( i, j ) );
3679  if( pos != end_[j] )
3680  end_[j] = std::copy( pos+1, end_[j], pos );
3681 }
3683 //*************************************************************************************************
3684 
3685 
3686 //*************************************************************************************************
3696 template< typename Type > // Data type of the sparse matrix
3698  CompressedMatrix<Type,true>::erase( size_t j, Iterator pos )
3699 {
3700  BLAZE_USER_ASSERT( j < columns() , "Invalid row access index" );
3701  BLAZE_USER_ASSERT( pos >= begin_[j] && pos <= end_[j], "Invalid compressed matrix iterator" );
3702 
3703  if( pos != end_[j] )
3704  end_[j] = std::copy( pos+1, end_[j], pos );
3705 
3706  return pos;
3707 }
3709 //*************************************************************************************************
3710 
3711 
3712 //*************************************************************************************************
3723 template< typename Type > // Data type of the sparse matrix
3725  CompressedMatrix<Type,true>::erase( size_t j, Iterator first, Iterator last )
3726 {
3727  BLAZE_USER_ASSERT( j < columns(), "Invalid row access index" );
3728  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
3729  BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j], "Invalid compressed matrix iterator" );
3730  BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j], "Invalid compressed matrix iterator" );
3731 
3732  if( first != last )
3733  end_[j] = std::copy( last, end_[j], first );
3734 
3735  return first;
3736 }
3738 //*************************************************************************************************
3739 
3740 
3741 //*************************************************************************************************
3757 template< typename Type > // Data type of the sparse matrix
3758 void CompressedMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
3759 {
3760  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
3761  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
3762 
3763  if( m == m_ && n == n_ ) return;
3764 
3765  if( n > capacity_ )
3766  {
3767  Iterator* newBegin( new Iterator[2UL*n+2UL] );
3768  Iterator* newEnd ( newBegin+n+1UL );
3769 
3770  newBegin[0UL] = begin_[0UL];
3771 
3772  if( preserve ) {
3773  for( size_t j=0UL; j<n_; ++j ) {
3774  newEnd [j] = end_ [j];
3775  newBegin[j+1UL] = begin_[j+1UL];
3776  }
3777  for( size_t j=n_; j<n; ++j ) {
3778  newBegin[j+1UL] = newEnd[j] = begin_[n_];
3779  }
3780  }
3781  else {
3782  for( size_t j=0UL; j<n; ++j ) {
3783  newBegin[j+1UL] = newEnd[j] = begin_[0UL];
3784  }
3785  }
3786 
3787  newEnd[n] = end_[n_];
3788 
3789  std::swap( newBegin, begin_ );
3790  delete [] newBegin;
3791 
3792  end_ = newEnd;
3793  capacity_ = n;
3794  }
3795  else if( n > n_ )
3796  {
3797  end_[n] = end_[n_];
3798 
3799  if( !preserve ) {
3800  for( size_t j=0UL; j<n_; ++j )
3801  end_[j] = begin_[j];
3802  }
3803 
3804  for( size_t j=n_; j<n; ++j )
3805  begin_[j+1UL] = end_[j] = begin_[n_];
3806  }
3807  else
3808  {
3809  if( preserve ) {
3810  for( size_t j=0UL; j<n; ++j )
3811  end_[j] = lowerBound( m, j );
3812  }
3813  else {
3814  for( size_t j=0UL; j<n; ++j )
3815  end_[j] = begin_[j];
3816  }
3817 
3818  end_[n] = end_[n_];
3819  }
3820 
3821  m_ = m;
3822  n_ = n;
3823 
3824  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
3825  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
3826 }
3828 //*************************************************************************************************
3829 
3830 
3831 //*************************************************************************************************
3842 template< typename Type > // Data type of the sparse matrix
3843 inline void CompressedMatrix<Type,true>::reserve( size_t nonzeros )
3844 {
3845  if( nonzeros > capacity() )
3846  reserveElements( nonzeros );
3847 }
3849 //*************************************************************************************************
3850 
3851 
3852 //*************************************************************************************************
3864 template< typename Type > // Data type of the sparse matrix
3865 void CompressedMatrix<Type,true>::reserve( size_t j, size_t nonzeros )
3866 {
3867  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3868 
3869  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
3870  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
3871 
3872  const size_t current( capacity(j) );
3873 
3874  if( current >= nonzeros ) return;
3875 
3876  const ptrdiff_t additional( nonzeros - current );
3877 
3878  if( end_[n_] - begin_[n_] < additional )
3879  {
3880  const size_t newCapacity( begin_[n_] - begin_[0UL] + additional );
3881  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
3882 
3883  Iterator* newBegin( new Iterator[2UL*n_+2UL] );
3884  Iterator* newEnd ( newBegin+n_+1UL );
3885 
3886  newBegin[0UL] = allocate<Element>( newCapacity );
3887  newEnd [n_ ] = newBegin[0UL]+newCapacity;
3888 
3889  for( size_t k=0UL; k<j; ++k ) {
3890  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
3891  newBegin[k+1UL] = newBegin[k] + capacity(k);
3892  }
3893  newEnd [j ] = std::copy( begin_[j], end_[j], newBegin[j] );
3894  newBegin[j+1UL] = newBegin[j] + nonzeros;
3895  for( size_t k=j+1UL; k<n_; ++k ) {
3896  newEnd [k ] = std::copy( begin_[k], end_[k], newBegin[k] );
3897  newBegin[k+1UL] = newBegin[k] + capacity(k);
3898  }
3899 
3900  BLAZE_INTERNAL_ASSERT( newBegin[n_] == newEnd[n_], "Invalid pointer calculations" );
3901 
3902  std::swap( newBegin, begin_ );
3903  deallocate( newBegin[0UL] );
3904  delete [] newBegin;
3905  end_ = newEnd;
3906  capacity_ = n_;
3907  }
3908  else
3909  {
3910  begin_[n_] += additional;
3911  for( size_t k=n_-1UL; k>j; --k ) {
3912  begin_[k] = std::copy_backward( begin_[k], end_[k], end_[k]+additional );
3913  end_ [k] += additional;
3914  }
3915  }
3916 
3917  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
3918  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
3919 }
3921 //*************************************************************************************************
3922 
3923 
3924 //*************************************************************************************************
3934 template< typename Type > // Data type of the sparse matrix
3935 void CompressedMatrix<Type,true>::trim()
3936 {
3937  for( size_t j=0UL; j<n_; ++j )
3938  trim( j );
3939 }
3941 //*************************************************************************************************
3942 
3943 
3944 //*************************************************************************************************
3955 template< typename Type > // Data type of the sparse matrix
3956 void CompressedMatrix<Type,true>::trim( size_t j )
3957 {
3958  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3959 
3960  if( j < ( n_ - 1UL ) )
3961  end_[j+1] = std::copy( begin_[j+1], end_[j+1], end_[j] );
3962  begin_[j+1] = end_[j];
3963 }
3965 //*************************************************************************************************
3966 
3967 
3968 //*************************************************************************************************
3974 template< typename Type > // Data type of the sparse matrix
3975 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::transpose()
3976 {
3977  CompressedMatrix tmp( trans( *this ) );
3978  swap( tmp );
3979  return *this;
3980 }
3982 //*************************************************************************************************
3983 
3984 
3985 //*************************************************************************************************
3992 template< typename Type > // Data type of the sparse matrix
3993 template< typename Other > // Data type of the scalar value
3994 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scale( const Other& scalar )
3995 {
3996  for( size_t j=0UL; j<n_; ++j )
3997  for( Iterator element=begin_[j]; element!=end_[j]; ++element )
3998  element->value_ *= scalar;
3999 
4000  return *this;
4001 }
4003 //*************************************************************************************************
4004 
4005 
4006 //*************************************************************************************************
4013 template< typename Type > // Data type of the sparse matrix
4014 template< typename Other > // Data type of the scalar value
4015 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scaleDiagonal( Other scalar )
4016 {
4017  const size_t size( blaze::min( m_, n_ ) );
4018 
4019  for( size_t j=0UL; j<size; ++j ) {
4020  Iterator pos = lowerBound( j, j );
4021  if( pos != end_[j] && pos->index_ == j )
4022  pos->value_ *= scalar;
4023  }
4024 
4025  return *this;
4026 }
4028 //*************************************************************************************************
4029 
4030 
4031 //*************************************************************************************************
4039 template< typename Type > // Data type of the sparse matrix
4040 inline void CompressedMatrix<Type,true>::swap( CompressedMatrix& sm ) /* throw() */
4041 {
4042  std::swap( m_, sm.m_ );
4043  std::swap( n_, sm.n_ );
4044  std::swap( capacity_, sm.capacity_ );
4045  std::swap( begin_, sm.begin_ );
4046  std::swap( end_ , sm.end_ );
4047 }
4049 //*************************************************************************************************
4050 
4051 
4052 //*************************************************************************************************
4061 template< typename Type > // Data type of the sparse matrix
4062 inline size_t CompressedMatrix<Type,true>::extendCapacity() const
4063 {
4064  size_t nonzeros( 2UL*capacity()+1UL );
4065  nonzeros = blaze::max( nonzeros, 7UL );
4066 
4067  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
4068 
4069  return nonzeros;
4070 }
4072 //*************************************************************************************************
4073 
4074 
4075 //*************************************************************************************************
4082 template< typename Type > // Data type of the sparse matrix
4083 void CompressedMatrix<Type,true>::reserveElements( size_t nonzeros )
4084 {
4085  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
4086  Iterator* newEnd = newBegin+capacity_+1UL;
4087 
4088  newBegin[0UL] = allocate<Element>( nonzeros );
4089 
4090  for( size_t k=0UL; k<n_; ++k ) {
4091  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid column pointers" );
4092  newEnd [k] = std::copy( begin_[k], end_[k], newBegin[k] );
4093  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
4094  }
4095 
4096  newEnd[n_] = newBegin[0UL]+nonzeros;
4097 
4098  std::swap( newBegin, begin_ );
4099  deallocate( newBegin[0UL] );
4100  delete [] newBegin;
4101  end_ = newEnd;
4102 }
4104 //*************************************************************************************************
4105 
4106 
4107 
4108 
4109 //=================================================================================================
4110 //
4111 // LOOKUP FUNCTIONS
4112 //
4113 //=================================================================================================
4114 
4115 //*************************************************************************************************
4130 template< typename Type > // Data type of the sparse matrix
4132  CompressedMatrix<Type,true>::find( size_t i, size_t j )
4133 {
4134  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
4135 }
4137 //*************************************************************************************************
4138 
4139 
4140 //*************************************************************************************************
4155 template< typename Type > // Data type of the sparse matrix
4157  CompressedMatrix<Type,true>::find( size_t i, size_t j ) const
4158 {
4159  const ConstIterator pos( lowerBound( i, j ) );
4160  if( pos != end_[j] && pos->index_ == i )
4161  return pos;
4162  else return end_[j];
4163 }
4165 //*************************************************************************************************
4166 
4167 
4168 //*************************************************************************************************
4182 template< typename Type > // Data type of the sparse matrix
4184  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j )
4185 {
4186  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
4187 }
4189 //*************************************************************************************************
4190 
4191 
4192 //*************************************************************************************************
4206 template< typename Type > // Data type of the sparse matrix
4208  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j ) const
4209 {
4210  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4211  return std::lower_bound( begin_[j], end_[j], i, FindIndex() );
4212 }
4214 //*************************************************************************************************
4215 
4216 
4217 //*************************************************************************************************
4231 template< typename Type > // Data type of the sparse matrix
4233  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j )
4234 {
4235  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
4236 }
4238 //*************************************************************************************************
4239 
4240 
4241 //*************************************************************************************************
4255 template< typename Type > // Data type of the sparse matrix
4257  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j ) const
4258 {
4259  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4260  return std::upper_bound( begin_[j], end_[j], i, FindIndex() );
4261 }
4263 //*************************************************************************************************
4264 
4265 
4266 
4267 
4268 //=================================================================================================
4269 //
4270 // LOW-LEVEL UTILITY FUNCTIONS
4271 //
4272 //=================================================================================================
4273 
4274 //*************************************************************************************************
4316 template< typename Type > // Data type of the sparse matrix
4317 inline void CompressedMatrix<Type,true>::append( size_t i, size_t j, const Type& value, bool check )
4318 {
4319  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
4320  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
4321  BLAZE_USER_ASSERT( end_[j] < end_[n_], "Not enough reserved capacity left" );
4322  BLAZE_USER_ASSERT( begin_[j] == end_[j] || i > ( end_[j]-1UL )->index_, "Index is not strictly increasing" );
4323 
4324  end_[j]->value_ = value;
4325 
4326  if( !check || !isDefault( end_[j]->value_ ) ) {
4327  end_[j]->index_ = i;
4328  ++end_[j];
4329  }
4330 }
4332 //*************************************************************************************************
4333 
4334 
4335 //*************************************************************************************************
4349 template< typename Type > // Data type of the sparse matrix
4350 inline void CompressedMatrix<Type,true>::finalize( size_t j )
4351 {
4352  BLAZE_USER_ASSERT( j < n_, "Invalid row access index" );
4353 
4354  begin_[j+1UL] = end_[j];
4355  if( j != n_-1UL )
4356  end_[j+1UL] = end_[j];
4357 }
4359 //*************************************************************************************************
4360 
4361 
4362 
4363 
4364 //=================================================================================================
4365 //
4366 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4367 //
4368 //=================================================================================================
4369 
4370 //*************************************************************************************************
4381 template< typename Type > // Data type of the sparse matrix
4382 template< typename Other > // Data type of the foreign expression
4383 inline bool CompressedMatrix<Type,true>::canAlias( const Other* alias ) const
4384 {
4385  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4386 }
4388 //*************************************************************************************************
4389 
4390 
4391 //*************************************************************************************************
4402 template< typename Type > // Data type of the sparse matrix
4403 template< typename Other > // Data type of the foreign expression
4404 inline bool CompressedMatrix<Type,true>::isAliased( const Other* alias ) const
4405 {
4406  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4407 }
4409 //*************************************************************************************************
4410 
4411 
4412 //*************************************************************************************************
4423 template< typename Type > // Data type of the sparse matrix
4424 inline bool CompressedMatrix<Type,true>::canSMPAssign() const
4425 {
4426  return false;
4427 }
4429 //*************************************************************************************************
4430 
4431 
4432 //*************************************************************************************************
4444 template< typename Type > // Data type of the sparse matrix
4445 template< typename MT // Type of the right-hand side dense matrix
4446  , bool SO > // Storage order of the right-hand side dense matrix
4447 inline void CompressedMatrix<Type,true>::assign( const DenseMatrix<MT,SO>& rhs )
4448 {
4449  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4450  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4451 
4452  size_t nonzeros( 0UL );
4453 
4454  for( size_t j=1UL; j<=n_; ++j )
4455  begin_[j] = end_[j] = end_[n_];
4456 
4457  for( size_t j=0UL; j<n_; ++j )
4458  {
4459  begin_[j] = end_[j] = begin_[0UL]+nonzeros;
4460 
4461  const size_t ibegin( ( IsLower<MT>::value )
4462  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
4463  :( 0UL ) );
4464  const size_t iend ( ( IsUpper<MT>::value )
4465  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
4466  :( m_ ) );
4467 
4468  for( size_t i=ibegin; i<iend; ++i )
4469  {
4470  if( nonzeros == capacity() ) {
4471  reserveElements( extendCapacity() );
4472  for( size_t k=j+1UL; k<=n_; ++k )
4473  begin_[k] = end_[k] = end_[n_];
4474  }
4475 
4476  end_[j]->value_ = (~rhs)(i,j);
4477 
4478  if( !isDefault( end_[j]->value_ ) ) {
4479  end_[j]->index_ = i;
4480  ++end_[j];
4481  ++nonzeros;
4482  }
4483  }
4484  }
4485 
4486  begin_[n_] = begin_[0UL]+nonzeros;
4487 }
4489 //*************************************************************************************************
4490 
4491 
4492 //*************************************************************************************************
4504 template< typename Type > // Data type of the sparse matrix
4505 template< typename MT > // Type of the right-hand side sparse matrix
4506 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,true>& rhs )
4507 {
4508  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4509  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4510  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4511  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
4512 
4513  if( n_ == 0UL || begin_[0] == NULL )
4514  return;
4515 
4516  for( size_t j=0UL; j<n_; ++j ) {
4517  begin_[j+1UL] = end_[j] = std::copy( (~rhs).begin(j), (~rhs).end(j), begin_[j] );
4518  }
4519 }
4521 //*************************************************************************************************
4522 
4523 
4524 //*************************************************************************************************
4536 template< typename Type > // Data type of the sparse matrix
4537 template< typename MT > // Type of the right-hand side sparse matrix
4538 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,false>& rhs )
4539 {
4541 
4542  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4543  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4544  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4545  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
4546 
4547  typedef typename MT::ConstIterator RhsIterator;
4548 
4549  // Counting the number of elements per column
4550  std::vector<size_t> columnLengths( n_, 0UL );
4551  for( size_t i=0UL; i<m_; ++i ) {
4552  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4553  ++columnLengths[element->index()];
4554  }
4555 
4556  // Resizing the sparse matrix
4557  for( size_t j=0UL; j<n_; ++j ) {
4558  begin_[j+1UL] = end_[j+1UL] = begin_[j] + columnLengths[j];
4559  }
4560 
4561  // Appending the elements to the columns of the sparse matrix
4562  for( size_t i=0UL; i<m_; ++i ) {
4563  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4564  append( i, element->index(), element->value() );
4565  }
4566 }
4568 //*************************************************************************************************
4569 
4570 
4571 //*************************************************************************************************
4583 template< typename Type > // Data type of the sparse matrix
4584 template< typename MT // Type of the right-hand side dense matrix
4585  , bool SO > // Storage order of the right-hand side dense matrix
4586 inline void CompressedMatrix<Type,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
4587 {
4588  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4589  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4590 
4591  CompressedMatrix tmp( serial( *this + (~rhs) ) );
4592  swap( tmp );
4593 }
4595 //*************************************************************************************************
4596 
4597 
4598 //*************************************************************************************************
4610 template< typename Type > // Data type of the sparse matrix
4611 template< typename MT // Type of the right-hand side sparse matrix
4612  , bool SO > // Storage order of the right-hand side sparse matrix
4613 inline void CompressedMatrix<Type,true>::addAssign( const SparseMatrix<MT,SO>& rhs )
4614 {
4615  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4616  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4617 
4618  CompressedMatrix tmp( serial( *this + (~rhs) ) );
4619  swap( tmp );
4620 }
4622 //*************************************************************************************************
4623 
4624 
4625 //*************************************************************************************************
4637 template< typename Type > // Data type of the sparse matrix
4638 template< typename MT // Type of the right-hand side dense matrix
4639  , bool SO > // Storage order of the right-hand side dense matrix
4640 inline void CompressedMatrix<Type,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
4641 {
4642  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4643  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4644 
4645  CompressedMatrix tmp( serial( *this - (~rhs) ) );
4646  swap( tmp );
4647 }
4649 //*************************************************************************************************
4650 
4651 
4652 //*************************************************************************************************
4664 template< typename Type > // Data type of the sparse matrix
4665 template< typename MT // Type of the right-hand side sparse matrix
4666  , bool SO > // Storage order of the right-hand side sparse matrix
4667 inline void CompressedMatrix<Type,true>::subAssign( const SparseMatrix<MT,SO>& rhs )
4668 {
4669  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4670  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4671 
4672  CompressedMatrix tmp( serial( *this - (~rhs) ) );
4673  swap( tmp );
4674 }
4676 //*************************************************************************************************
4677 
4678 
4679 
4680 
4681 
4682 
4683 
4684 
4685 //=================================================================================================
4686 //
4687 // COMPRESSEDMATRIX OPERATORS
4688 //
4689 //=================================================================================================
4690 
4691 //*************************************************************************************************
4694 template< typename Type, bool SO >
4695 inline void reset( CompressedMatrix<Type,SO>& m );
4696 
4697 template< typename Type, bool SO >
4698 inline void reset( CompressedMatrix<Type,SO>& m, size_t i );
4699 
4700 template< typename Type, bool SO >
4701 inline void clear( CompressedMatrix<Type,SO>& m );
4702 
4703 template< typename Type, bool SO >
4704 inline bool isDefault( const CompressedMatrix<Type,SO>& m );
4705 
4706 template< typename Type, bool SO >
4707 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) /* throw() */;
4708 
4709 template< typename Type, bool SO >
4710 inline void move( CompressedMatrix<Type,SO>& dst, CompressedMatrix<Type,SO>& src ) /* throw() */;
4712 //*************************************************************************************************
4713 
4714 
4715 //*************************************************************************************************
4722 template< typename Type // Data type of the sparse matrix
4723  , bool SO > // Storage order
4724 inline void reset( CompressedMatrix<Type,SO>& m )
4725 {
4726  m.reset();
4727 }
4728 //*************************************************************************************************
4729 
4730 
4731 //*************************************************************************************************
4744 template< typename Type // Data type of the sparse matrix
4745  , bool SO > // Storage order
4746 inline void reset( CompressedMatrix<Type,SO>& m, size_t i )
4747 {
4748  m.reset( i );
4749 }
4750 //*************************************************************************************************
4751 
4752 
4753 //*************************************************************************************************
4760 template< typename Type // Data type of the sparse matrix
4761  , bool SO > // Storage order
4762 inline void clear( CompressedMatrix<Type,SO>& m )
4763 {
4764  m.clear();
4765 }
4766 //*************************************************************************************************
4767 
4768 
4769 //*************************************************************************************************
4787 template< typename Type // Data type of the sparse matrix
4788  , bool SO > // Storage order
4789 inline bool isDefault( const CompressedMatrix<Type,SO>& m )
4790 {
4791  return ( m.rows() == 0UL && m.columns() == 0UL );
4792 }
4793 //*************************************************************************************************
4794 
4795 
4796 //*************************************************************************************************
4805 template< typename Type // Data type of the sparse matrix
4806  , bool SO > // Storage order
4807 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) /* throw() */
4808 {
4809  a.swap( b );
4810 }
4811 //*************************************************************************************************
4812 
4813 
4814 //*************************************************************************************************
4823 template< typename Type // Data type of the sparse matrix
4824  , bool SO > // Storage order
4825 inline void move( CompressedMatrix<Type,SO>& dst, CompressedMatrix<Type,SO>& src ) /* throw() */
4826 {
4827  dst.swap( src );
4828 }
4829 //*************************************************************************************************
4830 
4831 
4832 
4833 
4834 //=================================================================================================
4835 //
4836 // ISRESIZABLE SPECIALIZATIONS
4837 //
4838 //=================================================================================================
4839 
4840 //*************************************************************************************************
4842 template< typename T, bool SO >
4843 struct IsResizable< CompressedMatrix<T,SO> > : public TrueType
4844 {
4845  enum { value = 1 };
4846  typedef TrueType Type;
4847 };
4849 //*************************************************************************************************
4850 
4851 
4852 
4853 
4854 //=================================================================================================
4855 //
4856 // ADDTRAIT SPECIALIZATIONS
4857 //
4858 //=================================================================================================
4859 
4860 //*************************************************************************************************
4862 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4863 struct AddTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4864 {
4865  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4866 };
4867 
4868 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4869 struct AddTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4870 {
4871  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO2 > Type;
4872 };
4873 
4874 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4875 struct AddTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4876 {
4877  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4878 };
4879 
4880 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4881 struct AddTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4882 {
4883  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO1 > Type;
4884 };
4885 
4886 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4887 struct AddTrait< CompressedMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
4888 {
4889  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4890 };
4891 
4892 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4893 struct AddTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
4894 {
4895  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, SO2 > Type;
4896 };
4897 
4898 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4899 struct AddTrait< HybridMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4900 {
4901  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4902 };
4903 
4904 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4905 struct AddTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4906 {
4907  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, M, N, SO1 > Type;
4908 };
4909 
4910 template< typename T1, bool SO, typename T2 >
4911 struct AddTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4912 {
4913  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4914 };
4915 
4916 template< typename T1, bool SO1, typename T2, bool SO2 >
4917 struct AddTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4918 {
4919  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO2 > Type;
4920 };
4921 
4922 template< typename T1, bool SO, typename T2 >
4923 struct AddTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4924 {
4925  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4926 };
4927 
4928 template< typename T1, bool SO1, typename T2, bool SO2 >
4929 struct AddTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4930 {
4931  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO1 > Type;
4932 };
4933 
4934 template< typename T1, bool SO, typename T2 >
4935 struct AddTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
4936 {
4937  typedef CompressedMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4938 };
4939 
4940 template< typename T1, bool SO1, typename T2, bool SO2 >
4941 struct AddTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
4942 {
4943  typedef CompressedMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4944 };
4946 //*************************************************************************************************
4947 
4948 
4949 
4950 
4951 //=================================================================================================
4952 //
4953 // SUBTRAIT SPECIALIZATIONS
4954 //
4955 //=================================================================================================
4956 
4957 //*************************************************************************************************
4959 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4960 struct SubTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4961 {
4962  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4963 };
4964 
4965 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4966 struct SubTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4967 {
4968  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO2 > Type;
4969 };
4970 
4971 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4972 struct SubTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4973 {
4974  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4975 };
4976 
4977 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4978 struct SubTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
4979 {
4980  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO1 > Type;
4981 };
4982 
4983 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4984 struct SubTrait< CompressedMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
4985 {
4986  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4987 };
4988 
4989 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4990 struct SubTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
4991 {
4992  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, SO2 > Type;
4993 };
4994 
4995 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4996 struct SubTrait< HybridMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
4997 {
4998  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4999 };
5000 
5001 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5002 struct SubTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
5003 {
5004  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, M, N, SO1 > Type;
5005 };
5006 
5007 template< typename T1, bool SO, typename T2 >
5008 struct SubTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
5009 {
5010  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
5011 };
5012 
5013 template< typename T1, bool SO1, typename T2, bool SO2 >
5014 struct SubTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
5015 {
5016  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO2 > Type;
5017 };
5018 
5019 template< typename T1, bool SO, typename T2 >
5020 struct SubTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
5021 {
5022  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
5023 };
5024 
5025 template< typename T1, bool SO1, typename T2, bool SO2 >
5026 struct SubTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
5027 {
5028  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO1 > Type;
5029 };
5030 
5031 template< typename T1, bool SO, typename T2 >
5032 struct SubTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
5033 {
5034  typedef CompressedMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
5035 };
5036 
5037 template< typename T1, bool SO1, typename T2, bool SO2 >
5038 struct SubTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
5039 {
5040  typedef CompressedMatrix< typename SubTrait<T1,T2>::Type , false > Type;
5041 };
5043 //*************************************************************************************************
5044 
5045 
5046 
5047 
5048 //=================================================================================================
5049 //
5050 // MULTTRAIT SPECIALIZATIONS
5051 //
5052 //=================================================================================================
5053 
5054 //*************************************************************************************************
5056 template< typename T1, bool SO, typename T2 >
5057 struct MultTrait< CompressedMatrix<T1,SO>, T2 >
5058 {
5059  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
5061 };
5062 
5063 template< typename T1, typename T2, bool SO >
5064 struct MultTrait< T1, CompressedMatrix<T2,SO> >
5065 {
5066  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
5068 };
5069 
5070 template< typename T1, bool SO, typename T2, size_t N >
5071 struct MultTrait< CompressedMatrix<T1,SO>, StaticVector<T2,N,false> >
5072 {
5073  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
5074 };
5075 
5076 template< typename T1, size_t N, typename T2, bool SO >
5077 struct MultTrait< StaticVector<T1,N,true>, CompressedMatrix<T2,SO> >
5078 {
5079  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
5080 };
5081 
5082 template< typename T1, bool SO, typename T2, size_t N >
5083 struct MultTrait< CompressedMatrix<T1,SO>, HybridVector<T2,N,false> >
5084 {
5085  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
5086 };
5087 
5088 template< typename T1, size_t N, typename T2, bool SO >
5089 struct MultTrait< HybridVector<T1,N,true>, CompressedMatrix<T2,SO> >
5090 {
5091  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
5092 };
5093 
5094 template< typename T1, bool SO, typename T2 >
5095 struct MultTrait< CompressedMatrix<T1,SO>, DynamicVector<T2,false> >
5096 {
5097  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
5098 };
5099 
5100 template< typename T1, typename T2, bool SO >
5101 struct MultTrait< DynamicVector<T1,true>, CompressedMatrix<T2,SO> >
5102 {
5103  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
5104 };
5105 
5106 template< typename T1, bool SO, typename T2 >
5107 struct MultTrait< CompressedMatrix<T1,SO>, CompressedVector<T2,false> >
5108 {
5109  typedef CompressedVector< typename MultTrait<T1,T2>::Type, false > Type;
5110 };
5111 
5112 template< typename T1, typename T2, bool SO >
5113 struct MultTrait< CompressedVector<T1,true>, CompressedMatrix<T2,SO> >
5114 {
5115  typedef CompressedVector< typename MultTrait<T1,T2>::Type, true > Type;
5116 };
5117 
5118 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5119 struct MultTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
5120 {
5121  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5122 };
5123 
5124 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5125 struct MultTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
5126 {
5127  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5128 };
5129 
5130 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5131 struct MultTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
5132 {
5133  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5134 };
5135 
5136 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5137 struct MultTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
5138 {
5139  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5140 };
5141 
5142 template< typename T1, bool SO1, typename T2, bool SO2 >
5143 struct MultTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
5144 {
5145  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5146 };
5147 
5148 template< typename T1, bool SO1, typename T2, bool SO2 >
5149 struct MultTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
5150 {
5151  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5152 };
5153 
5154 template< typename T1, bool SO1, typename T2, bool SO2 >
5155 struct MultTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
5156 {
5157  typedef CompressedMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
5158 };
5160 //*************************************************************************************************
5161 
5162 
5163 
5164 
5165 //=================================================================================================
5166 //
5167 // DIVTRAIT SPECIALIZATIONS
5168 //
5169 //=================================================================================================
5170 
5171 //*************************************************************************************************
5173 template< typename T1, bool SO, typename T2 >
5174 struct DivTrait< CompressedMatrix<T1,SO>, T2 >
5175 {
5176  typedef CompressedMatrix< typename DivTrait<T1,T2>::Type, SO > Type;
5178 };
5180 //*************************************************************************************************
5181 
5182 
5183 
5184 
5185 //=================================================================================================
5186 //
5187 // MATHTRAIT SPECIALIZATIONS
5188 //
5189 //=================================================================================================
5190 
5191 //*************************************************************************************************
5193 template< typename T1, bool SO, typename T2 >
5194 struct MathTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
5195 {
5196  typedef CompressedMatrix< typename MathTrait<T1,T2>::HighType, SO > HighType;
5197  typedef CompressedMatrix< typename MathTrait<T1,T2>::LowType , SO > LowType;
5198 };
5200 //*************************************************************************************************
5201 
5202 
5203 
5204 
5205 //=================================================================================================
5206 //
5207 // SUBMATRIXTRAIT SPECIALIZATIONS
5208 //
5209 //=================================================================================================
5210 
5211 //*************************************************************************************************
5213 template< typename T1, bool SO >
5214 struct SubmatrixTrait< CompressedMatrix<T1,SO> >
5215 {
5216  typedef CompressedMatrix<T1,SO> Type;
5217 };
5219 //*************************************************************************************************
5220 
5221 
5222 
5223 
5224 //=================================================================================================
5225 //
5226 // ROWTRAIT SPECIALIZATIONS
5227 //
5228 //=================================================================================================
5229 
5230 //*************************************************************************************************
5232 template< typename T1, bool SO >
5233 struct RowTrait< CompressedMatrix<T1,SO> >
5234 {
5235  typedef CompressedVector<T1,true> Type;
5236 };
5238 //*************************************************************************************************
5239 
5240 
5241 
5242 
5243 //=================================================================================================
5244 //
5245 // COLUMNTRAIT SPECIALIZATIONS
5246 //
5247 //=================================================================================================
5248 
5249 //*************************************************************************************************
5251 template< typename T1, bool SO >
5252 struct ColumnTrait< CompressedMatrix<T1,SO> >
5253 {
5254  typedef CompressedVector<T1,false> Type;
5255 };
5257 //*************************************************************************************************
5258 
5259 } // namespace blaze
5260 
5261 #endif
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
Definition: Const.h:116
Pointer difference type of the Blaze library.
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1649
size_t rows() const
Returns the current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:1136
void reserveElements(size_t nonzeros)
Reserving the specified number of sparse matrix elements.
Definition: CompressedMatrix.h:1842
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:425
Header file for mathematical functions.
#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:264
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.
Header file for basic type definitions.
const Type & ConstReference
Reference to a constant sparse matrix value.
Definition: CompressedMatrix.h:265
const bool defaultStorageOrder
The default storage order for all matrices of the Blaze library.This value specifies the default stor...
Definition: StorageOrder.h:56
void move(CompressedMatrix< Type, SO > &dst, CompressedMatrix< Type, SO > &src)
Moving the contents of one compressed matrix to another.
Definition: CompressedMatrix.h:4825
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:264
Header file for the row trait.
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:258
Header file for the IsSparseMatrix type trait.
CompressedMatrix()
The default constructor for CompressedMatrix.
Definition: CompressedMatrix.h:469
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:209
size_t extendCapacity() const
Calculating a new matrix capacity.
Definition: CompressedMatrix.h:1822
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:821
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2665
void clear()
Clearing the sparse matrix.
Definition: CompressedMatrix.h:1277
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix)
Returns the maximum capacity of the matrix.
Definition: Matrix.h:348
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:261
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:316
void clear(CompressedMatrix< Type, SO > &m)
Clearing the given compressed matrix.
Definition: CompressedMatrix.h:4762
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:90
CompressedMatrix< ET, SO > Other
The type of the other CompressedMatrix.
Definition: CompressedMatrix.h:275
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2501
CompressedMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:259
#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:657
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:699
void reset(CompressedMatrix< Type, SO > &m)
Resetting the given compressed matrix.
Definition: CompressedMatrix.h:4724
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:386
Access proxy for sparse, matrices.The MatrixAccessProxy provides safe access to the elements of a no...
Definition: MatrixAccessProxy.h:95
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:90
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:2166
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:427
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:262
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
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:861
Constraint on the data type.
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: CompressedMatrix.h:1199
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:2667
Header file for the SparseMatrix base class.
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:423
void reserve(size_t nonzeros)
Setting the minimum capacity of the sparse matrix.
Definition: CompressedMatrix.h:1606
void reset()
Reset to the default initial values.
Definition: CompressedMatrix.h:1239
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:263
Header file for the ValueIndexPair class.
bool isDefault(const CompressedMatrix< Type, SO > &m)
Returns whether the given compressed matrix is in default state.
Definition: CompressedMatrix.h:4789
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
Header file for the If class template.
Header file for the IsFloatingPoint type trait.
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b)
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:4807
Iterator set(size_t i, size_t j, const Type &value)
Setting an element of the compressed matrix.
Definition: CompressedMatrix.h:1301
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:2511
#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:1436
Iterator * end_
Pointers one past the last non-zero element of each column.
Definition: CompressedMatrix.h:2669
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1602
BLAZE_ALWAYS_INLINE void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:635
EnableIf< IsBuiltin< T > >::Type deallocate(T *address)
Deallocation of memory for built-in data types.
Definition: Memory.h:226
#define BLAZE_CONSTRAINT_MUST_HAVE_SAME_SIZE(T1, T2)
Constraint on the size of two data types.In case the types T1 and T2 don't have the same size...
Definition: SameSize.h:78
ValueIndexPair< Type > ElementBase
Base class for the sparse matrix element.
Definition: CompressedMatrix.h:213
Constraint on the data type.
Header file for the IsLower type trait.
Header file for the equal shim.
Header file for the default storage order for all vectors of the Blaze library.
Iterator insert(size_t i, size_t j, const Type &value)
Inserting an element into the compressed matrix.
Definition: CompressedMatrix.h:1333
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:195
CompressedMatrix< ET, true > Other
The type of the other CompressedMatrix.
Definition: CompressedMatrix.h:2519
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
Compile time check for floating point data types.This type trait tests whether or not the given templ...
Definition: IsFloatingPoint.h:94
Compile time check for data types.This type trait tests whether or not the given template parameter i...
Definition: IsSMPAssignable.h:120
BLAZE_ALWAYS_INLINE void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:535
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2509
void subAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the subtraction assignment of a dense matrix.
Definition: CompressedMatrix.h:2395
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
Header file for the serial shim.
void swap(CompressedMatrix &sm)
Swapping the contents of two sparse matrices.
Definition: CompressedMatrix.h:1801
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:267
bool canSMPAssign() const
Returns whether the matrix can be used in SMP assignments.
Definition: CompressedMatrix.h:2185
size_t capacity() const
Returns the maximum capacity of the sparse matrix.
Definition: CompressedMatrix.h:1164
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the sparse matrix.
Definition: CompressedMatrix.h:1522
Header file for the IsNumeric type trait.
CompressedMatrix & operator=(const CompressedMatrix &rhs)
Copy assignment operator for CompressedMatrix.
Definition: CompressedMatrix.h:870
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:116
Reference operator()(size_t i, size_t j)
2D-access to the sparse matrix elements.
Definition: CompressedMatrix.h:683
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:798
CompressedMatrix & transpose()
Transposing the matrix.
Definition: CompressedMatrix.h:1739
BLAZE_ALWAYS_INLINE void addAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a matrix to a matrix.
Definition: Matrix.h:742
Header file for the division trait.
void trim()
Removing all excessive capacity from all rows/columns.
Definition: CompressedMatrix.h:1700
Header file for the submatrix trait.
Constraint on the data type.
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
#define BLAZE_CONSTRAINT_MUST_BE_NUMERIC_TYPE(T)
Constraint on the data type.In case the given data type T is not a numeric (integral or floating poin...
Definition: Numeric.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:116
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2510
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
Constraint on the data type.
size_t columns() const
Returns the current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:1150
Constraint on the data type.
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:258
Iterator * begin_
Pointers to the first non-zero element of each column.
Definition: CompressedMatrix.h:2668
void assign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the assignment of a row-major dense matrix.
Definition: CompressedMatrix.h:2207
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:266
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:2082
void finalize(size_t i)
Finalizing the element insertion of a row/column.
Definition: CompressedMatrix.h:2114
bool canAlias(const Other *alias) const
Returns whether the matrix can alias with the given address alias.
Definition: CompressedMatrix.h:2146
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b)
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:200
Base template for the DivTrait class.
Definition: DivTrait.h:150
CompressedMatrix< Type, SO > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:257
Iterator find(size_t i, size_t j)
Searches for a specific matrix element.
Definition: CompressedMatrix.h:1891
Header file for the mathematical trait.
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
Iterator * begin_
Pointers to the first non-zero element of each row.
Definition: CompressedMatrix.h:424
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2666
Index-value-pair for sparse vectors and matrices.The ValueIndexPair class represents a single index-v...
Definition: ValueIndexPair.h:70
Constraint on the size of two data types.
void addAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the addition assignment of a dense matrix.
Definition: CompressedMatrix.h:2343
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:937
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:260
Iterator lowerBound(size_t i, size_t j)
Returns an iterator to the first index not less then the given index.
Definition: CompressedMatrix.h:1944
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:2671
Iterator upperBound(size_t i, size_t j)
Returns an iterator to the first index greater then the given index.
Definition: CompressedMatrix.h:1995
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix)
Returns the current number of columns of the matrix.
Definition: Matrix.h:332
ConstIterator cbegin(size_t i) const
Returns an iterator to the first non-zero element of row/column i.
Definition: CompressedMatrix.h:776
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2508
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:274
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:2518
Header file for the IsUpper type trait.
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:422
ConstIterator cend(size_t i) const
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:842
Header file for the IsResizable type trait.
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:421
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Iterator begin(size_t i)
Returns an iterator to the first non-zero element of row/column i.
Definition: CompressedMatrix.h:732
BLAZE_ALWAYS_INLINE void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:849
Header file for a safe C++ NULL pointer implementation.