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 <utility>
45 #include <vector>
46 #include <blaze/math/Aliases.h>
48 #include <blaze/math/Exception.h>
50 #include <blaze/math/Forward.h>
51 #include <blaze/math/Functions.h>
74 #include <blaze/util/Algorithm.h>
75 #include <blaze/util/Assert.h>
81 #include <blaze/util/EnableIf.h>
82 #include <blaze/util/Memory.h>
83 #include <blaze/util/mpl/If.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 matrix
208  , bool SO = defaultStorageOrder > // Storage order
209 class CompressedMatrix : public SparseMatrix< CompressedMatrix<Type,SO>, SO >
210 {
211  private:
212  //**Type definitions****************************************************************************
214  typedef ElementBase* IteratorBase;
215  //**********************************************************************************************
216 
217  //**Private class Element***********************************************************************
224  struct Element : public ElementBase
225  {
226  //**Constructors*****************************************************************************
227  explicit Element() = default;
228  Element( const Element& rhs ) = default;
229  Element( Element&& rhs ) = default;
230  //*******************************************************************************************
231 
232  //**Assignment operators*********************************************************************
233  inline Element& operator=( const Element& rhs )
234  {
235  this->value_ = rhs.value_;
236  return *this;
237  }
238 
239  inline Element& operator=( Element&& rhs )
240  {
241  this->value_ = std::move( rhs.value_ );
242  return *this;
243  }
244 
245  template< typename Other >
246  inline EnableIf_< IsSparseElement<Other>, Element& >
247  operator=( const Other& rhs )
248  {
249  this->value_ = rhs.value();
250  return *this;
251  }
252 
253  template< typename Other >
255  , IsRValueReference<Other&&> >, Element& >
256  operator=( Other&& rhs )
257  {
258  this->value_ = std::move( rhs.value() );
259  return *this;
260  }
261 
262  template< typename Other >
263  inline EnableIf_< Not< IsSparseElement<Other> >, Element& >
264  operator=( const Other& v )
265  {
266  this->value_ = v;
267  return *this;
268  }
269 
270  template< typename Other >
272  , IsRValueReference<Other&&> >, Element& >
273  operator=( Other&& v )
274  {
275  this->value_ = std::move( v );
276  return *this;
277  }
278  //*******************************************************************************************
279 
280  //**Friend declarations**********************************************************************
281  friend class CompressedMatrix;
282  //*******************************************************************************************
283  };
285  //**********************************************************************************************
286 
287  public:
288  //**Type definitions****************************************************************************
291  typedef This ResultType;
294  typedef Type ElementType;
295  typedef const Type& ReturnType;
296  typedef const This& CompositeType;
298  typedef const Type& ConstReference;
299  typedef Element* Iterator;
300  typedef const Element* ConstIterator;
301  //**********************************************************************************************
302 
303  //**Rebind struct definition********************************************************************
306  template< typename NewType > // Data type of the other matrix
307  struct Rebind {
309  };
310  //**********************************************************************************************
311 
312  //**Resize struct definition********************************************************************
315  template< size_t NewM // Number of rows of the other matrix
316  , size_t NewN > // Number of columns of the other matrix
317  struct Resize {
319  };
320  //**********************************************************************************************
321 
322  //**Compilation flags***************************************************************************
324 
327  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
328  //**********************************************************************************************
329 
330  //**Constructors********************************************************************************
333  explicit inline CompressedMatrix();
334  explicit inline CompressedMatrix( size_t m, size_t n );
335  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
336  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
337  inline CompressedMatrix( const CompressedMatrix& sm );
338  inline CompressedMatrix( CompressedMatrix&& sm ) noexcept;
339  template< typename MT, bool SO2 > inline CompressedMatrix( const DenseMatrix<MT,SO2>& dm );
340  template< typename MT, bool SO2 > inline CompressedMatrix( const SparseMatrix<MT,SO2>& sm );
342  //**********************************************************************************************
343 
344  //**Destructor**********************************************************************************
347  inline ~CompressedMatrix();
349  //**********************************************************************************************
350 
351  //**Data access functions***********************************************************************
354  inline Reference operator()( size_t i, size_t j ) noexcept;
355  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
356  inline Reference at( size_t i, size_t j );
357  inline ConstReference at( size_t i, size_t j ) const;
358  inline Iterator begin ( size_t i ) noexcept;
359  inline ConstIterator begin ( size_t i ) const noexcept;
360  inline ConstIterator cbegin( size_t i ) const noexcept;
361  inline Iterator end ( size_t i ) noexcept;
362  inline ConstIterator end ( size_t i ) const noexcept;
363  inline ConstIterator cend ( size_t i ) const noexcept;
365  //**********************************************************************************************
366 
367  //**Assignment operators************************************************************************
370  inline CompressedMatrix& operator=( const CompressedMatrix& rhs );
371  inline CompressedMatrix& operator=( CompressedMatrix&& rhs ) noexcept;
372 
373  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO2>& rhs );
374  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO2>& rhs );
375  template< typename MT, bool SO2 > inline CompressedMatrix& operator+=( const Matrix<MT,SO2>& rhs );
376  template< typename MT, bool SO2 > inline CompressedMatrix& operator-=( const Matrix<MT,SO2>& rhs );
377  template< typename MT, bool SO2 > inline CompressedMatrix& operator*=( const Matrix<MT,SO2>& rhs );
378 
379  template< typename Other >
380  inline EnableIf_< IsNumeric<Other>, CompressedMatrix >& operator*=( Other rhs );
381 
382  template< typename Other >
383  inline EnableIf_< IsNumeric<Other>, CompressedMatrix >& operator/=( Other rhs );
385  //**********************************************************************************************
386 
387  //**Utility functions***************************************************************************
390  inline size_t rows() const noexcept;
391  inline size_t columns() const noexcept;
392  inline size_t capacity() const noexcept;
393  inline size_t capacity( size_t i ) const noexcept;
394  inline size_t nonZeros() const;
395  inline size_t nonZeros( size_t i ) const;
396  inline void reset();
397  inline void reset( size_t i );
398  inline void clear();
399  void resize ( size_t m, size_t n, bool preserve=true );
400  inline void reserve( size_t nonzeros );
401  void reserve( size_t i, size_t nonzeros );
402  inline void trim ();
403  inline void trim ( size_t i );
404  inline void swap( CompressedMatrix& sm ) noexcept;
406  //**********************************************************************************************
407 
408  //**Insertion functions*************************************************************************
411  inline Iterator set ( size_t i, size_t j, const Type& value );
412  inline Iterator insert ( size_t i, size_t j, const Type& value );
413  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
414  inline void finalize( size_t i );
416  //**********************************************************************************************
417 
418  //**Erase functions*****************************************************************************
421  inline void erase( size_t i, size_t j );
422  inline Iterator erase( size_t i, Iterator pos );
423  inline Iterator erase( size_t i, Iterator first, Iterator last );
424 
425  template< typename Pred >
426  inline void erase( Pred predicate );
427 
428  template< typename Pred >
429  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
431  //**********************************************************************************************
432 
433  //**Lookup functions****************************************************************************
436  inline Iterator find ( size_t i, size_t j );
437  inline ConstIterator find ( size_t i, size_t j ) const;
438  inline Iterator lowerBound( size_t i, size_t j );
439  inline ConstIterator lowerBound( size_t i, size_t j ) const;
440  inline Iterator upperBound( size_t i, size_t j );
441  inline ConstIterator upperBound( size_t i, size_t j ) const;
443  //**********************************************************************************************
444 
445  //**Numeric functions***************************************************************************
448  inline CompressedMatrix& transpose();
449  inline CompressedMatrix& ctranspose();
450 
451  template< typename Other > inline CompressedMatrix& scale( const Other& scalar );
452  template< typename Other > inline CompressedMatrix& scaleDiagonal( const Other& scalar );
454  //**********************************************************************************************
455 
456  //**Expression template evaluation functions****************************************************
459  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
460  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
461 
462  inline bool canSMPAssign() const noexcept;
463 
464  template< typename MT, bool SO2 > inline void assign ( const DenseMatrix<MT,SO2>& rhs );
465  template< typename MT > inline void assign ( const SparseMatrix<MT,SO>& rhs );
466  template< typename MT > inline void assign ( const SparseMatrix<MT,!SO>& rhs );
467  template< typename MT, bool SO2 > inline void addAssign( const DenseMatrix<MT,SO2>& rhs );
468  template< typename MT, bool SO2 > inline void addAssign( const SparseMatrix<MT,SO2>& rhs );
469  template< typename MT, bool SO2 > inline void subAssign( const DenseMatrix<MT,SO2>& rhs );
470  template< typename MT, bool SO2 > inline void subAssign( const SparseMatrix<MT,SO2>& rhs );
472  //**********************************************************************************************
473 
474  private:
475  //**Utility functions***************************************************************************
478  inline size_t extendCapacity() const noexcept;
479  void reserveElements( size_t nonzeros );
480 
481  inline Iterator castDown( IteratorBase it ) const noexcept;
482  inline IteratorBase castUp ( Iterator it ) const noexcept;
484  //**********************************************************************************************
485 
486  //**Insertion functions*************************************************************************
489  Iterator insert( Iterator pos, size_t i, size_t j, const Type& value );
491  //**********************************************************************************************
492 
493  //**Member variables****************************************************************************
496  size_t m_;
497  size_t n_;
498  size_t capacity_;
499  Iterator* begin_;
500  Iterator* end_;
501 
502  static const Type zero_;
503 
504  //**********************************************************************************************
505 
506  //**Compile time checks*************************************************************************
512  BLAZE_CONSTRAINT_MUST_HAVE_SAME_SIZE ( ElementBase, Element );
514  //**********************************************************************************************
515 };
516 //*************************************************************************************************
517 
518 
519 
520 
521 //=================================================================================================
522 //
523 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
524 //
525 //=================================================================================================
526 
527 template< typename Type, bool SO >
528 const Type CompressedMatrix<Type,SO>::zero_ = Type();
529 
530 
531 
532 
533 //=================================================================================================
534 //
535 // CONSTRUCTORS
536 //
537 //=================================================================================================
538 
539 //*************************************************************************************************
542 template< typename Type // Data type of the matrix
543  , bool SO > // Storage order
545  : m_ ( 0UL ) // The current number of rows of the compressed matrix
546  , n_ ( 0UL ) // The current number of columns of the compressed matrix
547  , capacity_( 0UL ) // The current capacity of the pointer array
548  , begin_ ( nullptr ) // Pointers to the first non-zero element of each row
549  , end_ ( nullptr ) // Pointers one past the last non-zero element of each row
550 {}
551 //*************************************************************************************************
552 
553 
554 //*************************************************************************************************
562 template< typename Type // Data type of the matrix
563  , bool SO > // Storage order
565  : m_ ( m ) // The current number of rows of the compressed matrix
566  , n_ ( n ) // The current number of columns of the compressed matrix
567  , capacity_( m ) // The current capacity of the pointer array
568  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
569  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
570 {
571  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
572  begin_[i] = nullptr;
573 }
574 //*************************************************************************************************
575 
576 
577 //*************************************************************************************************
586 template< typename Type // Data type of the matrix
587  , bool SO > // Storage order
588 inline CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
589  : m_ ( m ) // The current number of rows of the compressed matrix
590  , n_ ( n ) // The current number of columns of the compressed matrix
591  , capacity_( m ) // The current capacity of the pointer array
592  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
593  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
594 {
595  begin_[0UL] = allocate<Element>( nonzeros );
596  for( size_t i=1UL; i<(2UL*m_+1UL); ++i )
597  begin_[i] = begin_[0UL];
598  end_[m_] = begin_[0UL]+nonzeros;
599 }
600 //*************************************************************************************************
601 
602 
603 //*************************************************************************************************
614 template< typename Type // Data type of the matrix
615  , bool SO > // Storage order
616 CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
617  : m_ ( m ) // The current number of rows of the compressed matrix
618  , n_ ( n ) // The current number of columns of the compressed matrix
619  , capacity_( m ) // The current capacity of the pointer array
620  , begin_( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
621  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
622 {
623  BLAZE_USER_ASSERT( nonzeros.size() == m, "Size of capacity vector and number of rows don't match" );
624 
625  size_t newCapacity( 0UL );
626  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
627  newCapacity += *it;
628 
629  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
630  for( size_t i=0UL; i<m_; ++i ) {
631  begin_[i+1UL] = end_[i+1UL] = begin_[i] + nonzeros[i];
632  }
633 }
634 //*************************************************************************************************
635 
636 
637 //*************************************************************************************************
642 template< typename Type // Data type of the matrix
643  , bool SO > // Storage order
645  : m_ ( sm.m_ ) // The current number of rows of the compressed matrix
646  , n_ ( sm.n_ ) // The current number of columns of the compressed matrix
647  , capacity_( sm.m_ ) // The current capacity of the pointer array
648  , begin_( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
649  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
650 {
651  const size_t nonzeros( sm.nonZeros() );
652 
653  begin_[0UL] = allocate<Element>( nonzeros );
654  for( size_t i=0UL; i<m_; ++i ) {
655  end_[i] = castDown( std::copy( sm.begin(i), sm.end(i), castUp( begin_[i] ) ) );
656  begin_[i+1UL] = end_[i];
657  }
658  end_[m_] = begin_[0UL]+nonzeros;
659 }
660 //*************************************************************************************************
661 
662 
663 //*************************************************************************************************
668 template< typename Type // Data type of the matrix
669  , bool SO > // Storage order
671  : m_ ( sm.m_ ) // The current number of rows of the compressed matrix
672  , n_ ( sm.n_ ) // The current number of columns of the compressed matrix
673  , capacity_( sm.capacity_ ) // The current capacity of the pointer array
674  , begin_ ( sm.begin_ ) // Pointers to the first non-zero element of each row
675  , end_ ( sm.end_ ) // Pointers one past the last non-zero element of each row
676 {
677  sm.m_ = 0UL;
678  sm.n_ = 0UL;
679  sm.capacity_ = 0UL;
680  sm.begin_ = nullptr;
681  sm.end_ = nullptr;
682 }
683 //*************************************************************************************************
684 
685 
686 //*************************************************************************************************
691 template< typename Type // Data type of the matrix
692  , bool SO > // Storage order
693 template< typename MT // Type of the foreign dense matrix
694  , bool SO2 > // Storage order of the foreign dense matrix
696  : m_ ( (~dm).rows() ) // The current number of rows of the compressed matrix
697  , n_ ( (~dm).columns() ) // The current number of columns of the compressed matrix
698  , capacity_( m_ ) // The current capacity of the pointer array
699  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
700  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
701 {
702  using blaze::assign;
703 
704  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
705  begin_[i] = nullptr;
706 
707  assign( *this, ~dm );
708 }
709 //*************************************************************************************************
710 
711 
712 //*************************************************************************************************
717 template< typename Type // Data type of the matrix
718  , bool SO > // Storage order
719 template< typename MT // Type of the foreign compressed matrix
720  , bool SO2 > // Storage order of the foreign compressed matrix
722  : m_ ( (~sm).rows() ) // The current number of rows of the compressed matrix
723  , n_ ( (~sm).columns() ) // The current number of columns of the compressed matrix
724  , capacity_( m_ ) // The current capacity of the pointer array
725  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
726  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
727 {
728  using blaze::assign;
729 
730  const size_t nonzeros( (~sm).nonZeros() );
731 
732  begin_[0UL] = allocate<Element>( nonzeros );
733  for( size_t i=0UL; i<m_; ++i )
734  begin_[i+1UL] = end_[i] = begin_[0UL];
735  end_[m_] = begin_[0UL]+nonzeros;
736 
737  assign( *this, ~sm );
738 }
739 //*************************************************************************************************
740 
741 
742 
743 
744 //=================================================================================================
745 //
746 // DESTRUCTOR
747 //
748 //=================================================================================================
749 
750 //*************************************************************************************************
753 template< typename Type // Data type of the matrix
754  , bool SO > // Storage order
756 {
757  if( begin_ != nullptr ) {
758  deallocate( begin_[0UL] );
759  delete[] begin_;
760  }
761 }
762 //*************************************************************************************************
763 
764 
765 
766 
767 //=================================================================================================
768 //
769 // DATA ACCESS FUNCTIONS
770 //
771 //=================================================================================================
772 
773 //*************************************************************************************************
786 template< typename Type // Data type of the matrix
787  , bool SO > // Storage order
789  CompressedMatrix<Type,SO>::operator()( size_t i, size_t j ) noexcept
790 {
791  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
792  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
793 
794  return Reference( *this, i, j );
795 }
796 //*************************************************************************************************
797 
798 
799 //*************************************************************************************************
809 template< typename Type // Data type of the matrix
810  , bool SO > // Storage order
812  CompressedMatrix<Type,SO>::operator()( size_t i, size_t j ) const noexcept
813 {
814  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
815  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
816 
817  const ConstIterator pos( lowerBound( i, j ) );
818 
819  if( pos == end_[i] || pos->index_ != j )
820  return zero_;
821  else
822  return pos->value_;
823 }
824 //*************************************************************************************************
825 
826 
827 //*************************************************************************************************
840 template< typename Type // Data type of the matrix
841  , bool SO > // Storage order
843  CompressedMatrix<Type,SO>::at( size_t i, size_t j )
844 {
845  if( i >= m_ ) {
846  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
847  }
848  if( j >= n_ ) {
849  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
850  }
851  return (*this)(i,j);
852 }
853 //*************************************************************************************************
854 
855 
856 //*************************************************************************************************
867 template< typename Type // Data type of the matrix
868  , bool SO > // Storage order
870  CompressedMatrix<Type,SO>::at( size_t i, size_t j ) const
871 {
872  if( i >= m_ ) {
873  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
874  }
875  if( j >= n_ ) {
876  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
877  }
878  return (*this)(i,j);
879 }
880 //*************************************************************************************************
881 
882 
883 //*************************************************************************************************
894 template< typename Type // Data type of the matrix
895  , bool SO > // Storage order
897  CompressedMatrix<Type,SO>::begin( size_t i ) noexcept
898 {
899  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
900  return begin_[i];
901 }
902 //*************************************************************************************************
903 
904 
905 //*************************************************************************************************
916 template< typename Type // Data type of the matrix
917  , bool SO > // Storage order
919  CompressedMatrix<Type,SO>::begin( size_t i ) const noexcept
920 {
921  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
922  return begin_[i];
923 }
924 //*************************************************************************************************
925 
926 
927 //*************************************************************************************************
938 template< typename Type // Data type of the matrix
939  , bool SO > // Storage order
941  CompressedMatrix<Type,SO>::cbegin( size_t i ) const noexcept
942 {
943  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
944  return begin_[i];
945 }
946 //*************************************************************************************************
947 
948 
949 //*************************************************************************************************
960 template< typename Type // Data type of the matrix
961  , bool SO > // Storage order
963  CompressedMatrix<Type,SO>::end( size_t i ) noexcept
964 {
965  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
966  return end_[i];
967 }
968 //*************************************************************************************************
969 
970 
971 //*************************************************************************************************
982 template< typename Type // Data type of the matrix
983  , bool SO > // Storage order
985  CompressedMatrix<Type,SO>::end( size_t i ) const noexcept
986 {
987  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
988  return end_[i];
989 }
990 //*************************************************************************************************
991 
992 
993 //*************************************************************************************************
1004 template< typename Type // Data type of the matrix
1005  , bool SO > // Storage order
1007  CompressedMatrix<Type,SO>::cend( size_t i ) const noexcept
1008 {
1009  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1010  return end_[i];
1011 }
1012 //*************************************************************************************************
1013 
1014 
1015 
1016 
1017 //=================================================================================================
1018 //
1019 // ASSIGNMENT OPERATORS
1020 //
1021 //=================================================================================================
1022 
1023 //*************************************************************************************************
1032 template< typename Type // Data type of the matrix
1033  , bool SO > // Storage order
1036 {
1037  if( &rhs == this ) return *this;
1038 
1039  const size_t nonzeros( rhs.nonZeros() );
1040 
1041  if( rhs.m_ > capacity_ || nonzeros > capacity() )
1042  {
1043  Iterator* newBegin( new Iterator[2UL*rhs.m_+2UL] );
1044  Iterator* newEnd ( newBegin+(rhs.m_+1UL) );
1045 
1046  newBegin[0UL] = allocate<Element>( nonzeros );
1047  for( size_t i=0UL; i<rhs.m_; ++i ) {
1048  newEnd[i] = castDown( std::copy( rhs.begin_[i], rhs.end_[i], castUp( newBegin[i] ) ) );
1049  newBegin[i+1UL] = newEnd[i];
1050  }
1051  newEnd[rhs.m_] = newBegin[0UL]+nonzeros;
1052 
1053  std::swap( begin_, newBegin );
1054  end_ = newEnd;
1055  capacity_ = rhs.m_;
1056 
1057  if( newBegin != nullptr ) {
1058  deallocate( newBegin[0UL] );
1059  delete[] newBegin;
1060  }
1061  }
1062  else {
1063  for( size_t i=0UL; i<rhs.m_; ++i ) {
1064  end_[i] = castDown( std::copy( rhs.begin_[i], rhs.end_[i], castUp( begin_[i] ) ) );
1065  begin_[i+1UL] = end_[i];
1066  }
1067  }
1068 
1069  m_ = rhs.m_;
1070  n_ = rhs.n_;
1071 
1072  return *this;
1073 }
1074 //*************************************************************************************************
1075 
1076 
1077 //*************************************************************************************************
1083 template< typename Type // Data type of the matrix
1084  , bool SO > // Storage order
1087 {
1088  if( begin_ != nullptr ) {
1089  deallocate( begin_[0UL] );
1090  delete[] begin_;
1091  }
1092 
1093  m_ = rhs.m_;
1094  n_ = rhs.n_;
1095  capacity_ = rhs.capacity_;
1096  begin_ = rhs.begin_;
1097  end_ = rhs.end_;
1098 
1099  rhs.m_ = 0UL;
1100  rhs.n_ = 0UL;
1101  rhs.capacity_ = 0UL;
1102  rhs.begin_ = nullptr;
1103  rhs.end_ = nullptr;
1104 
1105  return *this;
1106 }
1107 //*************************************************************************************************
1108 
1109 
1110 //*************************************************************************************************
1119 template< typename Type // Data type of the matrix
1120  , bool SO > // Storage order
1121 template< typename MT // Type of the right-hand side dense matrix
1122  , bool SO2 > // Storage order of the right-hand side dense matrix
1125 {
1126  using blaze::assign;
1127 
1128  if( (~rhs).canAlias( this ) ) {
1129  CompressedMatrix tmp( ~rhs );
1130  swap( tmp );
1131  }
1132  else {
1133  resize( (~rhs).rows(), (~rhs).columns(), false );
1134  assign( *this, ~rhs );
1135  }
1136 
1137  return *this;
1138 }
1139 //*************************************************************************************************
1140 
1141 
1142 //*************************************************************************************************
1151 template< typename Type // Data type of the matrix
1152  , bool SO > // Storage order
1153 template< typename MT // Type of the right-hand side compressed matrix
1154  , bool SO2 > // Storage order of the right-hand side compressed matrix
1157 {
1158  using blaze::assign;
1159 
1160  if( (~rhs).canAlias( this ) ||
1161  (~rhs).rows() > capacity_ ||
1162  (~rhs).nonZeros() > capacity() ) {
1163  CompressedMatrix tmp( ~rhs );
1164  swap( tmp );
1165  }
1166  else {
1167  resize( (~rhs).rows(), (~rhs).columns(), false );
1168  reset();
1169  assign( *this, ~rhs );
1170  }
1171 
1172  return *this;
1173 }
1174 //*************************************************************************************************
1175 
1176 
1177 //*************************************************************************************************
1187 template< typename Type // Data type of the matrix
1188  , bool SO > // Storage order
1189 template< typename MT // Type of the right-hand side matrix
1190  , bool SO2 > // Storage order of the right-hand side matrix
1193 {
1194  using blaze::addAssign;
1195 
1196  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1197  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1198  }
1199 
1200  addAssign( *this, ~rhs );
1201  return *this;
1202 }
1203 //*************************************************************************************************
1204 
1205 
1206 //*************************************************************************************************
1216 template< typename Type // Data type of the matrix
1217  , bool SO > // Storage order
1218 template< typename MT // Type of the right-hand side matrix
1219  , bool SO2 > // Storage order of the right-hand side matrix
1221 {
1222  using blaze::subAssign;
1223 
1224  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1225  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1226  }
1227 
1228  subAssign( *this, ~rhs );
1229  return *this;
1230 }
1231 //*************************************************************************************************
1232 
1233 
1234 //*************************************************************************************************
1244 template< typename Type // Data type of the matrix
1245  , bool SO > // Storage order
1246 template< typename MT // Type of the right-hand side matrix
1247  , bool SO2 > // Storage order of the right-hand side matrix
1250 {
1251  if( (~rhs).rows() != n_ ) {
1252  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1253  }
1254 
1255  CompressedMatrix tmp( *this * (~rhs) );
1256  swap( tmp );
1257 
1258  return *this;
1259 }
1260 //*************************************************************************************************
1261 
1262 
1263 //*************************************************************************************************
1270 template< typename Type // Data type of the matrix
1271  , bool SO > // Storage order
1272 template< typename Other > // Data type of the right-hand side scalar
1275 {
1276  for( size_t i=0UL; i<m_; ++i ) {
1277  const Iterator last( end(i) );
1278  for( Iterator element=begin(i); element!=last; ++element )
1279  element->value_ *= rhs;
1280  }
1281  return *this;
1282 }
1283 //*************************************************************************************************
1284 
1285 
1286 //*************************************************************************************************
1293 template< typename Type // Data type of the matrix
1294  , bool SO > // Storage order
1295 template< typename Other > // Data type of the right-hand side scalar
1296 inline EnableIf_< IsNumeric<Other>, CompressedMatrix<Type,SO> >&
1298 {
1299  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1300 
1301  typedef DivTrait_<Type,Other> DT;
1302  typedef If_< IsNumeric<DT>, DT, Other > Tmp;
1303 
1304  // Depending on the two involved data types, an integer division is applied or a
1305  // floating point division is selected.
1307  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1308  for( size_t i=0UL; i<m_; ++i ) {
1309  const Iterator last( end(i) );
1310  for( Iterator element=begin(i); element!=last; ++element )
1311  element->value_ *= tmp;
1312  }
1313  }
1314  else {
1315  for( size_t i=0UL; i<m_; ++i ) {
1316  const Iterator last( end(i) );
1317  for( Iterator element=begin(i); element!=last; ++element )
1318  element->value_ /= rhs;
1319  }
1320  }
1321 
1322  return *this;
1323 }
1324 //*************************************************************************************************
1325 
1326 
1327 
1328 
1329 //=================================================================================================
1330 //
1331 // UTILITY FUNCTIONS
1332 //
1333 //=================================================================================================
1334 
1335 //*************************************************************************************************
1340 template< typename Type // Data type of the matrix
1341  , bool SO > // Storage order
1342 inline size_t CompressedMatrix<Type,SO>::rows() const noexcept
1343 {
1344  return m_;
1345 }
1346 //*************************************************************************************************
1347 
1348 
1349 //*************************************************************************************************
1354 template< typename Type // Data type of the matrix
1355  , bool SO > // Storage order
1356 inline size_t CompressedMatrix<Type,SO>::columns() const noexcept
1357 {
1358  return n_;
1359 }
1360 //*************************************************************************************************
1361 
1362 
1363 //*************************************************************************************************
1368 template< typename Type // Data type of the matrix
1369  , bool SO > // Storage order
1370 inline size_t CompressedMatrix<Type,SO>::capacity() const noexcept
1371 {
1372  if( begin_ != nullptr )
1373  return end_[m_] - begin_[0UL];
1374  else return 0UL;
1375 }
1376 //*************************************************************************************************
1377 
1378 
1379 //*************************************************************************************************
1390 template< typename Type // Data type of the matrix
1391  , bool SO > // Storage order
1392 inline size_t CompressedMatrix<Type,SO>::capacity( size_t i ) const noexcept
1393 {
1394  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1395  return begin_[i+1UL] - begin_[i];
1396 }
1397 //*************************************************************************************************
1398 
1399 
1400 //*************************************************************************************************
1405 template< typename Type // Data type of the matrix
1406  , bool SO > // Storage order
1408 {
1409  size_t nonzeros( 0UL );
1410 
1411  for( size_t i=0UL; i<m_; ++i )
1412  nonzeros += nonZeros( i );
1413 
1414  return nonzeros;
1415 }
1416 //*************************************************************************************************
1417 
1418 
1419 //*************************************************************************************************
1430 template< typename Type // Data type of the matrix
1431  , bool SO > // Storage order
1432 inline size_t CompressedMatrix<Type,SO>::nonZeros( size_t i ) const
1433 {
1434  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1435  return end_[i] - begin_[i];
1436 }
1437 //*************************************************************************************************
1438 
1439 
1440 //*************************************************************************************************
1445 template< typename Type // Data type of the matrix
1446  , bool SO > // Storage order
1448 {
1449  for( size_t i=0UL; i<m_; ++i )
1450  end_[i] = begin_[i];
1451 }
1452 //*************************************************************************************************
1453 
1454 
1455 //*************************************************************************************************
1466 template< typename Type // Data type of the matrix
1467  , bool SO > // Storage order
1468 inline void CompressedMatrix<Type,SO>::reset( size_t i )
1469 {
1470  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1471  end_[i] = begin_[i];
1472 }
1473 //*************************************************************************************************
1474 
1475 
1476 //*************************************************************************************************
1483 template< typename Type // Data type of the matrix
1484  , bool SO > // Storage order
1486 {
1487  if( end_ != nullptr )
1488  end_[0UL] = end_[m_];
1489  m_ = 0UL;
1490  n_ = 0UL;
1491 }
1492 //*************************************************************************************************
1493 
1494 
1495 //*************************************************************************************************
1510 template< typename Type // Data type of the matrix
1511  , bool SO > // Storage order
1512 void CompressedMatrix<Type,SO>::resize( size_t m, size_t n, bool preserve )
1513 {
1514  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1515  BLAZE_INTERNAL_ASSERT( begin_ == nullptr || size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1516 
1517  if( m == m_ && n == n_ ) return;
1518 
1519  if( begin_ == nullptr )
1520  {
1521  begin_ = new Iterator[2UL*m+2UL];
1522  end_ = begin_+m+1UL;
1523 
1524  for( size_t i=0UL; i<2UL*m+2UL; ++i ) {
1525  begin_[i] = nullptr;
1526  }
1527 
1528  capacity_ = m;
1529  }
1530  else if( m > capacity_ )
1531  {
1532  Iterator* newBegin( new Iterator[2UL*m+2UL] );
1533  Iterator* newEnd ( newBegin+m+1UL );
1534 
1535  newBegin[0UL] = begin_[0UL];
1536 
1537  if( preserve ) {
1538  for( size_t i=0UL; i<m_; ++i ) {
1539  newEnd [i] = end_ [i];
1540  newBegin[i+1UL] = begin_[i+1UL];
1541  }
1542  for( size_t i=m_; i<m; ++i ) {
1543  newBegin[i+1UL] = newEnd[i] = begin_[m_];
1544  }
1545  }
1546  else {
1547  for( size_t i=0UL; i<m; ++i ) {
1548  newBegin[i+1UL] = newEnd[i] = begin_[0UL];
1549  }
1550  }
1551 
1552  newEnd[m] = end_[m_];
1553 
1554  std::swap( newBegin, begin_ );
1555  delete[] newBegin;
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  }
1572  else
1573  {
1574  if( preserve ) {
1575  for( size_t i=0UL; i<m; ++i )
1576  end_[i] = lowerBound( i, n );
1577  }
1578  else {
1579  for( size_t i=0UL; i<m; ++i )
1580  end_[i] = begin_[i];
1581  }
1582 
1583  end_[m] = end_[m_];
1584  }
1585 
1586  m_ = m;
1587  n_ = n;
1588 
1589  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1590  BLAZE_INTERNAL_ASSERT( size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1591 }
1592 //*************************************************************************************************
1593 
1594 
1595 //*************************************************************************************************
1605 template< typename Type // Data type of the matrix
1606  , bool SO > // Storage order
1607 inline void CompressedMatrix<Type,SO>::reserve( size_t nonzeros )
1608 {
1609  if( nonzeros > capacity() )
1610  reserveElements( nonzeros );
1611 }
1612 //*************************************************************************************************
1613 
1614 
1615 //*************************************************************************************************
1629 template< typename Type // Data type of the matrix
1630  , bool SO > // Storage order
1631 void CompressedMatrix<Type,SO>::reserve( size_t i, size_t nonzeros )
1632 {
1633  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1634 
1635  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1636  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1637 
1638  const size_t current( capacity(i) );
1639 
1640  if( current >= nonzeros ) return;
1641 
1642  const ptrdiff_t additional( nonzeros - current );
1643 
1644  if( end_[m_] - begin_[m_] < additional )
1645  {
1646  const size_t newCapacity( begin_[m_] - begin_[0UL] + additional );
1647  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
1648 
1649  Iterator* newBegin( new Iterator[2UL*m_+2UL] );
1650  Iterator* newEnd ( newBegin+m_+1UL );
1651 
1652  newBegin[0UL] = allocate<Element>( newCapacity );
1653  newEnd [m_ ] = newBegin[0UL]+newCapacity;
1654 
1655  for( size_t k=0UL; k<i; ++k ) {
1656  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
1657  newBegin[k+1UL] = newBegin[k] + capacity(k);
1658  }
1659  newEnd [i ] = castDown( transfer( begin_[i], end_[i], castUp( newBegin[i] ) ) );
1660  newBegin[i+1UL] = newBegin[i] + nonzeros;
1661  for( size_t k=i+1UL; k<m_; ++k ) {
1662  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
1663  newBegin[k+1UL] = newBegin[k] + capacity(k);
1664  }
1665 
1666  BLAZE_INTERNAL_ASSERT( newBegin[m_] == newEnd[m_], "Invalid pointer calculations" );
1667 
1668  std::swap( newBegin, begin_ );
1669  deallocate( newBegin[0UL] );
1670  delete[] newBegin;
1671  end_ = newEnd;
1672  capacity_ = m_;
1673  }
1674  else
1675  {
1676  begin_[m_] += additional;
1677  for( size_t j=m_-1UL; j>i; --j ) {
1678  begin_[j] = castDown( std::move_backward( begin_[j], end_[j], castUp( end_[j]+additional ) ) );
1679  end_ [j] += additional;
1680  }
1681  }
1682 
1683  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1684  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1685 }
1686 //*************************************************************************************************
1687 
1688 
1689 //*************************************************************************************************
1699 template< typename Type // Data type of the matrix
1700  , bool SO > // Storage order
1702 {
1703  for( size_t i=0UL; i<m_; ++i )
1704  trim( i );
1705 }
1706 //*************************************************************************************************
1707 
1708 
1709 //*************************************************************************************************
1720 template< typename Type // Data type of the matrix
1721  , bool SO > // Storage order
1722 inline void CompressedMatrix<Type,SO>::trim( size_t i )
1723 {
1724  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1725 
1726  if( i < ( m_ - 1UL ) )
1727  end_[i+1] = castDown( std::move( begin_[i+1], end_[i+1], castUp( end_[i] ) ) );
1728  begin_[i+1] = end_[i];
1729 }
1730 //*************************************************************************************************
1731 
1732 
1733 //*************************************************************************************************
1739 template< typename Type // Data type of the matrix
1740  , bool SO > // Storage order
1742 {
1743  std::swap( m_, sm.m_ );
1744  std::swap( n_, sm.n_ );
1745  std::swap( capacity_, sm.capacity_ );
1746  std::swap( begin_, sm.begin_ );
1747  std::swap( end_ , sm.end_ );
1748 }
1749 //*************************************************************************************************
1750 
1751 
1752 //*************************************************************************************************
1760 template< typename Type // Data type of the matrix
1761  , bool SO > // Storage order
1762 inline size_t CompressedMatrix<Type,SO>::extendCapacity() const noexcept
1763 {
1764  size_t nonzeros( 2UL*capacity()+1UL );
1765  nonzeros = blaze::max( nonzeros, 7UL );
1766 
1767  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
1768 
1769  return nonzeros;
1770 }
1771 //*************************************************************************************************
1772 
1773 
1774 //*************************************************************************************************
1780 template< typename Type // Data type of the matrix
1781  , bool SO > // Storage order
1783 {
1784  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1785  Iterator* newEnd = newBegin+capacity_+1UL;
1786 
1787  newBegin[0UL] = allocate<Element>( nonzeros );
1788 
1789  for( size_t k=0UL; k<m_; ++k ) {
1790  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid row pointers" );
1791  newEnd [k] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
1792  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
1793  }
1794 
1795  newEnd[m_] = newBegin[0UL]+nonzeros;
1796 
1797  std::swap( newBegin, begin_ );
1798  end_ = newEnd;
1799 
1800  if( newBegin != nullptr ) {
1801  deallocate( newBegin[0UL] );
1802  delete[] newBegin;
1803  }
1804 }
1805 //*************************************************************************************************
1806 
1807 
1808 //*************************************************************************************************
1816 template< typename Type // Data type of the matrix
1817  , bool SO > // Storage order
1820 {
1821  return static_cast<Iterator>( it );
1822 }
1823 //*************************************************************************************************
1824 
1825 
1826 //*************************************************************************************************
1834 template< typename Type // Data type of the matrix
1835  , bool SO > // Storage order
1838 {
1839  return static_cast<IteratorBase>( it );
1840 }
1841 //*************************************************************************************************
1842 
1843 
1844 
1845 
1846 //=================================================================================================
1847 //
1848 // INSERTION FUNCTIONS
1849 //
1850 //=================================================================================================
1851 
1852 //*************************************************************************************************
1864 template< typename Type // Data type of the matrix
1865  , bool SO > // Storage order
1867  CompressedMatrix<Type,SO>::set( size_t i, size_t j, const Type& value )
1868 {
1869  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1870  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1871 
1872  const Iterator pos( lowerBound( i, j ) );
1873 
1874  if( pos != end_[i] && pos->index_ == j ) {
1875  pos->value() = value;
1876  return pos;
1877  }
1878  else return insert( pos, i, j, value );
1879 }
1880 //*************************************************************************************************
1881 
1882 
1883 //*************************************************************************************************
1896 template< typename Type // Data type of the matrix
1897  , bool SO > // Storage order
1899  CompressedMatrix<Type,SO>::insert( size_t i, size_t j, const Type& value )
1900 {
1901  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1902  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1903 
1904  const Iterator pos( lowerBound( i, j ) );
1905 
1906  if( pos != end_[i] && pos->index_ == j ) {
1907  BLAZE_THROW_INVALID_ARGUMENT( "Bad access index" );
1908  }
1909 
1910  return insert( pos, i, j, value );
1911 }
1912 //*************************************************************************************************
1913 
1914 
1915 //*************************************************************************************************
1925 template< typename Type // Data type of the matrix
1926  , bool SO > // Storage order
1928  CompressedMatrix<Type,SO>::insert( Iterator pos, size_t i, size_t j, const Type& value )
1929 {
1930  if( begin_[i+1UL] - end_[i] != 0 ) {
1931  std::move_backward( pos, end_[i], castUp( end_[i]+1UL ) );
1932  pos->value_ = value;
1933  pos->index_ = j;
1934  ++end_[i];
1935 
1936  return pos;
1937  }
1938  else if( end_[m_] - begin_[m_] != 0 ) {
1939  std::move_backward( pos, end_[m_-1UL], castUp( end_[m_-1UL]+1UL ) );
1940 
1941  pos->value_ = value;
1942  pos->index_ = j;
1943 
1944  for( size_t k=i+1UL; k<m_+1UL; ++k ) {
1945  ++begin_[k];
1946  ++end_[k-1UL];
1947  }
1948 
1949  return pos;
1950  }
1951  else {
1952  size_t newCapacity( extendCapacity() );
1953 
1954  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1955  Iterator* newEnd = newBegin+capacity_+1UL;
1956 
1957  newBegin[0UL] = allocate<Element>( newCapacity );
1958 
1959  for( size_t k=0UL; k<i; ++k ) {
1960  const size_t nonzeros( end_[k] - begin_[k] );
1961  const size_t total( begin_[k+1UL] - begin_[k] );
1962  newEnd [k] = newBegin[k] + nonzeros;
1963  newBegin[k+1UL] = newBegin[k] + total;
1964  }
1965  newEnd [i] = newBegin[i] + ( end_[i] - begin_[i] ) + 1;
1966  newBegin[i+1UL] = newBegin[i] + ( begin_[i+1] - begin_[i] ) + 1;
1967  for( size_t k=i+1UL; k<m_; ++k ) {
1968  const size_t nonzeros( end_[k] - begin_[k] );
1969  const size_t total( begin_[k+1UL] - begin_[k] );
1970  newEnd [k] = newBegin[k] + nonzeros;
1971  newBegin[k+1UL] = newBegin[k] + total;
1972  }
1973 
1974  newEnd[m_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
1975 
1976  Iterator tmp = castDown( std::move( begin_[0UL], pos, castUp( newBegin[0UL] ) ) );
1977  tmp->value_ = value;
1978  tmp->index_ = j;
1979  std::move( pos, end_[m_-1UL], castUp( tmp+1UL ) );
1980 
1981  std::swap( newBegin, begin_ );
1982  end_ = newEnd;
1983  deallocate( newBegin[0UL] );
1984  delete[] newBegin;
1985 
1986  return tmp;
1987  }
1988 }
1989 //*************************************************************************************************
1990 
1991 
1992 //*************************************************************************************************
2045 template< typename Type // Data type of the matrix
2046  , bool SO > // Storage order
2047 inline void CompressedMatrix<Type,SO>::append( size_t i, size_t j, const Type& value, bool check )
2048 {
2049  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2050  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
2051  BLAZE_USER_ASSERT( end_[i] < end_[m_], "Not enough reserved capacity left" );
2052  BLAZE_USER_ASSERT( begin_[i] == end_[i] || j > ( end_[i]-1UL )->index_, "Index is not strictly increasing" );
2053 
2054  end_[i]->value_ = value;
2055 
2056  if( !check || !isDefault<strict>( end_[i]->value_ ) ) {
2057  end_[i]->index_ = j;
2058  ++end_[i];
2059  }
2060 }
2061 //*************************************************************************************************
2062 
2063 
2064 //*************************************************************************************************
2077 template< typename Type // Data type of the matrix
2078  , bool SO > // Storage order
2080 {
2081  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2082 
2083  begin_[i+1UL] = end_[i];
2084  if( i != m_-1UL )
2085  end_[i+1UL] = end_[i];
2086 }
2087 //*************************************************************************************************
2088 
2089 
2090 
2091 
2092 //=================================================================================================
2093 //
2094 // ERASE FUNCTIONS
2095 //
2096 //=================================================================================================
2097 
2098 //*************************************************************************************************
2107 template< typename Type // Data type of the matrix
2108  , bool SO > // Storage order
2109 inline void CompressedMatrix<Type,SO>::erase( size_t i, size_t j )
2110 {
2111  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2112  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2113 
2114  const Iterator pos( find( i, j ) );
2115  if( pos != end_[i] )
2116  end_[i] = castDown( std::move( pos+1, end_[i], castUp( pos ) ) );
2117 }
2118 //*************************************************************************************************
2119 
2120 
2121 //*************************************************************************************************
2132 template< typename Type // Data type of the matrix
2133  , bool SO > // Storage order
2136 {
2137  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2138  BLAZE_USER_ASSERT( pos >= begin_[i] && pos <= end_[i], "Invalid compressed matrix iterator" );
2139 
2140  if( pos != end_[i] )
2141  end_[i] = castDown( std::move( pos+1, end_[i], castUp( pos ) ) );
2142 
2143  return pos;
2144 }
2145 //*************************************************************************************************
2146 
2147 
2148 //*************************************************************************************************
2160 template< typename Type // Data type of the matrix
2161  , bool SO > // Storage order
2164 {
2165  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2166  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
2167  BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i], "Invalid compressed matrix iterator" );
2168  BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i], "Invalid compressed matrix iterator" );
2169 
2170  if( first != last )
2171  end_[i] = castDown( std::move( last, end_[i], castUp( first ) ) );
2172 
2173  return first;
2174 }
2175 //*************************************************************************************************
2176 
2177 
2178 //*************************************************************************************************
2199 template< typename Type // Data type of the matrix
2200  , bool SO > // Storage order
2201 template< typename Pred > // Type of the unary predicate
2202 inline void CompressedMatrix<Type,SO>::erase( Pred predicate )
2203 {
2204  for( size_t i=0UL; i<m_; ++i ) {
2205  end_[i] = castDown( std::remove_if( castUp( begin_[i] ), castUp( end_[i] ),
2206  [predicate=predicate]( const ElementBase& element) {
2207  return predicate( element.value() );
2208  } ) );
2209  }
2210 }
2211 //*************************************************************************************************
2212 
2213 
2214 //*************************************************************************************************
2241 template< typename Type // Data type of the matrix
2242  , bool SO > // Storage order
2243 template< typename Pred > // Type of the unary predicate
2244 inline void CompressedMatrix<Type,SO>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
2245 {
2246  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2247  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
2248  BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i], "Invalid compressed matrix iterator" );
2249  BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i], "Invalid compressed matrix iterator" );
2250 
2251  const auto pos = std::remove_if( castUp( first ), castUp( last ),
2252  [predicate=predicate]( const ElementBase& element ) {
2253  return predicate( element.value() );
2254  } );
2255 
2256  end_[i] = castDown( std::move( last, end_[i], pos ) );
2257 }
2258 //*************************************************************************************************
2259 
2260 
2261 
2262 
2263 //=================================================================================================
2264 //
2265 // LOOKUP FUNCTIONS
2266 //
2267 //=================================================================================================
2268 
2269 //*************************************************************************************************
2284 template< typename Type // Data type of the matrix
2285  , bool SO > // Storage order
2287  CompressedMatrix<Type,SO>::find( size_t i, size_t j )
2288 {
2289  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
2290 }
2291 //*************************************************************************************************
2292 
2293 
2294 //*************************************************************************************************
2309 template< typename Type // Data type of the matrix
2310  , bool SO > // Storage order
2312  CompressedMatrix<Type,SO>::find( size_t i, size_t j ) const
2313 {
2314  const ConstIterator pos( lowerBound( i, j ) );
2315  if( pos != end_[i] && pos->index_ == j )
2316  return pos;
2317  else return end_[i];
2318 }
2319 //*************************************************************************************************
2320 
2321 
2322 //*************************************************************************************************
2337 template< typename Type // Data type of the matrix
2338  , bool SO > // Storage order
2341 {
2342  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
2343 }
2344 //*************************************************************************************************
2345 
2346 
2347 //*************************************************************************************************
2362 template< typename Type // Data type of the matrix
2363  , bool SO > // Storage order
2365  CompressedMatrix<Type,SO>::lowerBound( size_t i, size_t j ) const
2366 {
2367  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2368  return std::lower_bound( begin_[i], end_[i], j,
2369  []( const Element& element, size_t index )
2370  {
2371  return element.index() < index;
2372  } );
2373 }
2374 //*************************************************************************************************
2375 
2376 
2377 //*************************************************************************************************
2392 template< typename Type // Data type of the matrix
2393  , bool SO > // Storage order
2396 {
2397  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
2398 }
2399 //*************************************************************************************************
2400 
2401 
2402 //*************************************************************************************************
2417 template< typename Type // Data type of the matrix
2418  , bool SO > // Storage order
2420  CompressedMatrix<Type,SO>::upperBound( size_t i, size_t j ) const
2421 {
2422  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2423  return std::upper_bound( begin_[i], end_[i], j,
2424  []( size_t index, const Element& element )
2425  {
2426  return index < element.index();
2427  } );
2428 }
2429 //*************************************************************************************************
2430 
2431 
2432 
2433 
2434 //=================================================================================================
2435 //
2436 // NUMERIC FUNCTIONS
2437 //
2438 //=================================================================================================
2439 
2440 //*************************************************************************************************
2445 template< typename Type // Data type of the matrix
2446  , bool SO > // Storage order
2448 {
2449  CompressedMatrix tmp( trans( *this ) );
2450  swap( tmp );
2451  return *this;
2452 }
2453 //*************************************************************************************************
2454 
2455 
2456 //*************************************************************************************************
2461 template< typename Type // Data type of the matrix
2462  , bool SO > // Storage order
2464 {
2465  CompressedMatrix tmp( ctrans( *this ) );
2466  swap( tmp );
2467  return *this;
2468 }
2469 //*************************************************************************************************
2470 
2471 
2472 //*************************************************************************************************
2478 template< typename Type // Data type of the matrix
2479  , bool SO > // Storage order
2480 template< typename Other > // Data type of the scalar value
2482 {
2483  for( size_t i=0UL; i<m_; ++i )
2484  for( Iterator element=begin_[i]; element!=end_[i]; ++element )
2485  element->value_ *= scalar;
2486 
2487  return *this;
2488 }
2489 //*************************************************************************************************
2490 
2491 
2492 //*************************************************************************************************
2498 template< typename Type // Data type of the matrix
2499  , bool SO > // Storage order
2500 template< typename Other > // Data type of the scalar value
2502 {
2503  const size_t size( blaze::min( m_, n_ ) );
2504 
2505  for( size_t i=0UL; i<size; ++i ) {
2506  Iterator pos = lowerBound( i, i );
2507  if( pos != end_[i] && pos->index_ == i )
2508  pos->value_ *= scalar;
2509  }
2510 
2511  return *this;
2512 }
2513 //*************************************************************************************************
2514 
2515 
2516 
2517 
2518 //=================================================================================================
2519 //
2520 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2521 //
2522 //=================================================================================================
2523 
2524 //*************************************************************************************************
2534 template< typename Type // Data type of the matrix
2535  , bool SO > // Storage order
2536 template< typename Other > // Data type of the foreign expression
2537 inline bool CompressedMatrix<Type,SO>::canAlias( const Other* alias ) const noexcept
2538 {
2539  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2540 }
2541 //*************************************************************************************************
2542 
2543 
2544 //*************************************************************************************************
2554 template< typename Type // Data type of the matrix
2555  , bool SO > // Storage order
2556 template< typename Other > // Data type of the foreign expression
2557 inline bool CompressedMatrix<Type,SO>::isAliased( const Other* alias ) const noexcept
2558 {
2559  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2560 }
2561 //*************************************************************************************************
2562 
2563 
2564 //*************************************************************************************************
2574 template< typename Type // Data type of the matrix
2575  , bool SO > // Storage order
2576 inline bool CompressedMatrix<Type,SO>::canSMPAssign() const noexcept
2577 {
2578  return false;
2579 }
2580 //*************************************************************************************************
2581 
2582 
2583 //*************************************************************************************************
2594 template< typename Type // Data type of the matrix
2595  , bool SO > // Storage order
2596 template< typename MT // Type of the right-hand side dense matrix
2597  , bool SO2 > // Storage order of the right-hand side dense matrix
2599 {
2600  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2601  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2602 
2603  if( m_ == 0UL || n_ == 0UL )
2604  return;
2605 
2606  size_t nonzeros( 0UL );
2607 
2608  for( size_t i=1UL; i<=m_; ++i )
2609  begin_[i] = end_[i] = end_[m_];
2610 
2611  for( size_t i=0UL; i<m_; ++i )
2612  {
2613  begin_[i] = end_[i] = begin_[0UL]+nonzeros;
2614 
2615  const size_t jbegin( ( IsUpper<MT>::value )
2616  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2617  :( 0UL ) );
2618  const size_t jend ( ( IsLower<MT>::value )
2619  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2620  :( n_ ) );
2621 
2622  for( size_t j=jbegin; j<jend; ++j )
2623  {
2624  if( nonzeros == capacity() ) {
2626  for( size_t k=i+1UL; k<=m_; ++k )
2627  begin_[k] = end_[k] = end_[m_];
2628  }
2629 
2630  end_[i]->value_ = (~rhs)(i,j);
2631 
2632  if( !isDefault<strict>( end_[i]->value_ ) ) {
2633  end_[i]->index_ = j;
2634  ++end_[i];
2635  ++nonzeros;
2636  }
2637  }
2638  }
2639 
2640  begin_[m_] = begin_[0UL]+nonzeros;
2641 }
2642 //*************************************************************************************************
2643 
2644 
2645 //*************************************************************************************************
2656 template< typename Type // Data type of the matrix
2657  , bool SO > // Storage order
2658 template< typename MT > // Type of the right-hand side compressed matrix
2660 {
2661  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2662  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2663  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2664  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
2665 
2666  if( m_ == 0UL || begin_[0] == nullptr )
2667  return;
2668 
2669  for( size_t i=0UL; i<m_; ++i ) {
2670  end_[i] = castDown( std::copy( (~rhs).begin(i), (~rhs).end(i), castUp( begin_[i] ) ) );
2671  begin_[i+1UL] = end_[i];
2672  }
2673 }
2674 //*************************************************************************************************
2675 
2676 
2677 //*************************************************************************************************
2688 template< typename Type // Data type of the matrix
2689  , bool SO > // Storage order
2690 template< typename MT > // Type of the right-hand side compressed matrix
2692 {
2694 
2695  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2696  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2697  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2698  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
2699 
2700  typedef ConstIterator_<MT> RhsIterator;
2701 
2702  // Counting the number of elements per row
2703  std::vector<size_t> rowLengths( m_, 0UL );
2704  for( size_t j=0UL; j<n_; ++j ) {
2705  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2706  ++rowLengths[element->index()];
2707  }
2708 
2709  // Resizing the compressed matrix
2710  for( size_t i=0UL; i<m_; ++i ) {
2711  begin_[i+1UL] = end_[i+1UL] = begin_[i] + rowLengths[i];
2712  }
2713 
2714  // Appending the elements to the rows of the compressed matrix
2715  for( size_t j=0UL; j<n_; ++j ) {
2716  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2717  append( element->index(), j, element->value() );
2718  }
2719 }
2720 //*************************************************************************************************
2721 
2722 
2723 //*************************************************************************************************
2734 template< typename Type // Data type of the matrix
2735  , bool SO > // Storage order
2736 template< typename MT // Type of the right-hand side dense matrix
2737  , bool SO2 > // Storage order of the right-hand side dense matrix
2739 {
2740  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2741  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2742 
2743  CompressedMatrix tmp( serial( *this + (~rhs) ) );
2744  swap( tmp );
2745 }
2746 //*************************************************************************************************
2747 
2748 
2749 //*************************************************************************************************
2760 template< typename Type // Data type of the matrix
2761  , bool SO > // Storage order
2762 template< typename MT // Type of the right-hand side compressed matrix
2763  , bool SO2 > // Storage order of the right-hand side compressed matrix
2765 {
2766  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2767  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2768 
2769  CompressedMatrix tmp( serial( *this + (~rhs) ) );
2770  swap( tmp );
2771 }
2772 //*************************************************************************************************
2773 
2774 
2775 //*************************************************************************************************
2786 template< typename Type // Data type of the matrix
2787  , bool SO > // Storage order
2788 template< typename MT // Type of the right-hand side dense matrix
2789  , bool SO2 > // Storage order of the right-hand side dense matrix
2791 {
2792  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2793  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2794 
2795  CompressedMatrix tmp( serial( *this - (~rhs) ) );
2796  swap( tmp );
2797 }
2798 //*************************************************************************************************
2799 
2800 
2801 //*************************************************************************************************
2812 template< typename Type // Data type of the matrix
2813  , bool SO > // Storage order
2814 template< typename MT // Type of the right-hand side compressed matrix
2815  , bool SO2 > // Storage order of the right-hand compressed matrix
2817 {
2818  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2819  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2820 
2821  CompressedMatrix tmp( serial( *this - (~rhs) ) );
2822  swap( tmp );
2823 }
2824 //*************************************************************************************************
2825 
2826 
2827 
2828 
2829 
2830 
2831 
2832 
2833 //=================================================================================================
2834 //
2835 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2836 //
2837 //=================================================================================================
2838 
2839 //*************************************************************************************************
2847 template< typename Type > // Data type of the matrix
2848 class CompressedMatrix<Type,true> : public SparseMatrix< CompressedMatrix<Type,true>, true >
2849 {
2850  private:
2851  //**Type definitions****************************************************************************
2853  typedef ElementBase* IteratorBase;
2854  //**********************************************************************************************
2855 
2856  //**Private class Element***********************************************************************
2863  struct Element : public ElementBase
2864  {
2865  //**Constructors*****************************************************************************
2866  explicit Element() = default;
2867  Element( const Element& rhs ) = default;
2868  Element( Element&& rhs ) = default;
2869  //*******************************************************************************************
2870 
2871  //**Assignment operators*********************************************************************
2872  inline Element& operator=( const Element& rhs )
2873  {
2874  this->value_ = rhs.value_;
2875  return *this;
2876  }
2877 
2878  inline Element& operator=( Element&& rhs )
2879  {
2880  this->value_ = std::move( rhs.value_ );
2881  return *this;
2882  }
2883 
2884  template< typename Other >
2885  inline EnableIf_< IsSparseElement<Other>, Element& >
2886  operator=( const Other& rhs )
2887  {
2888  this->value_ = rhs.value();
2889  return *this;
2890  }
2891 
2892  template< typename Other >
2894  , IsRValueReference<Other&&> >, Element& >
2895  operator=( Other&& rhs )
2896  {
2897  this->value_ = std::move( rhs.value() );
2898  return *this;
2899  }
2900 
2901  template< typename Other >
2902  inline EnableIf_< Not< IsSparseElement<Other> >, Element& >
2903  operator=( const Other& v )
2904  {
2905  this->value_ = v;
2906  return *this;
2907  }
2908 
2909  template< typename Other >
2911  , IsRValueReference<Other&&> >, Element& >
2912  operator=( Other&& v )
2913  {
2914  this->value_ = std::move( v );
2915  return *this;
2916  }
2917  //*******************************************************************************************
2918 
2919  //**Friend declarations**********************************************************************
2920  friend class CompressedMatrix;
2921  //*******************************************************************************************
2922  };
2924  //**********************************************************************************************
2925 
2926  public:
2927  //**Type definitions****************************************************************************
2930  typedef This ResultType;
2933  typedef Type ElementType;
2934  typedef const Type& ReturnType;
2935  typedef const This& CompositeType;
2937  typedef const Type& ConstReference;
2938  typedef Element* Iterator;
2939  typedef const Element* ConstIterator;
2940  //**********************************************************************************************
2941 
2942  //**Rebind struct definition********************************************************************
2945  template< typename NewType > // Data type of the other matrix
2946  struct Rebind {
2948  };
2949  //**********************************************************************************************
2950 
2951  //**Resize struct definition********************************************************************
2954  template< size_t NewM // Number of rows of the other matrix
2955  , size_t NewN > // Number of columns of the other matrix
2956  struct Resize {
2958  };
2959  //**********************************************************************************************
2960 
2961  //**Compilation flags***************************************************************************
2963 
2966  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
2967  //**********************************************************************************************
2968 
2969  //**Constructors********************************************************************************
2972  explicit inline CompressedMatrix();
2973  explicit inline CompressedMatrix( size_t m, size_t n );
2974  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
2975  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
2976  inline CompressedMatrix( const CompressedMatrix& sm );
2977  inline CompressedMatrix( CompressedMatrix&& sm ) noexcept;
2978  template< typename MT, bool SO > inline CompressedMatrix( const DenseMatrix<MT,SO>& dm );
2979  template< typename MT, bool SO > inline CompressedMatrix( const SparseMatrix<MT,SO>& sm );
2981  //**********************************************************************************************
2982 
2983  //**Destructor**********************************************************************************
2986  inline ~CompressedMatrix();
2988  //**********************************************************************************************
2989 
2990  //**Data access functions***********************************************************************
2993  inline Reference operator()( size_t i, size_t j ) noexcept;
2994  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
2995  inline Reference at( size_t i, size_t j );
2996  inline ConstReference at( size_t i, size_t j ) const;
2997  inline Iterator begin ( size_t i ) noexcept;
2998  inline ConstIterator begin ( size_t i ) const noexcept;
2999  inline ConstIterator cbegin( size_t i ) const noexcept;
3000  inline Iterator end ( size_t i ) noexcept;
3001  inline ConstIterator end ( size_t i ) const noexcept;
3002  inline ConstIterator cend ( size_t i ) const noexcept;
3004  //**********************************************************************************************
3005 
3006  //**Assignment operators************************************************************************
3009  inline CompressedMatrix& operator=( const CompressedMatrix& rhs );
3010  inline CompressedMatrix& operator=( CompressedMatrix&& rhs ) noexcept;
3011 
3012  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO>& rhs );
3013  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO>& rhs );
3014  template< typename MT, bool SO > inline CompressedMatrix& operator+=( const Matrix<MT,SO>& rhs );
3015  template< typename MT, bool SO > inline CompressedMatrix& operator-=( const Matrix<MT,SO>& rhs );
3016  template< typename MT, bool SO > inline CompressedMatrix& operator*=( const Matrix<MT,SO>& rhs );
3017 
3018  template< typename Other >
3019  inline EnableIf_< IsNumeric<Other>, CompressedMatrix >& operator*=( Other rhs );
3020 
3021  template< typename Other >
3022  inline EnableIf_< IsNumeric<Other>, CompressedMatrix >& operator/=( Other rhs );
3024  //**********************************************************************************************
3025 
3026  //**Utility functions***************************************************************************
3029  inline size_t rows() const noexcept;
3030  inline size_t columns() const noexcept;
3031  inline size_t capacity() const noexcept;
3032  inline size_t capacity( size_t j ) const noexcept;
3033  inline size_t nonZeros() const;
3034  inline size_t nonZeros( size_t j ) const;
3035  inline void reset();
3036  inline void reset( size_t j );
3037  inline void clear();
3038  void resize ( size_t m, size_t n, bool preserve=true );
3039  inline void reserve( size_t nonzeros );
3040  void reserve( size_t j, size_t nonzeros );
3041  inline void trim ();
3042  inline void trim ( size_t j );
3043  inline void swap( CompressedMatrix& sm ) noexcept;
3045  //**********************************************************************************************
3046 
3047  //**Insertion functions*************************************************************************
3050  inline Iterator set ( size_t i, size_t j, const Type& value );
3051  inline Iterator insert ( size_t i, size_t j, const Type& value );
3052  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
3053  inline void finalize( size_t j );
3055  //**********************************************************************************************
3056 
3057  //**Erase functions*****************************************************************************
3060  inline void erase( size_t i, size_t j );
3061  inline Iterator erase( size_t j, Iterator pos );
3062  inline Iterator erase( size_t j, Iterator first, Iterator last );
3063 
3064  template< typename Pred >
3065  inline void erase( Pred predicate );
3066 
3067  template< typename Pred >
3068  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
3070  //**********************************************************************************************
3071 
3072  //**Lookup functions****************************************************************************
3075  inline Iterator find ( size_t i, size_t j );
3076  inline ConstIterator find ( size_t i, size_t j ) const;
3077  inline Iterator lowerBound( size_t i, size_t j );
3078  inline ConstIterator lowerBound( size_t i, size_t j ) const;
3079  inline Iterator upperBound( size_t i, size_t j );
3080  inline ConstIterator upperBound( size_t i, size_t j ) const;
3082  //**********************************************************************************************
3083 
3084  //**Numeric functions***************************************************************************
3087  inline CompressedMatrix& transpose();
3088  inline CompressedMatrix& ctranspose();
3089 
3090  template< typename Other > inline CompressedMatrix& scale( const Other& scalar );
3091  template< typename Other > inline CompressedMatrix& scaleDiagonal( const Other& scalar );
3093  //**********************************************************************************************
3094 
3095  //**Expression template evaluation functions****************************************************
3098  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3099  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3100 
3101  inline bool canSMPAssign() const noexcept;
3102 
3103  template< typename MT, bool SO > inline void assign ( const DenseMatrix<MT,SO>& rhs );
3104  template< typename MT > inline void assign ( const SparseMatrix<MT,true>& rhs );
3105  template< typename MT > inline void assign ( const SparseMatrix<MT,false>& rhs );
3106  template< typename MT, bool SO > inline void addAssign( const DenseMatrix<MT,SO>& rhs );
3107  template< typename MT, bool SO > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
3108  template< typename MT, bool SO > inline void subAssign( const DenseMatrix<MT,SO>& rhs );
3109  template< typename MT, bool SO > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
3111  //**********************************************************************************************
3112 
3113  private:
3114  //**Utility functions***************************************************************************
3117  inline size_t extendCapacity() const noexcept;
3118  void reserveElements( size_t nonzeros );
3119 
3120  inline Iterator castDown( IteratorBase it ) const noexcept;
3121  inline IteratorBase castUp ( Iterator it ) const noexcept;
3123  //**********************************************************************************************
3124 
3125  //**Insertion functions*************************************************************************
3128  Iterator insert( Iterator pos, size_t i, size_t j, const Type& value );
3130  //**********************************************************************************************
3131 
3132  //**Member variables****************************************************************************
3135  size_t m_;
3136  size_t n_;
3137  size_t capacity_;
3138  Iterator* begin_;
3139  Iterator* end_;
3140 
3141  static const Type zero_;
3142 
3143  //**********************************************************************************************
3144 
3145  //**Compile time checks*************************************************************************
3151  BLAZE_CONSTRAINT_MUST_HAVE_SAME_SIZE ( ElementBase, Element );
3153  //**********************************************************************************************
3154 };
3156 //*************************************************************************************************
3157 
3158 
3159 
3160 
3161 //=================================================================================================
3162 //
3163 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
3164 //
3165 //=================================================================================================
3166 
3167 template< typename Type >
3168 const Type CompressedMatrix<Type,true>::zero_ = Type();
3169 
3170 
3171 
3172 
3173 //=================================================================================================
3174 //
3175 // CONSTRUCTORS
3176 //
3177 //=================================================================================================
3178 
3179 //*************************************************************************************************
3183 template< typename Type > // Data type of the matrix
3185  : m_ ( 0UL ) // The current number of rows of the compressed matrix
3186  , n_ ( 0UL ) // The current number of columns of the compressed matrix
3187  , capacity_( 0UL ) // The current capacity of the pointer array
3188  , begin_ ( nullptr ) // Pointers to the first non-zero element of each column
3189  , end_ ( nullptr ) // Pointers one past the last non-zero element of each column
3190 {}
3192 //*************************************************************************************************
3193 
3194 
3195 //*************************************************************************************************
3204 template< typename Type > // Data type of the matrix
3205 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n )
3206  : m_ ( m ) // The current number of rows of the compressed matrix
3207  , n_ ( n ) // The current number of columns of the compressed matrix
3208  , capacity_( n ) // The current capacity of the pointer array
3209  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
3210  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
3211 {
3212  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
3213  begin_[j] = nullptr;
3214 }
3216 //*************************************************************************************************
3217 
3218 
3219 //*************************************************************************************************
3229 template< typename Type > // Data type of the matrix
3230 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
3231  : m_ ( m ) // The current number of rows of the compressed matrix
3232  , n_ ( n ) // The current number of columns of the compressed matrix
3233  , capacity_( n ) // The current capacity of the pointer array
3234  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
3235  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
3236 {
3237  begin_[0UL] = allocate<Element>( nonzeros );
3238  for( size_t j=1UL; j<(2UL*n_+1UL); ++j )
3239  begin_[j] = begin_[0UL];
3240  end_[n_] = begin_[0UL]+nonzeros;
3241 }
3243 //*************************************************************************************************
3244 
3245 
3246 //*************************************************************************************************
3257 template< typename Type > // Data type of the matrix
3258 CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
3259  : m_ ( m ) // The current number of rows of the compressed matrix
3260  , n_ ( n ) // The current number of columns of the compressed matrix
3261  , capacity_( n ) // The current capacity of the pointer array
3262  , begin_( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
3263  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
3264 {
3265  BLAZE_USER_ASSERT( nonzeros.size() == n, "Size of capacity vector and number of columns don't match" );
3266 
3267  size_t newCapacity( 0UL );
3268  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
3269  newCapacity += *it;
3270 
3271  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
3272  for( size_t j=0UL; j<n_; ++j ) {
3273  begin_[j+1UL] = end_[j+1UL] = begin_[j] + nonzeros[j];
3274  }
3275 }
3277 //*************************************************************************************************
3278 
3279 
3280 //*************************************************************************************************
3286 template< typename Type > // Data type of the matrix
3288  : m_ ( sm.m_ ) // The current number of rows of the compressed matrix
3289  , n_ ( sm.n_ ) // The current number of columns of the compressed matrix
3290  , capacity_( sm.n_ ) // The current capacity of the pointer array
3291  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
3292  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
3293 {
3294  const size_t nonzeros( sm.nonZeros() );
3295 
3296  begin_[0UL] = allocate<Element>( nonzeros );
3297  for( size_t j=0UL; j<n_; ++j ) {
3298  end_[j] = castDown( std::copy( sm.begin(j), sm.end(j), castUp( begin_[j] ) ) );
3299  begin_[j+1UL] = end_[j];
3300  }
3301  end_[n_] = begin_[0UL]+nonzeros;
3302 }
3304 //*************************************************************************************************
3305 
3306 
3307 //*************************************************************************************************
3313 template< typename Type > // Data type of the matrix
3315  : m_ ( sm.m_ ) // The current number of rows of the compressed matrix
3316  , n_ ( sm.n_ ) // The current number of columns of the compressed matrix
3317  , capacity_( sm.capacity_ ) // The current capacity of the pointer array
3318  , begin_ ( sm.begin_ ) // Pointers to the first non-zero element of each column
3319  , end_ ( sm.end_ ) // Pointers one past the last non-zero element of each column
3320 {
3321  sm.m_ = 0UL;
3322  sm.n_ = 0UL;
3323  sm.capacity_ = 0UL;
3324  sm.begin_ = nullptr;
3325  sm.end_ = nullptr;
3326 }
3328 //*************************************************************************************************
3329 
3330 
3331 //*************************************************************************************************
3337 template< typename Type > // Data type of the matrix
3338 template< typename MT // Type of the foreign dense matrix
3339  , bool SO > // Storage order of the foreign dense matrix
3341  : m_ ( (~dm).rows() ) // The current number of rows of the compressed matrix
3342  , n_ ( (~dm).columns() ) // The current number of columns of the compressed matrix
3343  , capacity_( n_ ) // The current capacity of the pointer array
3344  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
3345  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
3346 {
3347  using blaze::assign;
3348 
3349  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
3350  begin_[j] = nullptr;
3351 
3352  assign( *this, ~dm );
3353 }
3355 //*************************************************************************************************
3356 
3357 
3358 //*************************************************************************************************
3364 template< typename Type > // Data type of the matrix
3365 template< typename MT // Type of the foreign compressed matrix
3366  , bool SO > // Storage order of the foreign compressed matrix
3368  : m_ ( (~sm).rows() ) // The current number of rows of the compressed matrix
3369  , n_ ( (~sm).columns() ) // The current number of columns of the compressed matrix
3370  , capacity_( n_ ) // The current capacity of the pointer array
3371  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
3372  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
3373 {
3374  using blaze::assign;
3375 
3376  const size_t nonzeros( (~sm).nonZeros() );
3377 
3378  begin_[0UL] = allocate<Element>( nonzeros );
3379  for( size_t j=0UL; j<n_; ++j )
3380  begin_[j+1UL] = end_[j] = begin_[0UL];
3381  end_[n_] = begin_[0UL]+nonzeros;
3382 
3383  assign( *this, ~sm );
3384 }
3386 //*************************************************************************************************
3387 
3388 
3389 
3390 
3391 //=================================================================================================
3392 //
3393 // DESTRUCTOR
3394 //
3395 //=================================================================================================
3396 
3397 //*************************************************************************************************
3401 template< typename Type > // Data type of the matrix
3403 {
3404  if( begin_ != nullptr ) {
3405  deallocate( begin_[0UL] );
3406  delete[] begin_;
3407  }
3408 }
3410 //*************************************************************************************************
3411 
3412 
3413 
3414 
3415 //=================================================================================================
3416 //
3417 // DATA ACCESS FUNCTIONS
3418 //
3419 //=================================================================================================
3420 
3421 //*************************************************************************************************
3435 template< typename Type > // Data type of the matrix
3437  CompressedMatrix<Type,true>::operator()( size_t i, size_t j ) noexcept
3438 {
3439  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3440  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3441 
3442  return Reference( *this, i, j );
3443 }
3445 //*************************************************************************************************
3446 
3447 
3448 //*************************************************************************************************
3459 template< typename Type > // Data type of the matrix
3461  CompressedMatrix<Type,true>::operator()( size_t i, size_t j ) const noexcept
3462 {
3463  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3464  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3465 
3466  const ConstIterator pos( lowerBound( i, j ) );
3467 
3468  if( pos == end_[j] || pos->index_ != i )
3469  return zero_;
3470  else
3471  return pos->value_;
3472 }
3474 //*************************************************************************************************
3475 
3476 
3477 //*************************************************************************************************
3491 template< typename Type > // Data type of the matrix
3493  CompressedMatrix<Type,true>::at( size_t i, size_t j )
3494 {
3495  if( i >= m_ ) {
3496  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3497  }
3498  if( j >= n_ ) {
3499  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3500  }
3501  return (*this)(i,j);
3502 }
3504 //*************************************************************************************************
3505 
3506 
3507 //*************************************************************************************************
3519 template< typename Type > // Data type of the matrix
3521  CompressedMatrix<Type,true>::at( size_t i, size_t j ) const
3522 {
3523  if( i >= m_ ) {
3524  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3525  }
3526  if( j >= n_ ) {
3527  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3528  }
3529  return (*this)(i,j);
3530 }
3532 //*************************************************************************************************
3533 
3534 
3535 //*************************************************************************************************
3542 template< typename Type > // Data type of the matrix
3544  CompressedMatrix<Type,true>::begin( size_t j ) noexcept
3545 {
3546  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3547  return begin_[j];
3548 }
3550 //*************************************************************************************************
3551 
3552 
3553 //*************************************************************************************************
3560 template< typename Type > // Data type of the matrix
3562  CompressedMatrix<Type,true>::begin( size_t j ) const noexcept
3563 {
3564  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3565  return begin_[j];
3566 }
3568 //*************************************************************************************************
3569 
3570 
3571 //*************************************************************************************************
3578 template< typename Type > // Data type of the matrix
3580  CompressedMatrix<Type,true>::cbegin( size_t j ) const noexcept
3581 {
3582  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3583  return begin_[j];
3584 }
3586 //*************************************************************************************************
3587 
3588 
3589 //*************************************************************************************************
3596 template< typename Type > // Data type of the matrix
3598  CompressedMatrix<Type,true>::end( size_t j ) noexcept
3599 {
3600  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3601  return end_[j];
3602 }
3604 //*************************************************************************************************
3605 
3606 
3607 //*************************************************************************************************
3614 template< typename Type > // Data type of the matrix
3616  CompressedMatrix<Type,true>::end( size_t j ) const noexcept
3617 {
3618  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3619  return end_[j];
3620 }
3622 //*************************************************************************************************
3623 
3624 
3625 //*************************************************************************************************
3632 template< typename Type > // Data type of the matrix
3634  CompressedMatrix<Type,true>::cend( size_t j ) const noexcept
3635 {
3636  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3637  return end_[j];
3638 }
3640 //*************************************************************************************************
3641 
3642 
3643 
3644 
3645 //=================================================================================================
3646 //
3647 // ASSIGNMENT OPERATORS
3648 //
3649 //=================================================================================================
3650 
3651 //*************************************************************************************************
3661 template< typename Type > // Data type of the matrix
3664 {
3665  if( &rhs == this ) return *this;
3666 
3667  const size_t nonzeros( rhs.nonZeros() );
3668 
3669  if( rhs.n_ > capacity_ || nonzeros > capacity() )
3670  {
3671  Iterator* newBegin( new Iterator[2UL*rhs.n_+2UL] );
3672  Iterator* newEnd ( newBegin+(rhs.n_+1UL) );
3673 
3674  newBegin[0UL] = allocate<Element>( nonzeros );
3675  for( size_t j=0UL; j<rhs.n_; ++j ) {
3676  newEnd[j] = castDown( std::copy( rhs.begin_[j], rhs.end_[j], castUp( newBegin[j] ) ) );
3677  newBegin[j+1UL] = newEnd[j];
3678  }
3679  newEnd[rhs.n_] = newBegin[0UL]+nonzeros;
3680 
3681  std::swap( begin_, newBegin );
3682  end_ = newEnd;
3683  capacity_ = rhs.n_;
3684 
3685  if( newBegin != nullptr ) {
3686  deallocate( newBegin[0UL] );
3687  delete[] newBegin;
3688  }
3689  }
3690  else {
3691  for( size_t j=0UL; j<rhs.n_; ++j ) {
3692  end_[j] = castDown( std::copy( rhs.begin_[j], rhs.end_[j], castUp( begin_[j] ) ) );
3693  begin_[j+1UL] = end_[j];
3694  }
3695  }
3696 
3697  m_ = rhs.m_;
3698  n_ = rhs.n_;
3699 
3700  return *this;
3701 }
3703 //*************************************************************************************************
3704 
3705 
3706 //*************************************************************************************************
3713 template< typename Type > // Data type of the matrix
3716 {
3717  if( begin_ != nullptr ) {
3718  deallocate( begin_[0UL] );
3719  delete[] begin_;
3720  }
3721 
3722  m_ = rhs.m_;
3723  n_ = rhs.n_;
3724  capacity_ = rhs.capacity_;
3725  begin_ = rhs.begin_;
3726  end_ = rhs.end_;
3727 
3728  rhs.m_ = 0UL;
3729  rhs.n_ = 0UL;
3730  rhs.capacity_ = 0UL;
3731  rhs.begin_ = nullptr;
3732  rhs.end_ = nullptr;
3733 
3734  return *this;
3735 }
3737 //*************************************************************************************************
3738 
3739 
3740 //*************************************************************************************************
3750 template< typename Type > // Data type of the matrix
3751 template< typename MT // Type of the right-hand side dense matrix
3752  , bool SO > // Storage order of the right-hand side dense matrix
3755 {
3756  using blaze::assign;
3757 
3758  if( (~rhs).canAlias( this ) ) {
3759  CompressedMatrix tmp( ~rhs );
3760  swap( tmp );
3761  }
3762  else {
3763  resize( (~rhs).rows(), (~rhs).columns(), false );
3764  assign( *this, ~rhs );
3765  }
3766 
3767  return *this;
3768 }
3770 //*************************************************************************************************
3771 
3772 
3773 //*************************************************************************************************
3783 template< typename Type > // Data type of the matrix
3784 template< typename MT // Type of the right-hand side compressed matrix
3785  , bool SO > // Storage order of the right-hand side compressed matrix
3788 {
3789  using blaze::assign;
3790 
3791  if( (~rhs).canAlias( this ) ||
3792  (~rhs).columns() > capacity_ ||
3793  (~rhs).nonZeros() > capacity() ) {
3794  CompressedMatrix tmp( ~rhs );
3795  swap( tmp );
3796  }
3797  else {
3798  resize( (~rhs).rows(), (~rhs).columns(), false );
3799  reset();
3800  assign( *this, ~rhs );
3801  }
3802 
3803  return *this;
3804 }
3806 //*************************************************************************************************
3807 
3808 
3809 //*************************************************************************************************
3820 template< typename Type > // Data type of the matrix
3821 template< typename MT // Type of the right-hand side matrix
3822  , bool SO > // Storage order of the right-hand side matrix
3824 {
3825  using blaze::addAssign;
3826 
3827  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
3828  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3829  }
3830 
3831  addAssign( *this, ~rhs );
3832  return *this;
3833 }
3835 //*************************************************************************************************
3836 
3837 
3838 //*************************************************************************************************
3849 template< typename Type > // Data type of the matrix
3850 template< typename MT // Type of the right-hand side matrix
3851  , bool SO > // Storage order of the right-hand side matrix
3853 {
3854  using blaze::subAssign;
3855 
3856  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
3857  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3858  }
3859 
3860  subAssign( *this, ~rhs );
3861  return *this;
3862 }
3864 //*************************************************************************************************
3865 
3866 
3867 //*************************************************************************************************
3878 template< typename Type > // Data type of the matrix
3879 template< typename MT // Type of the right-hand side matrix
3880  , bool SO > // Storage order of the right-hand side matrix
3883 {
3884  if( (~rhs).rows() != n_ ) {
3885  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3886  }
3887 
3888  CompressedMatrix tmp( *this * (~rhs) );
3889  swap( tmp );
3890 
3891  return *this;
3892 }
3894 //*************************************************************************************************
3895 
3896 
3897 //*************************************************************************************************
3905 template< typename Type > // Data type of the matrix
3906 template< typename Other > // Data type of the right-hand side scalar
3907 inline EnableIf_< IsNumeric<Other>, CompressedMatrix<Type,true> >&
3909 {
3910  for( size_t j=0UL; j<n_; ++j ) {
3911  const Iterator last( end(j) );
3912  for( Iterator element=begin(j); element!=last; ++element )
3913  element->value_ *= rhs;
3914  }
3915  return *this;
3916 }
3918 //*************************************************************************************************
3919 
3920 
3921 //*************************************************************************************************
3929 template< typename Type > // Data type of the matrix
3930 template< typename Other > // Data type of the right-hand side scalar
3931 inline EnableIf_< IsNumeric<Other>, CompressedMatrix<Type,true> >&
3932  CompressedMatrix<Type,true>::operator/=( Other rhs )
3933 {
3934  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3935 
3936  typedef DivTrait_<Type,Other> DT;
3937  typedef If_< IsNumeric<DT>, DT, Other > Tmp;
3938 
3939  // Depending on the two involved data types, an integer division is applied or a
3940  // floating point division is selected.
3941  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
3942  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
3943  for( size_t j=0UL; j<n_; ++j ) {
3944  const Iterator last( end(j) );
3945  for( Iterator element=begin(j); element!=last; ++element )
3946  element->value_ *= tmp;
3947  }
3948  }
3949  else {
3950  for( size_t j=0UL; j<n_; ++j ) {
3951  const Iterator last( end(j) );
3952  for( Iterator element=begin(j); element!=last; ++element )
3953  element->value_ /= rhs;
3954  }
3955  }
3956 
3957  return *this;
3958 }
3960 //*************************************************************************************************
3961 
3962 
3963 
3964 
3965 //=================================================================================================
3966 //
3967 // UTILITY FUNCTIONS
3968 //
3969 //=================================================================================================
3970 
3971 //*************************************************************************************************
3977 template< typename Type > // Data type of the matrix
3978 inline size_t CompressedMatrix<Type,true>::rows() const noexcept
3979 {
3980  return m_;
3981 }
3983 //*************************************************************************************************
3984 
3985 
3986 //*************************************************************************************************
3992 template< typename Type > // Data type of the matrix
3993 inline size_t CompressedMatrix<Type,true>::columns() const noexcept
3994 {
3995  return n_;
3996 }
3998 //*************************************************************************************************
3999 
4000 
4001 //*************************************************************************************************
4007 template< typename Type > // Data type of the matrix
4008 inline size_t CompressedMatrix<Type,true>::capacity() const noexcept
4009 {
4010  if( begin_ != nullptr )
4011  return end_[n_] - begin_[0UL];
4012  else return 0UL;
4013 }
4015 //*************************************************************************************************
4016 
4017 
4018 //*************************************************************************************************
4025 template< typename Type > // Data type of the matrix
4026 inline size_t CompressedMatrix<Type,true>::capacity( size_t j ) const noexcept
4027 {
4028  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4029  return begin_[j+1UL] - begin_[j];
4030 }
4032 //*************************************************************************************************
4033 
4034 
4035 //*************************************************************************************************
4041 template< typename Type > // Data type of the matrix
4042 inline size_t CompressedMatrix<Type,true>::nonZeros() const
4043 {
4044  size_t nonzeros( 0UL );
4045 
4046  for( size_t j=0UL; j<n_; ++j )
4047  nonzeros += nonZeros( j );
4048 
4049  return nonzeros;
4050 }
4052 //*************************************************************************************************
4053 
4054 
4055 //*************************************************************************************************
4062 template< typename Type > // Data type of the matrix
4063 inline size_t CompressedMatrix<Type,true>::nonZeros( size_t j ) const
4064 {
4065  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4066  return end_[j] - begin_[j];
4067 }
4069 //*************************************************************************************************
4070 
4071 
4072 //*************************************************************************************************
4078 template< typename Type > // Data type of the matrix
4080 {
4081  for( size_t j=0UL; j<n_; ++j )
4082  end_[j] = begin_[j];
4083 }
4085 //*************************************************************************************************
4086 
4087 
4088 //*************************************************************************************************
4098 template< typename Type > // Data type of the matrix
4099 inline void CompressedMatrix<Type,true>::reset( size_t j )
4100 {
4101  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4102  end_[j] = begin_[j];
4103 }
4105 //*************************************************************************************************
4106 
4107 
4108 //*************************************************************************************************
4116 template< typename Type > // Data type of the matrix
4118 {
4119  if( end_ != nullptr )
4120  end_[0UL] = end_[n_];
4121  m_ = 0UL;
4122  n_ = 0UL;
4123 }
4125 //*************************************************************************************************
4126 
4127 
4128 //*************************************************************************************************
4144 template< typename Type > // Data type of the matrix
4145 void CompressedMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
4146 {
4147  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4148  BLAZE_INTERNAL_ASSERT( begin_ == nullptr || size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4149 
4150  if( m == m_ && n == n_ ) return;
4151 
4152  if( begin_ == nullptr )
4153  {
4154  begin_ = new Iterator[2UL*n+2UL];
4155  end_ = begin_+n+1UL;
4156 
4157  for( size_t j=0UL; j<2UL*n+2UL; ++j ) {
4158  begin_[j] = nullptr;
4159  }
4160 
4161  capacity_ = n;
4162  }
4163  else if( n > capacity_ )
4164  {
4165  Iterator* newBegin( new Iterator[2UL*n+2UL] );
4166  Iterator* newEnd ( newBegin+n+1UL );
4167 
4168  newBegin[0UL] = begin_[0UL];
4169 
4170  if( preserve ) {
4171  for( size_t j=0UL; j<n_; ++j ) {
4172  newEnd [j] = end_ [j];
4173  newBegin[j+1UL] = begin_[j+1UL];
4174  }
4175  for( size_t j=n_; j<n; ++j ) {
4176  newBegin[j+1UL] = newEnd[j] = begin_[n_];
4177  }
4178  }
4179  else {
4180  for( size_t j=0UL; j<n; ++j ) {
4181  newBegin[j+1UL] = newEnd[j] = begin_[0UL];
4182  }
4183  }
4184 
4185  newEnd[n] = end_[n_];
4186 
4187  std::swap( newBegin, begin_ );
4188  delete[] newBegin;
4189  end_ = newEnd;
4190  capacity_ = n;
4191  }
4192  else if( n > n_ )
4193  {
4194  end_[n] = end_[n_];
4195 
4196  if( !preserve ) {
4197  for( size_t j=0UL; j<n_; ++j )
4198  end_[j] = begin_[j];
4199  }
4200 
4201  for( size_t j=n_; j<n; ++j ) {
4202  begin_[j+1UL] = end_[j] = begin_[n_];
4203  }
4204  }
4205  else
4206  {
4207  if( preserve ) {
4208  for( size_t j=0UL; j<n; ++j )
4209  end_[j] = lowerBound( m, j );
4210  }
4211  else {
4212  for( size_t j=0UL; j<n; ++j )
4213  end_[j] = begin_[j];
4214  }
4215 
4216  end_[n] = end_[n_];
4217  }
4218 
4219  m_ = m;
4220  n_ = n;
4221 
4222  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4223  BLAZE_INTERNAL_ASSERT( size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4224 }
4226 //*************************************************************************************************
4227 
4228 
4229 //*************************************************************************************************
4240 template< typename Type > // Data type of the matrix
4241 inline void CompressedMatrix<Type,true>::reserve( size_t nonzeros )
4242 {
4243  if( nonzeros > capacity() )
4244  reserveElements( nonzeros );
4245 }
4247 //*************************************************************************************************
4248 
4249 
4250 //*************************************************************************************************
4262 template< typename Type > // Data type of the matrix
4263 void CompressedMatrix<Type,true>::reserve( size_t j, size_t nonzeros )
4264 {
4265  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4266 
4267  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4268  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4269 
4270  const size_t current( capacity(j) );
4271 
4272  if( current >= nonzeros ) return;
4273 
4274  const ptrdiff_t additional( nonzeros - current );
4275 
4276  if( end_[n_] - begin_[n_] < additional )
4277  {
4278  const size_t newCapacity( begin_[n_] - begin_[0UL] + additional );
4279  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
4280 
4281  Iterator* newBegin( new Iterator[2UL*n_+2UL] );
4282  Iterator* newEnd ( newBegin+n_+1UL );
4283 
4284  newBegin[0UL] = allocate<Element>( newCapacity );
4285  newEnd [n_ ] = newBegin[0UL]+newCapacity;
4286 
4287  for( size_t k=0UL; k<j; ++k ) {
4288  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4289  newBegin[k+1UL] = newBegin[k] + capacity(k);
4290  }
4291  newEnd [j ] = castDown( transfer( begin_[j], end_[j], castUp( newBegin[j] ) ) );
4292  newBegin[j+1UL] = newBegin[j] + nonzeros;
4293  for( size_t k=j+1UL; k<n_; ++k ) {
4294  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4295  newBegin[k+1UL] = newBegin[k] + capacity(k);
4296  }
4297 
4298  BLAZE_INTERNAL_ASSERT( newBegin[n_] == newEnd[n_], "Invalid pointer calculations" );
4299 
4300  std::swap( newBegin, begin_ );
4301  deallocate( newBegin[0UL] );
4302  delete[] newBegin;
4303  end_ = newEnd;
4304  capacity_ = n_;
4305  }
4306  else
4307  {
4308  begin_[n_] += additional;
4309  for( size_t k=n_-1UL; k>j; --k ) {
4310  begin_[k] = castDown( std::move_backward( begin_[k], end_[k], castUp( end_[k]+additional ) ) );
4311  end_ [k] += additional;
4312  }
4313  }
4314 
4315  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4316  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4317 }
4319 //*************************************************************************************************
4320 
4321 
4322 //*************************************************************************************************
4332 template< typename Type > // Data type of the matrix
4334 {
4335  for( size_t j=0UL; j<n_; ++j )
4336  trim( j );
4337 }
4339 //*************************************************************************************************
4340 
4341 
4342 //*************************************************************************************************
4353 template< typename Type > // Data type of the matrix
4354 void CompressedMatrix<Type,true>::trim( size_t j )
4355 {
4356  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4357 
4358  if( j < ( n_ - 1UL ) )
4359  end_[j+1] = castDown( std::move( begin_[j+1], end_[j+1], castUp( end_[j] ) ) );
4360  begin_[j+1] = end_[j];
4361 }
4363 //*************************************************************************************************
4364 
4365 
4366 //*************************************************************************************************
4373 template< typename Type > // Data type of the matrix
4374 inline void CompressedMatrix<Type,true>::swap( CompressedMatrix& sm ) noexcept
4375 {
4376  std::swap( m_, sm.m_ );
4377  std::swap( n_, sm.n_ );
4378  std::swap( capacity_, sm.capacity_ );
4379  std::swap( begin_, sm.begin_ );
4380  std::swap( end_ , sm.end_ );
4381 }
4383 //*************************************************************************************************
4384 
4385 
4386 //*************************************************************************************************
4395 template< typename Type > // Data type of the matrix
4396 inline size_t CompressedMatrix<Type,true>::extendCapacity() const noexcept
4397 {
4398  size_t nonzeros( 2UL*capacity()+1UL );
4399  nonzeros = blaze::max( nonzeros, 7UL );
4400 
4401  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
4402 
4403  return nonzeros;
4404 }
4406 //*************************************************************************************************
4407 
4408 
4409 //*************************************************************************************************
4416 template< typename Type > // Data type of the matrix
4417 void CompressedMatrix<Type,true>::reserveElements( size_t nonzeros )
4418 {
4419  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
4420  Iterator* newEnd = newBegin+capacity_+1UL;
4421 
4422  newBegin[0UL] = allocate<Element>( nonzeros );
4423 
4424  for( size_t k=0UL; k<n_; ++k ) {
4425  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid column pointers" );
4426  newEnd [k] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4427  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
4428  }
4429 
4430  newEnd[n_] = newBegin[0UL]+nonzeros;
4431 
4432  std::swap( newBegin, begin_ );
4433  end_ = newEnd;
4434 
4435  if( newBegin != nullptr ) {
4436  deallocate( newBegin[0UL] );
4437  delete[] newBegin;
4438  }
4439 }
4441 //*************************************************************************************************
4442 
4443 
4444 //*************************************************************************************************
4452 template< typename Type > // Data type of the matrix
4454  CompressedMatrix<Type,true>::castDown( IteratorBase it ) const noexcept
4455 {
4456  return static_cast<Iterator>( it );
4457 }
4458 //*************************************************************************************************
4459 
4460 
4461 //*************************************************************************************************
4469 template< typename Type > // Data type of the matrix
4471  CompressedMatrix<Type,true>::castUp( Iterator it ) const noexcept
4472 {
4473  return static_cast<IteratorBase>( it );
4474 }
4475 //*************************************************************************************************
4476 
4477 
4478 
4479 
4480 //=================================================================================================
4481 //
4482 // INSERTION FUNCTIONS
4483 //
4484 //=================================================================================================
4485 
4486 //*************************************************************************************************
4499 template< typename Type > // Data type of the matrix
4501  CompressedMatrix<Type,true>::set( size_t i, size_t j, const Type& value )
4502 {
4503  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4504  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4505 
4506  const Iterator pos( lowerBound( i, j ) );
4507 
4508  if( pos != end_[j] && pos->index_ == i ) {
4509  pos->value() = value;
4510  return pos;
4511  }
4512  else return insert( pos, i, j, value );
4513 }
4515 //*************************************************************************************************
4516 
4517 
4518 //*************************************************************************************************
4532 template< typename Type > // Data type of the matrix
4534  CompressedMatrix<Type,true>::insert( size_t i, size_t j, const Type& value )
4535 {
4536  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4537  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4538 
4539  const Iterator pos( lowerBound( i, j ) );
4540 
4541  if( pos != end_[j] && pos->index_ == i ) {
4542  BLAZE_THROW_INVALID_ARGUMENT( "Bad access index" );
4543  }
4544 
4545  return insert( pos, i, j, value );
4546 }
4548 //*************************************************************************************************
4549 
4550 
4551 //*************************************************************************************************
4562 template< typename Type > // Data type of the matrix
4564  CompressedMatrix<Type,true>::insert( Iterator pos, size_t i, size_t j, const Type& value )
4565 {
4566  if( begin_[j+1UL] - end_[j] != 0 ) {
4567  std::move_backward( pos, end_[j], castUp( end_[j]+1UL ) );
4568  pos->value_ = value;
4569  pos->index_ = i;
4570  ++end_[j];
4571 
4572  return pos;
4573  }
4574  else if( end_[n_] - begin_[n_] != 0 ) {
4575  std::move_backward( pos, end_[n_-1UL], castUp( end_[n_-1]+1UL ) );
4576 
4577  pos->value_ = value;
4578  pos->index_ = i;
4579 
4580  for( size_t k=j+1UL; k<n_+1UL; ++k ) {
4581  ++begin_[k];
4582  ++end_[k-1UL];
4583  }
4584 
4585  return pos;
4586  }
4587  else {
4588  size_t newCapacity( extendCapacity() );
4589 
4590  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
4591  Iterator* newEnd = newBegin+capacity_+1UL;
4592 
4593  newBegin[0UL] = allocate<Element>( newCapacity );
4594 
4595  for( size_t k=0UL; k<j; ++k ) {
4596  const size_t nonzeros( end_[k] - begin_[k] );
4597  const size_t total( begin_[k+1UL] - begin_[k] );
4598  newEnd [k] = newBegin[k] + nonzeros;
4599  newBegin[k+1UL] = newBegin[k] + total;
4600  }
4601  newEnd [j] = newBegin[j] + ( end_[j] - begin_[j] ) + 1;
4602  newBegin[j+1UL] = newBegin[j] + ( begin_[j+1UL] - begin_[j] ) + 1;
4603  for( size_t k=j+1UL; k<n_; ++k ) {
4604  const size_t nonzeros( end_[k] - begin_[k] );
4605  const size_t total( begin_[k+1UL] - begin_[k] );
4606  newEnd [k] = newBegin[k] + nonzeros;
4607  newBegin[k+1UL] = newBegin[k] + total;
4608  }
4609 
4610  newEnd[n_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
4611 
4612  Iterator tmp = castDown( std::move( begin_[0UL], pos, castUp( newBegin[0UL] ) ) );
4613  tmp->value_ = value;
4614  tmp->index_ = i;
4615  std::move( pos, end_[n_-1UL], castUp( tmp+1UL ) );
4616 
4617  std::swap( newBegin, begin_ );
4618  end_ = newEnd;
4619  deallocate( newBegin[0UL] );
4620  delete[] newBegin;
4621 
4622  return tmp;
4623  }
4624 }
4626 //*************************************************************************************************
4627 
4628 
4629 //*************************************************************************************************
4682 template< typename Type > // Data type of the matrix
4683 inline void CompressedMatrix<Type,true>::append( size_t i, size_t j, const Type& value, bool check )
4684 {
4685  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
4686  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
4687  BLAZE_USER_ASSERT( end_[j] < end_[n_], "Not enough reserved capacity left" );
4688  BLAZE_USER_ASSERT( begin_[j] == end_[j] || i > ( end_[j]-1UL )->index_, "Index is not strictly increasing" );
4689 
4690  end_[j]->value_ = value;
4691 
4692  if( !check || !isDefault<strict>( end_[j]->value_ ) ) {
4693  end_[j]->index_ = i;
4694  ++end_[j];
4695  }
4696 }
4698 //*************************************************************************************************
4699 
4700 
4701 //*************************************************************************************************
4715 template< typename Type > // Data type of the matrix
4716 inline void CompressedMatrix<Type,true>::finalize( size_t j )
4717 {
4718  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
4719 
4720  begin_[j+1UL] = end_[j];
4721  if( j != n_-1UL )
4722  end_[j+1UL] = end_[j];
4723 }
4725 //*************************************************************************************************
4726 
4727 
4728 
4729 
4730 //=================================================================================================
4731 //
4732 // ERASE FUNCTIONS
4733 //
4734 //=================================================================================================
4735 
4736 //*************************************************************************************************
4746 template< typename Type > // Data type of the matrix
4747 inline void CompressedMatrix<Type,true>::erase( size_t i, size_t j )
4748 {
4749  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4750  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4751 
4752  const Iterator pos( find( i, j ) );
4753  if( pos != end_[j] )
4754  end_[j] = castDown( std::move( pos+1, end_[j], castUp( pos ) ) );
4755 }
4757 //*************************************************************************************************
4758 
4759 
4760 //*************************************************************************************************
4770 template< typename Type > // Data type of the matrix
4773 {
4774  BLAZE_USER_ASSERT( j < columns() , "Invalid column access index" );
4775  BLAZE_USER_ASSERT( pos >= begin_[j] && pos <= end_[j], "Invalid compressed matrix iterator" );
4776 
4777  if( pos != end_[j] )
4778  end_[j] = castDown( std::move( pos+1, end_[j], castUp( pos ) ) );
4779 
4780  return pos;
4781 }
4783 //*************************************************************************************************
4784 
4785 
4786 //*************************************************************************************************
4797 template< typename Type > // Data type of the matrix
4799  CompressedMatrix<Type,true>::erase( size_t j, Iterator first, Iterator last )
4800 {
4801  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4802  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
4803  BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j], "Invalid compressed matrix iterator" );
4804  BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j], "Invalid compressed matrix iterator" );
4805 
4806  if( first != last )
4807  end_[j] = castDown( std::move( last, end_[j], castUp( first ) ) );
4808 
4809  return first;
4810 }
4812 //*************************************************************************************************
4813 
4814 
4815 //*************************************************************************************************
4837 template< typename Type > // Data type of the matrix
4838 template< typename Pred > // Type of the unary predicate
4839 inline void CompressedMatrix<Type,true>::erase( Pred predicate )
4840 {
4841  for( size_t j=0UL; j<n_; ++j ) {
4842  end_[j] = castDown( std::remove_if( castUp( begin_[j] ), castUp( end_[j] ),
4843  [predicate=predicate]( const ElementBase& element ) {
4844  return predicate( element.value() );
4845  } ) );
4846  }
4847 }
4849 //*************************************************************************************************
4850 
4851 
4852 //*************************************************************************************************
4877 template< typename Type > // Data type of the matrix
4878 template< typename Pred > // Type of the unary predicate
4879 inline void CompressedMatrix<Type,true>::erase( size_t j, Iterator first, Iterator last, Pred predicate )
4880 {
4881  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4882  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
4883  BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j], "Invalid compressed matrix iterator" );
4884  BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j], "Invalid compressed matrix iterator" );
4885 
4886  const auto pos = std::remove_if( castUp( first ), castUp( last ),
4887  [predicate=predicate]( const ElementBase& element ) {
4888  return predicate( element.value() );
4889  } );
4890 
4891  end_[j] = castDown( std::move( last, end_[j], pos ) );
4892 }
4894 //*************************************************************************************************
4895 
4896 
4897 
4898 
4899 //=================================================================================================
4900 //
4901 // LOOKUP FUNCTIONS
4902 //
4903 //=================================================================================================
4904 
4905 //*************************************************************************************************
4920 template< typename Type > // Data type of the matrix
4922  CompressedMatrix<Type,true>::find( size_t i, size_t j )
4923 {
4924  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
4925 }
4927 //*************************************************************************************************
4928 
4929 
4930 //*************************************************************************************************
4945 template< typename Type > // Data type of the matrix
4947  CompressedMatrix<Type,true>::find( size_t i, size_t j ) const
4948 {
4949  const ConstIterator pos( lowerBound( i, j ) );
4950  if( pos != end_[j] && pos->index_ == i )
4951  return pos;
4952  else return end_[j];
4953 }
4955 //*************************************************************************************************
4956 
4957 
4958 //*************************************************************************************************
4972 template< typename Type > // Data type of the matrix
4974  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j )
4975 {
4976  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
4977 }
4979 //*************************************************************************************************
4980 
4981 
4982 //*************************************************************************************************
4996 template< typename Type > // Data type of the matrix
4998  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j ) const
4999 {
5000  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5001  return std::lower_bound( begin_[j], end_[j], i,
5002  []( const Element& element, size_t index )
5003  {
5004  return element.index() < index;
5005  } );
5006 }
5008 //*************************************************************************************************
5009 
5010 
5011 //*************************************************************************************************
5025 template< typename Type > // Data type of the matrix
5027  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j )
5028 {
5029  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
5030 }
5032 //*************************************************************************************************
5033 
5034 
5035 //*************************************************************************************************
5049 template< typename Type > // Data type of the matrix
5051  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j ) const
5052 {
5053  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5054  return std::upper_bound( begin_[j], end_[j], i,
5055  []( size_t index, const Element& element )
5056  {
5057  return index < element.index();
5058  } );
5059 }
5061 //*************************************************************************************************
5062 
5063 
5064 
5065 
5066 //=================================================================================================
5067 //
5068 // NUMERIC FUNCTIONS
5069 //
5070 //=================================================================================================
5071 
5072 //*************************************************************************************************
5078 template< typename Type > // Data type of the matrix
5079 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::transpose()
5080 {
5081  CompressedMatrix tmp( trans( *this ) );
5082  swap( tmp );
5083  return *this;
5084 }
5086 //*************************************************************************************************
5087 
5088 
5089 //*************************************************************************************************
5095 template< typename Type > // Data type of the matrix
5096 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::ctranspose()
5097 {
5098  CompressedMatrix tmp( ctrans( *this ) );
5099  swap( tmp );
5100  return *this;
5101 }
5103 //*************************************************************************************************
5104 
5105 
5106 //*************************************************************************************************
5113 template< typename Type > // Data type of the matrix
5114 template< typename Other > // Data type of the scalar value
5115 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scale( const Other& scalar )
5116 {
5117  for( size_t j=0UL; j<n_; ++j )
5118  for( Iterator element=begin_[j]; element!=end_[j]; ++element )
5119  element->value_ *= scalar;
5120 
5121  return *this;
5122 }
5124 //*************************************************************************************************
5125 
5126 
5127 //*************************************************************************************************
5134 template< typename Type > // Data type of the matrix
5135 template< typename Other > // Data type of the scalar value
5136 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scaleDiagonal( const Other& scalar )
5137 {
5138  const size_t size( blaze::min( m_, n_ ) );
5139 
5140  for( size_t j=0UL; j<size; ++j ) {
5141  Iterator pos = lowerBound( j, j );
5142  if( pos != end_[j] && pos->index_ == j )
5143  pos->value_ *= scalar;
5144  }
5145 
5146  return *this;
5147 }
5149 //*************************************************************************************************
5150 
5151 
5152 
5153 
5154 //=================================================================================================
5155 //
5156 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5157 //
5158 //=================================================================================================
5159 
5160 //*************************************************************************************************
5171 template< typename Type > // Data type of the matrix
5172 template< typename Other > // Data type of the foreign expression
5173 inline bool CompressedMatrix<Type,true>::canAlias( const Other* alias ) const noexcept
5174 {
5175  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5176 }
5178 //*************************************************************************************************
5179 
5180 
5181 //*************************************************************************************************
5192 template< typename Type > // Data type of the matrix
5193 template< typename Other > // Data type of the foreign expression
5194 inline bool CompressedMatrix<Type,true>::isAliased( const Other* alias ) const noexcept
5195 {
5196  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5197 }
5199 //*************************************************************************************************
5200 
5201 
5202 //*************************************************************************************************
5213 template< typename Type > // Data type of the matrix
5214 inline bool CompressedMatrix<Type,true>::canSMPAssign() const noexcept
5215 {
5216  return false;
5217 }
5219 //*************************************************************************************************
5220 
5221 
5222 //*************************************************************************************************
5234 template< typename Type > // Data type of the matrix
5235 template< typename MT // Type of the right-hand side dense matrix
5236  , bool SO > // Storage order of the right-hand side dense matrix
5237 inline void CompressedMatrix<Type,true>::assign( const DenseMatrix<MT,SO>& rhs )
5238 {
5239  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5240  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5241 
5242  if( m_ == 0UL || n_ == 0UL )
5243  return;
5244 
5245  size_t nonzeros( 0UL );
5246 
5247  for( size_t j=1UL; j<=n_; ++j )
5248  begin_[j] = end_[j] = end_[n_];
5249 
5250  for( size_t j=0UL; j<n_; ++j )
5251  {
5252  begin_[j] = end_[j] = begin_[0UL]+nonzeros;
5253 
5254  const size_t ibegin( ( IsLower<MT>::value )
5255  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5256  :( 0UL ) );
5257  const size_t iend ( ( IsUpper<MT>::value )
5258  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5259  :( m_ ) );
5260 
5261  for( size_t i=ibegin; i<iend; ++i )
5262  {
5263  if( nonzeros == capacity() ) {
5264  reserveElements( extendCapacity() );
5265  for( size_t k=j+1UL; k<=n_; ++k )
5266  begin_[k] = end_[k] = end_[n_];
5267  }
5268 
5269  end_[j]->value_ = (~rhs)(i,j);
5270 
5271  if( !isDefault<strict>( end_[j]->value_ ) ) {
5272  end_[j]->index_ = i;
5273  ++end_[j];
5274  ++nonzeros;
5275  }
5276  }
5277  }
5278 
5279  begin_[n_] = begin_[0UL]+nonzeros;
5280 }
5282 //*************************************************************************************************
5283 
5284 
5285 //*************************************************************************************************
5297 template< typename Type > // Data type of the matrix
5298 template< typename MT > // Type of the right-hand side compressed matrix
5299 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,true>& rhs )
5300 {
5301  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5302  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5303  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
5304  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
5305 
5306  if( n_ == 0UL || begin_[0] == nullptr )
5307  return;
5308 
5309  for( size_t j=0UL; j<n_; ++j ) {
5310  end_[j] = castDown( std::copy( (~rhs).begin(j), (~rhs).end(j), castUp( begin_[j] ) ) );
5311  begin_[j+1UL] = end_[j];
5312  }
5313 }
5315 //*************************************************************************************************
5316 
5317 
5318 //*************************************************************************************************
5330 template< typename Type > // Data type of the matrix
5331 template< typename MT > // Type of the right-hand side compressed matrix
5332 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,false>& rhs )
5333 {
5335 
5336  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5337  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5338  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
5339  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
5340 
5341  typedef ConstIterator_<MT> RhsIterator;
5342 
5343  // Counting the number of elements per column
5344  std::vector<size_t> columnLengths( n_, 0UL );
5345  for( size_t i=0UL; i<m_; ++i ) {
5346  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5347  ++columnLengths[element->index()];
5348  }
5349 
5350  // Resizing the compressed matrix
5351  for( size_t j=0UL; j<n_; ++j ) {
5352  begin_[j+1UL] = end_[j+1UL] = begin_[j] + columnLengths[j];
5353  }
5354 
5355  // Appending the elements to the columns of the compressed matrix
5356  for( size_t i=0UL; i<m_; ++i ) {
5357  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5358  append( i, element->index(), element->value() );
5359  }
5360 }
5362 //*************************************************************************************************
5363 
5364 
5365 //*************************************************************************************************
5377 template< typename Type > // Data type of the matrix
5378 template< typename MT // Type of the right-hand side dense matrix
5379  , bool SO > // Storage order of the right-hand side dense matrix
5380 inline void CompressedMatrix<Type,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
5381 {
5382  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5383  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5384 
5385  CompressedMatrix tmp( serial( *this + (~rhs) ) );
5386  swap( tmp );
5387 }
5389 //*************************************************************************************************
5390 
5391 
5392 //*************************************************************************************************
5404 template< typename Type > // Data type of the matrix
5405 template< typename MT // Type of the right-hand side compressed matrix
5406  , bool SO > // Storage order of the right-hand side compressed matrix
5407 inline void CompressedMatrix<Type,true>::addAssign( const SparseMatrix<MT,SO>& rhs )
5408 {
5409  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5410  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5411 
5412  CompressedMatrix tmp( serial( *this + (~rhs) ) );
5413  swap( tmp );
5414 }
5416 //*************************************************************************************************
5417 
5418 
5419 //*************************************************************************************************
5431 template< typename Type > // Data type of the matrix
5432 template< typename MT // Type of the right-hand side dense matrix
5433  , bool SO > // Storage order of the right-hand side dense matrix
5434 inline void CompressedMatrix<Type,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
5435 {
5436  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5437  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5438 
5439  CompressedMatrix tmp( serial( *this - (~rhs) ) );
5440  swap( tmp );
5441 }
5443 //*************************************************************************************************
5444 
5445 
5446 //*************************************************************************************************
5458 template< typename Type > // Data type of the matrix
5459 template< typename MT // Type of the right-hand side compressed matrix
5460  , bool SO > // Storage order of the right-hand side compressed matrix
5461 inline void CompressedMatrix<Type,true>::subAssign( const SparseMatrix<MT,SO>& rhs )
5462 {
5463  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5464  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5465 
5466  CompressedMatrix tmp( serial( *this - (~rhs) ) );
5467  swap( tmp );
5468 }
5470 //*************************************************************************************************
5471 
5472 
5473 
5474 
5475 
5476 
5477 
5478 
5479 //=================================================================================================
5480 //
5481 // COMPRESSEDMATRIX OPERATORS
5482 //
5483 //=================================================================================================
5484 
5485 //*************************************************************************************************
5488 template< typename Type, bool SO >
5489 inline void reset( CompressedMatrix<Type,SO>& m );
5490 
5491 template< typename Type, bool SO >
5492 inline void reset( CompressedMatrix<Type,SO>& m, size_t i );
5493 
5494 template< typename Type, bool SO >
5495 inline void clear( CompressedMatrix<Type,SO>& m );
5496 
5497 template< bool RF, typename Type, bool SO >
5498 inline bool isDefault( const CompressedMatrix<Type,SO>& m );
5499 
5500 template< typename Type, bool SO >
5501 inline bool isIntact( const CompressedMatrix<Type,SO>& m );
5502 
5503 template< typename Type, bool SO >
5504 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) noexcept;
5506 //*************************************************************************************************
5507 
5508 
5509 //*************************************************************************************************
5516 template< typename Type // Data type of the matrix
5517  , bool SO > // Storage order
5518 inline void reset( CompressedMatrix<Type,SO>& m )
5519 {
5520  m.reset();
5521 }
5522 //*************************************************************************************************
5523 
5524 
5525 //*************************************************************************************************
5538 template< typename Type // Data type of the matrix
5539  , bool SO > // Storage order
5540 inline void reset( CompressedMatrix<Type,SO>& m, size_t i )
5541 {
5542  m.reset( i );
5543 }
5544 //*************************************************************************************************
5545 
5546 
5547 //*************************************************************************************************
5554 template< typename Type // Data type of the matrix
5555  , bool SO > // Storage order
5556 inline void clear( CompressedMatrix<Type,SO>& m )
5557 {
5558  m.clear();
5559 }
5560 //*************************************************************************************************
5561 
5562 
5563 //*************************************************************************************************
5588 template< bool RF // Relaxation flag
5589  , typename Type // Data type of the matrix
5590  , bool SO > // Storage order
5591 inline bool isDefault( const CompressedMatrix<Type,SO>& m )
5592 {
5593  return ( m.rows() == 0UL && m.columns() == 0UL );
5594 }
5595 //*************************************************************************************************
5596 
5597 
5598 //*************************************************************************************************
5616 template< typename Type // Data type of the matrix
5617  , bool SO > // Storage order
5618 inline bool isIntact( const CompressedMatrix<Type,SO>& m )
5619 {
5620  return ( m.nonZeros() <= m.capacity() );
5621 }
5622 //*************************************************************************************************
5623 
5624 
5625 //*************************************************************************************************
5633 template< typename Type // Data type of the matrix
5634  , bool SO > // Storage order
5635 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) noexcept
5636 {
5637  a.swap( b );
5638 }
5639 //*************************************************************************************************
5640 
5641 
5642 
5643 
5644 //=================================================================================================
5645 //
5646 // ISRESIZABLE SPECIALIZATIONS
5647 //
5648 //=================================================================================================
5649 
5650 //*************************************************************************************************
5652 template< typename T, bool SO >
5653 struct IsResizable< CompressedMatrix<T,SO> > : public TrueType
5654 {};
5656 //*************************************************************************************************
5657 
5658 
5659 
5660 
5661 //=================================================================================================
5662 //
5663 // ADDTRAIT SPECIALIZATIONS
5664 //
5665 //=================================================================================================
5666 
5667 //*************************************************************************************************
5669 template< typename T1, bool SO, typename T2, size_t M, size_t N >
5670 struct AddTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
5671 {
5672  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
5673 };
5674 
5675 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5676 struct AddTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
5677 {
5678  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO2 >;
5679 };
5680 
5681 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5682 struct AddTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
5683 {
5684  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
5685 };
5686 
5687 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5688 struct AddTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
5689 {
5690  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO1 >;
5691 };
5692 
5693 template< typename T1, bool SO, typename T2, size_t M, size_t N >
5694 struct AddTrait< CompressedMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
5695 {
5696  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO >;
5697 };
5698 
5699 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5700 struct AddTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
5701 {
5702  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO2 >;
5703 };
5704 
5705 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5706 struct AddTrait< HybridMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
5707 {
5708  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO >;
5709 };
5710 
5711 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5712 struct AddTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
5713 {
5714  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO1 >;
5715 };
5716 
5717 template< typename T1, bool SO, typename T2 >
5718 struct AddTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
5719 {
5720  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
5721 };
5722 
5723 template< typename T1, bool SO1, typename T2, bool SO2 >
5724 struct AddTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
5725 {
5726  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO2 >;
5727 };
5728 
5729 template< typename T1, bool SO, typename T2 >
5730 struct AddTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
5731 {
5732  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
5733 };
5734 
5735 template< typename T1, bool SO1, typename T2, bool SO2 >
5736 struct AddTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
5737 {
5738  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO1 >;
5739 };
5740 
5741 template< typename T1, bool SO, typename T2, bool AF, bool PF >
5742 struct AddTrait< CompressedMatrix<T1,SO>, CustomMatrix<T2,AF,PF,SO> >
5743 {
5744  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
5745 };
5746 
5747 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
5748 struct AddTrait< CompressedMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
5749 {
5750  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO2 >;
5751 };
5752 
5753 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
5754 struct AddTrait< CustomMatrix<T1,AF,PF,SO>, CompressedMatrix<T2,SO> >
5755 {
5756  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
5757 };
5758 
5759 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
5760 struct AddTrait< CustomMatrix<T1,AF,PF,SO1>, CompressedMatrix<T2,SO2> >
5761 {
5762  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO1 >;
5763 };
5764 
5765 template< typename T1, bool SO, typename T2 >
5766 struct AddTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
5767 {
5768  using Type = CompressedMatrix< AddTrait_<T1,T2>, SO >;
5769 };
5770 
5771 template< typename T1, bool SO1, typename T2, bool SO2 >
5772 struct AddTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
5773 {
5774  using Type = CompressedMatrix< AddTrait_<T1,T2>, false >;
5775 };
5777 //*************************************************************************************************
5778 
5779 
5780 
5781 
5782 //=================================================================================================
5783 //
5784 // SUBTRAIT SPECIALIZATIONS
5785 //
5786 //=================================================================================================
5787 
5788 //*************************************************************************************************
5790 template< typename T1, bool SO, typename T2, size_t M, size_t N >
5791 struct SubTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
5792 {
5793  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
5794 };
5795 
5796 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5797 struct SubTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
5798 {
5799  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO2 >;
5800 };
5801 
5802 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5803 struct SubTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
5804 {
5805  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
5806 };
5807 
5808 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5809 struct SubTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
5810 {
5811  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO1 >;
5812 };
5813 
5814 template< typename T1, bool SO, typename T2, size_t M, size_t N >
5815 struct SubTrait< CompressedMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
5816 {
5817  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO >;
5818 };
5819 
5820 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5821 struct SubTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
5822 {
5823  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO2 >;
5824 };
5825 
5826 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5827 struct SubTrait< HybridMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
5828 {
5829  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO >;
5830 };
5831 
5832 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5833 struct SubTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
5834 {
5835  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO1 >;
5836 };
5837 
5838 template< typename T1, bool SO, typename T2 >
5839 struct SubTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
5840 {
5841  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
5842 };
5843 
5844 template< typename T1, bool SO1, typename T2, bool SO2 >
5845 struct SubTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
5846 {
5847  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO2 >;
5848 };
5849 
5850 template< typename T1, bool SO, typename T2 >
5851 struct SubTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
5852 {
5853  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
5854 };
5855 
5856 template< typename T1, bool SO1, typename T2, bool SO2 >
5857 struct SubTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
5858 {
5859  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO1 >;
5860 };
5861 
5862 template< typename T1, bool SO, typename T2, bool AF, bool PF >
5863 struct SubTrait< CompressedMatrix<T1,SO>, CustomMatrix<T2,AF,PF,SO> >
5864 {
5865  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
5866 };
5867 
5868 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
5869 struct SubTrait< CompressedMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
5870 {
5871  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO2 >;
5872 };
5873 
5874 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
5875 struct SubTrait< CustomMatrix<T1,AF,PF,SO>, CompressedMatrix<T2,SO> >
5876 {
5877  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
5878 };
5879 
5880 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
5881 struct SubTrait< CustomMatrix<T1,AF,PF,SO1>, CompressedMatrix<T2,SO2> >
5882 {
5883  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO1 >;
5884 };
5885 
5886 template< typename T1, bool SO, typename T2 >
5887 struct SubTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
5888 {
5889  using Type = CompressedMatrix< SubTrait_<T1,T2> , SO >;
5890 };
5891 
5892 template< typename T1, bool SO1, typename T2, bool SO2 >
5893 struct SubTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
5894 {
5895  using Type = CompressedMatrix< SubTrait_<T1,T2> , false >;
5896 };
5898 //*************************************************************************************************
5899 
5900 
5901 
5902 
5903 //=================================================================================================
5904 //
5905 // MULTTRAIT SPECIALIZATIONS
5906 //
5907 //=================================================================================================
5908 
5909 //*************************************************************************************************
5911 template< typename T1, bool SO, typename T2 >
5912 struct MultTrait< CompressedMatrix<T1,SO>, T2, EnableIf_< IsNumeric<T2> > >
5913 {
5914  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO >;
5915 };
5916 
5917 template< typename T1, typename T2, bool SO >
5918 struct MultTrait< T1, CompressedMatrix<T2,SO>, EnableIf_< IsNumeric<T1> > >
5919 {
5920  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO >;
5921 };
5922 
5923 template< typename T1, bool SO, typename T2, size_t N >
5924 struct MultTrait< CompressedMatrix<T1,SO>, StaticVector<T2,N,false> >
5925 {
5926  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
5927 };
5928 
5929 template< typename T1, size_t N, typename T2, bool SO >
5930 struct MultTrait< StaticVector<T1,N,true>, CompressedMatrix<T2,SO> >
5931 {
5932  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
5933 };
5934 
5935 template< typename T1, bool SO, typename T2, size_t N >
5936 struct MultTrait< CompressedMatrix<T1,SO>, HybridVector<T2,N,false> >
5937 {
5938  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
5939 };
5940 
5941 template< typename T1, size_t N, typename T2, bool SO >
5942 struct MultTrait< HybridVector<T1,N,true>, CompressedMatrix<T2,SO> >
5943 {
5944  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
5945 };
5946 
5947 template< typename T1, bool SO, typename T2 >
5948 struct MultTrait< CompressedMatrix<T1,SO>, DynamicVector<T2,false> >
5949 {
5950  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
5951 };
5952 
5953 template< typename T1, typename T2, bool SO >
5954 struct MultTrait< DynamicVector<T1,true>, CompressedMatrix<T2,SO> >
5955 {
5956  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
5957 };
5958 
5959 template< typename T1, bool SO, typename T2, bool AF, bool PF >
5960 struct MultTrait< CompressedMatrix<T1,SO>, CustomVector<T2,AF,PF,false> >
5961 {
5962  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
5963 };
5964 
5965 template< typename T1, bool AF, bool PF, typename T2, bool SO >
5966 struct MultTrait< CustomVector<T1,AF,PF,true>, CompressedMatrix<T2,SO> >
5967 {
5968  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
5969 };
5970 
5971 template< typename T1, bool SO, typename T2 >
5972 struct MultTrait< CompressedMatrix<T1,SO>, CompressedVector<T2,false> >
5973 {
5974  using Type = CompressedVector< MultTrait_<T1,T2>, false >;
5975 };
5976 
5977 template< typename T1, typename T2, bool SO >
5978 struct MultTrait< CompressedVector<T1,true>, CompressedMatrix<T2,SO> >
5979 {
5980  using Type = CompressedVector< MultTrait_<T1,T2>, true >;
5981 };
5982 
5983 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5984 struct MultTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
5985 {
5986  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
5987 };
5988 
5989 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5990 struct MultTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
5991 {
5992  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
5993 };
5994 
5995 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5996 struct MultTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
5997 {
5998  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
5999 };
6000 
6001 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6002 struct MultTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
6003 {
6004  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6005 };
6006 
6007 template< typename T1, bool SO1, typename T2, bool SO2 >
6008 struct MultTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
6009 {
6010  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6011 };
6012 
6013 template< typename T1, bool SO1, typename T2, bool SO2 >
6014 struct MultTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
6015 {
6016  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6017 };
6018 
6019 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6020 struct MultTrait< CompressedMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6021 {
6022  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6023 };
6024 
6025 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6026 struct MultTrait< CustomMatrix<T1,AF,PF,SO1>, CompressedMatrix<T2,SO2> >
6027 {
6028  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6029 };
6030 
6031 template< typename T1, bool SO1, typename T2, bool SO2 >
6032 struct MultTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
6033 {
6034  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO1 >;
6035 };
6037 //*************************************************************************************************
6038 
6039 
6040 
6041 
6042 //=================================================================================================
6043 //
6044 // DIVTRAIT SPECIALIZATIONS
6045 //
6046 //=================================================================================================
6047 
6048 //*************************************************************************************************
6050 template< typename T1, bool SO, typename T2 >
6051 struct DivTrait< CompressedMatrix<T1,SO>, T2, EnableIf_< IsNumeric<T2> > >
6052 {
6053  using Type = CompressedMatrix< DivTrait_<T1,T2>, SO >;
6054 };
6056 //*************************************************************************************************
6057 
6058 
6059 
6060 
6061 //=================================================================================================
6062 //
6063 // HIGHTYPE SPECIALIZATIONS
6064 //
6065 //=================================================================================================
6066 
6067 //*************************************************************************************************
6069 template< typename T1, bool SO, typename T2 >
6070 struct HighType< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6071 {
6072  using Type = CompressedMatrix< typename HighType<T1,T2>::Type, SO >;
6073 };
6075 //*************************************************************************************************
6076 
6077 
6078 
6079 
6080 //=================================================================================================
6081 //
6082 // LOWTYPE SPECIALIZATIONS
6083 //
6084 //=================================================================================================
6085 
6086 //*************************************************************************************************
6088 template< typename T1, bool SO, typename T2 >
6089 struct LowType< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6090 {
6091  using Type = CompressedMatrix< typename LowType<T1,T2>::Type, SO >;
6092 };
6094 //*************************************************************************************************
6095 
6096 
6097 
6098 
6099 //=================================================================================================
6100 //
6101 // SUBMATRIXTRAIT SPECIALIZATIONS
6102 //
6103 //=================================================================================================
6104 
6105 //*************************************************************************************************
6107 template< typename T1, bool SO >
6108 struct SubmatrixTrait< CompressedMatrix<T1,SO> >
6109 {
6110  using Type = CompressedMatrix<T1,SO>;
6111 };
6113 //*************************************************************************************************
6114 
6115 
6116 
6117 
6118 //=================================================================================================
6119 //
6120 // ROWTRAIT SPECIALIZATIONS
6121 //
6122 //=================================================================================================
6123 
6124 //*************************************************************************************************
6126 template< typename T1, bool SO >
6127 struct RowTrait< CompressedMatrix<T1,SO> >
6128 {
6129  using Type = CompressedVector<T1,true>;
6130 };
6132 //*************************************************************************************************
6133 
6134 
6135 
6136 
6137 //=================================================================================================
6138 //
6139 // COLUMNTRAIT SPECIALIZATIONS
6140 //
6141 //=================================================================================================
6142 
6143 //*************************************************************************************************
6145 template< typename T1, bool SO >
6146 struct ColumnTrait< CompressedMatrix<T1,SO> >
6147 {
6148  using Type = CompressedVector<T1,false>;
6149 };
6151 //*************************************************************************************************
6152 
6153 } // namespace blaze
6154 
6155 #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:79
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Pointer difference type of the Blaze library.
void reserveElements(size_t nonzeros)
Reserving the specified number of compressed matrix elements.
Definition: CompressedMatrix.h:1782
Header file for auxiliary alias declarations.
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:79
Iterator * end_
Pointers one past the last non-zero element of each row.
Definition: CompressedMatrix.h:500
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 compressed matrix value.
Definition: CompressedMatrix.h:297
CompressedMatrix< NewType, true > Other
The type of the other CompressedMatrix.
Definition: CompressedMatrix.h:2947
Header file for the subtraction trait.
bool canSMPAssign() const noexcept
Returns whether the matrix can be used in SMP assignments.
Definition: CompressedMatrix.h:2576
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:352
Header file for basic type definitions.
const Type & ConstReference
Reference to a constant compressed matrix value.
Definition: CompressedMatrix.h:298
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: CompressedMatrix.h:2557
Header file for the row trait.
CompressedMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: CompressedMatrix.h:2463
CompressedMatrix()
The default constructor for CompressedMatrix.
Definition: CompressedMatrix.h:544
Header file for the serial shim.
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:209
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:261
const CTransExprTrait_< MT > ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatForEachExpr.h:1251
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1339
Iterator end(size_t i) noexcept
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:963
Reference operator()(size_t i, size_t j) noexcept
2D-access to the compressed matrix elements.
Definition: CompressedMatrix.h:789
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:194
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:533
size_t m_
The current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:3135
void clear()
Clearing the compressed matrix.
Definition: CompressedMatrix.h:1485
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:294
OutputIterator transfer(InputIterator first, InputIterator last, OutputIterator dest)
Transfers the elements from the given source range to the destination range.
Definition: Algorithm.h:71
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1755
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2928
CompressedMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:292
#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:79
~CompressedMatrix()
The destructor for CompressedMatrix.
Definition: CompressedMatrix.h:755
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:721
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:390
Access proxy for sparse, matrices.The MatrixAccessProxy provides safe access to the elements of a no...
Definition: MatrixAccessProxy.h:101
size_t columns() const noexcept
Returns the current number of columns of the compressed matrix.
Definition: CompressedMatrix.h:1356
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:88
BoolConstant< true > TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
Header file for memory allocation and deallocation functionality.
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1321
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first non-zero element of row/column i.
Definition: CompressedMatrix.h:941
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1802
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:502
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:295
Resize mechanism to obtain a CompressedMatrix with different fixed dimensions.
Definition: CompressedMatrix.h:2956
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:71
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:119
void swap(CompressedMatrix &sm) noexcept
Swapping the contents of two sparse matrices.
Definition: CompressedMatrix.h:1741
Constraint on the data type.
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:3137
Header file for the SparseMatrix base class.
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:498
void reserve(size_t nonzeros)
Setting the minimum capacity of the compressed matrix.
Definition: CompressedMatrix.h:1607
void reset()
Reset to the default initial values.
Definition: CompressedMatrix.h:1447
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:296
Header file for the ValueIndexPair class.
CompressedMatrix< Type, true > Other
The type of the other CompressedMatrix.
Definition: CompressedMatrix.h:2957
Header file for the LowType type trait.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5635
Header file for the If class template.
CompressedMatrix< NewType, SO > Other
The type of the other CompressedMatrix.
Definition: CompressedMatrix.h:308
Header file for the IsFloatingPoint type trait.
Iterator set(size_t i, size_t j, const Type &value)
Setting an element of the compressed matrix.
Definition: CompressedMatrix.h:1867
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:2939
#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:79
Header file for the IsSMPAssignable type trait.
void erase(size_t i, size_t j)
Erasing an element from the compressed matrix.
Definition: CompressedMatrix.h:2109
Iterator * end_
Pointers one past the last non-zero element of each column.
Definition: CompressedMatrix.h:3139
size_t rows() const noexcept
Returns the current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:1342
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
#define BLAZE_CONSTRAINT_MUST_HAVE_SAME_SIZE(T1, T2)
Constraint on the size of two data types.In case the types T1 and T2 don&#39;t have the same size...
Definition: SameSize.h:60
ValueIndexPair< Type > ElementBase
Base class for the compressed matrix element.
Definition: CompressedMatrix.h:213
size_t capacity() const noexcept
Returns the maximum capacity of the compressed matrix.
Definition: CompressedMatrix.h:1370
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:1007
Constraint on the data type.
Header file for the IsLower type trait.
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:336
Header file for the default storage order for all vectors of the Blaze library.
IteratorBase castUp(Iterator it) const noexcept
Performs an up-cast of the given iterator.
Definition: CompressedMatrix.h:1837
Iterator insert(size_t i, size_t j, const Type &value)
Inserting an element into the compressed matrix.
Definition: CompressedMatrix.h:1899
Header file for the exception macros of the math module.
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:75
Compile time check for data types.This type trait tests whether or not the given template parameter i...
Definition: IsSMPAssignable.h:119
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:544
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:260
Headerfile for generic algorithms.
void subAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the subtraction assignment of a dense matrix.
Definition: CompressedMatrix.h:2790
size_t nonZeros() const
Returns the number of non-zero elements in the compressed matrix.
Definition: CompressedMatrix.h:1407
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:553
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:300
typename DivTrait< T1, T2 >::Type DivTrait_
Auxiliary alias declaration for the DivTrait class template.The DivTrait_ alias declaration provides ...
Definition: DivTrait.h:245
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the compressed matrix.
Definition: CompressedMatrix.h:1512
Header file for the IsNumeric type trait.
CompressedMatrix & operator=(const CompressedMatrix &rhs)
Copy assignment operator for CompressedMatrix.
Definition: CompressedMatrix.h:1035
#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:79
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: CompressedMatrix.h:2537
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1285
Header file for run time assertion macros.
Header file for the relaxation flag types.
Header file for the addition trait.
Resize mechanism to obtain a CompressedMatrix with different fixed dimensions.
Definition: CompressedMatrix.h:317
CompressedMatrix & transpose()
In-place transpose of the matrix.
Definition: CompressedMatrix.h:2447
Header file for the division trait.
void trim()
Removing all excessive capacity from all rows/columns.
Definition: CompressedMatrix.h:1701
Header file for the submatrix trait.
Constraint on the data type.
typename If< T1, T2, T3 >::Type If_
Auxiliary alias declaration for the If class template.The If_ alias declaration provides a convenient...
Definition: If.h:160
#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:79
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2938
Header file for the column trait.
Header file for the isDefault shim.
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b) noexcept
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:267
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:94
Constraint on the data type.
Constraint on the data type.
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:291
Iterator * begin_
Pointers to the first non-zero element of each column.
Definition: CompressedMatrix.h:3138
void assign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the assignment of a row-major dense matrix.
Definition: CompressedMatrix.h:2598
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:299
void append(size_t i, size_t j, const Type &value, bool check=false)
Appending an element to the specified row/column of the compressed matrix.
Definition: CompressedMatrix.h:2047
EnableIf_< IsBuiltin< T > > deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:225
void finalize(size_t i)
Finalizing the element insertion of a row/column.
Definition: CompressedMatrix.h:2079
CompressedMatrix< Type, SO > Other
The type of the other CompressedMatrix.
Definition: CompressedMatrix.h:318
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:223
CompressedMatrix< Type, SO > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:289
Iterator find(size_t i, size_t j)
Searches for a specific matrix element.
Definition: CompressedMatrix.h:2287
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:499
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:320
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
size_t n_
The current number of columns of the compressed matrix.
Definition: CompressedMatrix.h:3136
Index-value-pair for sparse vectors and matrices.The ValueIndexPair class represents a single index-v...
Definition: ValueIndexPair.h:73
Constraint on the size of two data types.
Iterator castDown(IteratorBase it) const noexcept
Performs a down-cast of the given iterator.
Definition: CompressedMatrix.h:1819
void addAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the addition assignment of a dense matrix.
Definition: CompressedMatrix.h:2738
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:733
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:293
SparseMatrix< This, SO > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:290
Iterator lowerBound(size_t i, size_t j)
Returns an iterator to the first index not less then the given index.
Definition: CompressedMatrix.h:2340
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:3141
Compile time type check.This class tests whether the given template parameter T is an rvalue referenc...
Definition: IsRValueReference.h:77
Iterator upperBound(size_t i, size_t j)
Returns an iterator to the first index greater then the given index.
Definition: CompressedMatrix.h:2395
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:249
ElementBase * IteratorBase
Iterator over non-constant base elements.
Definition: CompressedMatrix.h:214
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2936
size_t extendCapacity() const noexcept
Calculating a new matrix capacity.
Definition: CompressedMatrix.h:1762
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:307
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:2946
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1303
Header file for the IsUpper type trait.
size_t n_
The current number of columns of the compressed matrix.
Definition: CompressedMatrix.h:497
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: CompressedMatrix.h:843
Header file for the IsResizable type trait.
size_t m_
The current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:496
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
Reference value()
Access to the current value of the value-index-pair.
Definition: ValueIndexPair.h:361
Header file for the HighType type trait.
Iterator begin(size_t i) noexcept
Returns an iterator to the first non-zero element of row/column i.
Definition: CompressedMatrix.h:897
constexpr bool defaultStorageOrder
The default storage order for all matrices of the Blaze library.This value specifies the default stor...
Definition: StorageOrder.h:56