Blaze  3.6
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>
49 #include <blaze/math/Exception.h>
51 #include <blaze/math/Forward.h>
92 #include <blaze/util/Assert.h>
98 #include <blaze/util/EnableIf.h>
100 #include <blaze/util/Memory.h>
101 #include <blaze/util/Types.h>
105 
106 
107 namespace blaze {
108 
109 //=================================================================================================
110 //
111 // CLASS DEFINITION
112 //
113 //=================================================================================================
114 
115 //*************************************************************************************************
225 template< typename Type // Data type of the matrix
226  , bool SO = defaultStorageOrder > // Storage order
228  : public SparseMatrix< CompressedMatrix<Type,SO>, SO >
229 {
230  private:
231  //**Type definitions****************************************************************************
234  //**********************************************************************************************
235 
236  //**Private class Element***********************************************************************
243  struct Element
244  : public ElementBase
245  {
246  //**Constructors*****************************************************************************
247  explicit Element() = default;
248  Element( const Element& rhs ) = default;
249  Element( Element&& rhs ) = default;
250  //*******************************************************************************************
251 
252  //**Assignment operators*********************************************************************
253  inline Element& operator=( const Element& rhs )
254  {
255  this->value_ = rhs.value_;
256  return *this;
257  }
258 
259  inline Element& operator=( Element&& rhs )
260  {
261  this->value_ = std::move( rhs.value_ );
262  return *this;
263  }
264 
265  template< typename Other >
266  inline auto operator=( const Other& rhs )
268  {
269  this->value_ = rhs.value();
270  return *this;
271  }
272 
273  template< typename Other >
274  inline auto operator=( Other&& rhs )
276  IsRValueReference_v<Other&&>, Element& >
277  {
278  this->value_ = std::move( rhs.value() );
279  return *this;
280  }
281 
282  template< typename Other >
283  inline auto operator=( const Other& v )
285  {
286  this->value_ = v;
287  return *this;
288  }
289 
290  template< typename Other >
291  inline auto operator=( Other&& v )
293  IsRValueReference_v<Other&&>, Element& >
294  {
295  this->value_ = std::move( v );
296  return *this;
297  }
298  //*******************************************************************************************
299 
300  //**Friend declarations**********************************************************************
301  friend class CompressedMatrix;
302  //*******************************************************************************************
303  };
305  //**********************************************************************************************
306 
307  //**Private class Uninitialized*****************************************************************
311  struct Uninitialized {};
313  //**********************************************************************************************
314 
315  public:
316  //**Type definitions****************************************************************************
319  using ResultType = This;
322  using ElementType = Type;
323  using ReturnType = const Type&;
324  using CompositeType = const This&;
326  using ConstReference = const Type&;
327  using Iterator = Element*;
328  using ConstIterator = const Element*;
329  //**********************************************************************************************
330 
331  //**Rebind struct definition********************************************************************
334  template< typename NewType > // Data type of the other matrix
335  struct Rebind {
337  };
338  //**********************************************************************************************
339 
340  //**Resize struct definition********************************************************************
343  template< size_t NewM // Number of rows of the other matrix
344  , size_t NewN > // Number of columns of the other matrix
345  struct Resize {
347  };
348  //**********************************************************************************************
349 
350  //**Compilation flags***************************************************************************
352 
355  static constexpr bool smpAssignable = !IsSMPAssignable_v<Type>;
356  //**********************************************************************************************
357 
358  //**Constructors********************************************************************************
361  explicit inline CompressedMatrix();
362  explicit inline CompressedMatrix( size_t m, size_t n );
363  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
364  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
366 
367  inline CompressedMatrix( const CompressedMatrix& sm );
368  inline CompressedMatrix( CompressedMatrix&& sm ) noexcept;
369 
370  template< typename MT, bool SO2 > inline CompressedMatrix( const DenseMatrix<MT,SO2>& dm );
371  template< typename MT, bool SO2 > inline CompressedMatrix( const SparseMatrix<MT,SO2>& sm );
373  //**********************************************************************************************
374 
375  //**Destructor**********************************************************************************
378  inline ~CompressedMatrix();
380  //**********************************************************************************************
381 
382  //**Data access functions***********************************************************************
385  inline Reference operator()( size_t i, size_t j ) noexcept;
386  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
387  inline Reference at( size_t i, size_t j );
388  inline ConstReference at( size_t i, size_t j ) const;
389  inline Iterator begin ( size_t i ) noexcept;
390  inline ConstIterator begin ( size_t i ) const noexcept;
391  inline ConstIterator cbegin( size_t i ) const noexcept;
392  inline Iterator end ( size_t i ) noexcept;
393  inline ConstIterator end ( size_t i ) const noexcept;
394  inline ConstIterator cend ( size_t i ) const noexcept;
396  //**********************************************************************************************
397 
398  //**Assignment operators************************************************************************
402  inline CompressedMatrix& operator=( const CompressedMatrix& rhs );
403  inline CompressedMatrix& operator=( CompressedMatrix&& rhs ) noexcept;
404 
405  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO2>& rhs );
406  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO2>& rhs );
407  template< typename MT, bool SO2 > inline CompressedMatrix& operator+=( const Matrix<MT,SO2>& rhs );
408  template< typename MT, bool SO2 > inline CompressedMatrix& operator-=( const Matrix<MT,SO2>& rhs );
409  template< typename MT, bool SO2 > inline CompressedMatrix& operator%=( const DenseMatrix<MT,SO2>& rhs );
410  template< typename MT, bool SO2 > inline CompressedMatrix& operator%=( const SparseMatrix<MT,SO2>& rhs );
412  //**********************************************************************************************
413 
414  //**Utility functions***************************************************************************
417  inline size_t rows() const noexcept;
418  inline size_t columns() const noexcept;
419  inline size_t capacity() const noexcept;
420  inline size_t capacity( size_t i ) const noexcept;
421  inline size_t nonZeros() const;
422  inline size_t nonZeros( size_t i ) const;
423  inline void reset();
424  inline void reset( size_t i );
425  inline void clear();
426  void resize ( size_t m, size_t n, bool preserve=true );
427  inline void reserve( size_t nonzeros );
428  void reserve( size_t i, size_t nonzeros );
429  inline void trim ();
430  inline void trim ( size_t i );
431  inline void shrinkToFit();
432  inline void swap( CompressedMatrix& sm ) noexcept;
434  //**********************************************************************************************
435 
436  //**Insertion functions*************************************************************************
439  inline Iterator set ( size_t i, size_t j, const Type& value );
440  inline Iterator insert ( size_t i, size_t j, const Type& value );
441  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
442  inline void finalize( size_t i );
444  //**********************************************************************************************
445 
446  //**Erase functions*****************************************************************************
449  inline void erase( size_t i, size_t j );
450  inline Iterator erase( size_t i, Iterator pos );
451  inline Iterator erase( size_t i, Iterator first, Iterator last );
452 
453  template< typename Pred >
454  inline void erase( Pred predicate );
455 
456  template< typename Pred >
457  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
459  //**********************************************************************************************
460 
461  //**Lookup functions****************************************************************************
464  inline Iterator find ( size_t i, size_t j );
465  inline ConstIterator find ( size_t i, size_t j ) const;
466  inline Iterator lowerBound( size_t i, size_t j );
467  inline ConstIterator lowerBound( size_t i, size_t j ) const;
468  inline Iterator upperBound( size_t i, size_t j );
469  inline ConstIterator upperBound( size_t i, size_t j ) const;
471  //**********************************************************************************************
472 
473  //**Numeric functions***************************************************************************
476  inline CompressedMatrix& transpose();
477  inline CompressedMatrix& ctranspose();
478 
479  template< typename Other > inline CompressedMatrix& scale( const Other& scalar );
481  //**********************************************************************************************
482 
483  //**Expression template evaluation functions****************************************************
486  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
487  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
488 
489  inline bool canSMPAssign() const noexcept;
490 
491  template< typename MT, bool SO2 > inline void assign ( const DenseMatrix<MT,SO2>& rhs );
492  template< typename MT > inline void assign ( const SparseMatrix<MT,SO>& rhs );
493  template< typename MT > inline void assign ( const SparseMatrix<MT,!SO>& rhs );
494  template< typename MT, bool SO2 > inline void addAssign ( const DenseMatrix<MT,SO2>& rhs );
495  template< typename MT, bool SO2 > inline void addAssign ( const SparseMatrix<MT,SO2>& rhs );
496  template< typename MT, bool SO2 > inline void subAssign ( const DenseMatrix<MT,SO2>& rhs );
497  template< typename MT, bool SO2 > inline void subAssign ( const SparseMatrix<MT,SO2>& rhs );
498  template< typename MT, bool SO2 > inline void schurAssign( const DenseMatrix<MT,SO2>& rhs );
500  //**********************************************************************************************
501 
502  private:
503  //**Constructors********************************************************************************
506  explicit inline CompressedMatrix( size_t m, size_t n, Uninitialized );
508  //**********************************************************************************************
509 
510  //**Utility functions***************************************************************************
513  inline size_t extendCapacity() const noexcept;
514  void reserveElements( size_t nonzeros );
515 
516  inline Iterator castDown( IteratorBase it ) const noexcept;
517  inline IteratorBase castUp ( Iterator it ) const noexcept;
519  //**********************************************************************************************
520 
521  //**Insertion functions*************************************************************************
524  Iterator insert( Iterator pos, size_t i, size_t j, const Type& value );
526  //**********************************************************************************************
527 
528  //**Member variables****************************************************************************
531  size_t m_;
532  size_t n_;
533  size_t capacity_;
536 
537  static const Type zero_;
538 
539  //**********************************************************************************************
540 
541  //**Compile time checks*************************************************************************
549  //**********************************************************************************************
550 };
551 //*************************************************************************************************
552 
553 
554 
555 
556 //=================================================================================================
557 //
558 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
559 //
560 //=================================================================================================
561 
562 template< typename Type, bool SO >
563 const Type CompressedMatrix<Type,SO>::zero_{};
564 
565 
566 
567 
568 //=================================================================================================
569 //
570 // CONSTRUCTORS
571 //
572 //=================================================================================================
573 
574 //*************************************************************************************************
577 template< typename Type // Data type of the matrix
578  , bool SO > // Storage order
580  : m_ ( 0UL ) // The current number of rows of the compressed matrix
581  , n_ ( 0UL ) // The current number of columns of the compressed matrix
582  , capacity_( 0UL ) // The current capacity of the pointer array
583  , begin_ ( nullptr ) // Pointers to the first non-zero element of each row
584  , end_ ( nullptr ) // Pointers one past the last non-zero element of each row
585 {}
586 //*************************************************************************************************
587 
588 
589 //*************************************************************************************************
597 template< typename Type // Data type of the matrix
598  , bool SO > // Storage order
600  : CompressedMatrix( m, n, Uninitialized() )
601 {
602  for( size_t i=1UL; i<2UL*m_+2UL; ++i )
603  begin_[i] = nullptr;
604 }
605 //*************************************************************************************************
606 
607 
608 //*************************************************************************************************
617 template< typename Type // Data type of the matrix
618  , bool SO > // Storage order
619 inline CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
620  : CompressedMatrix( m, n, Uninitialized() )
621 {
622  begin_[0UL] = allocate<Element>( nonzeros );
623  for( size_t i=1UL; i<(2UL*m_+1UL); ++i )
624  begin_[i] = begin_[0UL];
625  end_[m_] = begin_[0UL]+nonzeros;
626 }
627 //*************************************************************************************************
628 
629 
630 //*************************************************************************************************
641 template< typename Type // Data type of the matrix
642  , bool SO > // Storage order
643 CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
644  : CompressedMatrix( m, n, Uninitialized() )
645 {
646  BLAZE_USER_ASSERT( nonzeros.size() == m, "Size of capacity vector and number of rows don't match" );
647 
648  size_t newCapacity( 0UL );
649  for( auto it=nonzeros.begin(); it!=nonzeros.end(); ++it )
650  newCapacity += *it;
651 
652  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
653  for( size_t i=0UL; i<m_; ++i ) {
654  begin_[i+1UL] = end_[i+1UL] = begin_[i] + nonzeros[i];
655  }
656 }
657 //*************************************************************************************************
658 
659 
660 //*************************************************************************************************
680 template< typename Type // Data type of the matrix
681  , bool SO > // Storage order
683  : CompressedMatrix( list.size(), determineColumns( list ), blaze::nonZeros( list ) )
684 {
685  size_t i( 0UL );
686 
687  for( const auto& rowList : list )
688  {
689  size_t j( 0UL );
690 
691  for( const Type& element : rowList ) {
692  if( !isDefault<strict>( element ) )
693  append( i, j, element );
694  ++j;
695  }
696 
697  finalize( i );
698  ++i;
699  }
700 }
701 //*************************************************************************************************
702 
703 
704 //*************************************************************************************************
709 template< typename Type // Data type of the matrix
710  , bool SO > // Storage order
712  : CompressedMatrix( sm.m_, sm.n_, Uninitialized() )
713 {
714  const size_t nonzeros( sm.nonZeros() );
715 
716  begin_[0UL] = allocate<Element>( nonzeros );
717  for( size_t i=0UL; i<m_; ++i ) {
718  end_[i] = castDown( std::copy( sm.begin(i), sm.end(i), castUp( begin_[i] ) ) );
719  begin_[i+1UL] = end_[i];
720  }
721  end_[m_] = begin_[0UL]+nonzeros;
722 }
723 //*************************************************************************************************
724 
725 
726 //*************************************************************************************************
731 template< typename Type // Data type of the matrix
732  , bool SO > // Storage order
734  : m_ ( sm.m_ ) // The current number of rows of the compressed matrix
735  , n_ ( sm.n_ ) // The current number of columns of the compressed matrix
736  , capacity_( sm.capacity_ ) // The current capacity of the pointer array
737  , begin_ ( sm.begin_ ) // Pointers to the first non-zero element of each row
738  , end_ ( sm.end_ ) // Pointers one past the last non-zero element of each row
739 {
740  sm.m_ = 0UL;
741  sm.n_ = 0UL;
742  sm.capacity_ = 0UL;
743  sm.begin_ = nullptr;
744  sm.end_ = nullptr;
745 }
746 //*************************************************************************************************
747 
748 
749 //*************************************************************************************************
754 template< typename Type // Data type of the matrix
755  , bool SO > // Storage order
756 template< typename MT // Type of the foreign dense matrix
757  , bool SO2 > // Storage order of the foreign dense matrix
759  : CompressedMatrix( (~dm).rows(), (~dm).columns() )
760 {
761  using blaze::assign;
762 
763  assign( *this, ~dm );
764 }
765 //*************************************************************************************************
766 
767 
768 //*************************************************************************************************
773 template< typename Type // Data type of the matrix
774  , bool SO > // Storage order
775 template< typename MT // Type of the foreign compressed matrix
776  , bool SO2 > // Storage order of the foreign compressed matrix
778  : CompressedMatrix( (~sm).rows(), (~sm).columns(), (~sm).nonZeros() )
779 {
780  using blaze::assign;
781 
782  assign( *this, ~sm );
783 }
784 //*************************************************************************************************
785 
786 
787 //*************************************************************************************************
793 template< typename Type // Data type of the matrix
794  , bool SO > // Storage order
795 inline CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, Uninitialized )
796  : m_ ( m ) // The current number of rows of the compressed matrix
797  , n_ ( n ) // The current number of columns of the compressed matrix
798  , capacity_( m ) // The current capacity of the pointer array
799  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
800  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
801 {
802  begin_[0] = nullptr;
803 }
804 //*************************************************************************************************
805 
806 
807 
808 
809 //=================================================================================================
810 //
811 // DESTRUCTOR
812 //
813 //=================================================================================================
814 
815 //*************************************************************************************************
818 template< typename Type // Data type of the matrix
819  , bool SO > // Storage order
821 {
822  if( begin_ != nullptr ) {
823  deallocate( begin_[0UL] );
824  delete[] begin_;
825  }
826 }
827 //*************************************************************************************************
828 
829 
830 
831 
832 //=================================================================================================
833 //
834 // DATA ACCESS FUNCTIONS
835 //
836 //=================================================================================================
837 
838 //*************************************************************************************************
851 template< typename Type // Data type of the matrix
852  , bool SO > // Storage order
854  CompressedMatrix<Type,SO>::operator()( size_t i, size_t j ) noexcept
855 {
856  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
857  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
858 
859  return Reference( *this, i, j );
860 }
861 //*************************************************************************************************
862 
863 
864 //*************************************************************************************************
874 template< typename Type // Data type of the matrix
875  , bool SO > // Storage order
877  CompressedMatrix<Type,SO>::operator()( size_t i, size_t j ) const noexcept
878 {
879  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
880  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
881 
882  const ConstIterator pos( lowerBound( i, j ) );
883 
884  if( pos == end_[i] || pos->index_ != j )
885  return zero_;
886  else
887  return pos->value_;
888 }
889 //*************************************************************************************************
890 
891 
892 //*************************************************************************************************
905 template< typename Type // Data type of the matrix
906  , bool SO > // Storage order
908  CompressedMatrix<Type,SO>::at( size_t i, size_t j )
909 {
910  if( i >= m_ ) {
911  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
912  }
913  if( j >= n_ ) {
914  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
915  }
916  return (*this)(i,j);
917 }
918 //*************************************************************************************************
919 
920 
921 //*************************************************************************************************
932 template< typename Type // Data type of the matrix
933  , bool SO > // Storage order
935  CompressedMatrix<Type,SO>::at( size_t i, size_t j ) const
936 {
937  if( i >= m_ ) {
938  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
939  }
940  if( j >= n_ ) {
941  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
942  }
943  return (*this)(i,j);
944 }
945 //*************************************************************************************************
946 
947 
948 //*************************************************************************************************
959 template< typename Type // Data type of the matrix
960  , bool SO > // Storage order
962  CompressedMatrix<Type,SO>::begin( size_t i ) noexcept
963 {
964  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
965  return begin_[i];
966 }
967 //*************************************************************************************************
968 
969 
970 //*************************************************************************************************
981 template< typename Type // Data type of the matrix
982  , bool SO > // Storage order
984  CompressedMatrix<Type,SO>::begin( size_t i ) const noexcept
985 {
986  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
987  return begin_[i];
988 }
989 //*************************************************************************************************
990 
991 
992 //*************************************************************************************************
1003 template< typename Type // Data type of the matrix
1004  , bool SO > // Storage order
1006  CompressedMatrix<Type,SO>::cbegin( size_t i ) const noexcept
1007 {
1008  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1009  return begin_[i];
1010 }
1011 //*************************************************************************************************
1012 
1013 
1014 //*************************************************************************************************
1025 template< typename Type // Data type of the matrix
1026  , bool SO > // Storage order
1028  CompressedMatrix<Type,SO>::end( size_t i ) noexcept
1029 {
1030  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1031  return end_[i];
1032 }
1033 //*************************************************************************************************
1034 
1035 
1036 //*************************************************************************************************
1047 template< typename Type // Data type of the matrix
1048  , bool SO > // Storage order
1050  CompressedMatrix<Type,SO>::end( size_t i ) const noexcept
1051 {
1052  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1053  return end_[i];
1054 }
1055 //*************************************************************************************************
1056 
1057 
1058 //*************************************************************************************************
1069 template< typename Type // Data type of the matrix
1070  , bool SO > // Storage order
1072  CompressedMatrix<Type,SO>::cend( size_t i ) const noexcept
1073 {
1074  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1075  return end_[i];
1076 }
1077 //*************************************************************************************************
1078 
1079 
1080 
1081 
1082 //=================================================================================================
1083 //
1084 // ASSIGNMENT OPERATORS
1085 //
1086 //=================================================================================================
1087 
1088 //*************************************************************************************************
1109 template< typename Type // Data type of the matrix
1110  , bool SO > // Storage order
1113 {
1114  using blaze::nonZeros;
1115 
1116  resize( list.size(), determineColumns( list ), false );
1117  reserve( nonZeros( list ) );
1118 
1119  size_t i( 0UL );
1120 
1121  for( const auto& rowList : list )
1122  {
1123  size_t j( 0UL );
1124 
1125  for( const Type& element : rowList ) {
1126  if( !isDefault<strict>( element ) )
1127  append( i, j, element );
1128  ++j;
1129  }
1130 
1131  finalize( i );
1132  ++i;
1133  }
1134 
1135  return *this;
1136 }
1137 //*************************************************************************************************
1138 
1139 
1140 //*************************************************************************************************
1149 template< typename Type // Data type of the matrix
1150  , bool SO > // Storage order
1153 {
1154  using std::swap;
1155 
1156  if( &rhs == this ) return *this;
1157 
1158  const size_t nonzeros( rhs.nonZeros() );
1159 
1160  if( rhs.m_ > capacity_ || nonzeros > capacity() )
1161  {
1162  Iterator* newBegin( new Iterator[2UL*rhs.m_+2UL] );
1163  Iterator* newEnd ( newBegin+(rhs.m_+1UL) );
1164 
1165  newBegin[0UL] = allocate<Element>( nonzeros );
1166  for( size_t i=0UL; i<rhs.m_; ++i ) {
1167  newEnd[i] = castDown( std::copy( rhs.begin_[i], rhs.end_[i], castUp( newBegin[i] ) ) );
1168  newBegin[i+1UL] = newEnd[i];
1169  }
1170  newEnd[rhs.m_] = newBegin[0UL]+nonzeros;
1171 
1172  swap( begin_, newBegin );
1173  end_ = newEnd;
1174  capacity_ = rhs.m_;
1175 
1176  if( newBegin != nullptr ) {
1177  deallocate( newBegin[0UL] );
1178  delete[] newBegin;
1179  }
1180  }
1181  else {
1182  for( size_t i=0UL; i<rhs.m_; ++i ) {
1183  end_[i] = castDown( std::copy( rhs.begin_[i], rhs.end_[i], castUp( begin_[i] ) ) );
1184  begin_[i+1UL] = end_[i];
1185  }
1186  }
1187 
1188  m_ = rhs.m_;
1189  n_ = rhs.n_;
1190 
1191  return *this;
1192 }
1193 //*************************************************************************************************
1194 
1195 
1196 //*************************************************************************************************
1202 template< typename Type // Data type of the matrix
1203  , bool SO > // Storage order
1206 {
1207  if( begin_ != nullptr ) {
1208  deallocate( begin_[0UL] );
1209  delete[] begin_;
1210  }
1211 
1212  m_ = rhs.m_;
1213  n_ = rhs.n_;
1214  capacity_ = rhs.capacity_;
1215  begin_ = rhs.begin_;
1216  end_ = rhs.end_;
1217 
1218  rhs.m_ = 0UL;
1219  rhs.n_ = 0UL;
1220  rhs.capacity_ = 0UL;
1221  rhs.begin_ = nullptr;
1222  rhs.end_ = nullptr;
1223 
1224  return *this;
1225 }
1226 //*************************************************************************************************
1227 
1228 
1229 //*************************************************************************************************
1238 template< typename Type // Data type of the matrix
1239  , bool SO > // Storage order
1240 template< typename MT // Type of the right-hand side dense matrix
1241  , bool SO2 > // Storage order of the right-hand side dense matrix
1244 {
1245  using blaze::assign;
1246 
1247  if( (~rhs).canAlias( this ) ) {
1248  CompressedMatrix tmp( ~rhs );
1249  swap( tmp );
1250  }
1251  else {
1252  resize( (~rhs).rows(), (~rhs).columns(), false );
1253  assign( *this, ~rhs );
1254  }
1255 
1256  return *this;
1257 }
1258 //*************************************************************************************************
1259 
1260 
1261 //*************************************************************************************************
1270 template< typename Type // Data type of the matrix
1271  , bool SO > // Storage order
1272 template< typename MT // Type of the right-hand side compressed matrix
1273  , bool SO2 > // Storage order of the right-hand side compressed matrix
1276 {
1277  using blaze::assign;
1278 
1279  if( (~rhs).canAlias( this ) ||
1280  (~rhs).rows() > capacity_ ||
1281  (~rhs).nonZeros() > capacity() ) {
1282  CompressedMatrix tmp( ~rhs );
1283  swap( tmp );
1284  }
1285  else {
1286  resize( (~rhs).rows(), (~rhs).columns(), false );
1287  reset();
1288 
1289  if( !IsZero_v<MT> ) {
1290  assign( *this, ~rhs );
1291  }
1292  }
1293 
1294  return *this;
1295 }
1296 //*************************************************************************************************
1297 
1298 
1299 //*************************************************************************************************
1309 template< typename Type // Data type of the matrix
1310  , bool SO > // Storage order
1311 template< typename MT // Type of the right-hand side matrix
1312  , bool SO2 > // Storage order of the right-hand side matrix
1315 {
1316  using blaze::addAssign;
1317 
1318  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1319  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1320  }
1321 
1322  if( !IsZero_v<MT> ) {
1323  addAssign( *this, ~rhs );
1324  }
1325 
1326  return *this;
1327 }
1328 //*************************************************************************************************
1329 
1330 
1331 //*************************************************************************************************
1341 template< typename Type // Data type of the matrix
1342  , bool SO > // Storage order
1343 template< typename MT // Type of the right-hand side matrix
1344  , bool SO2 > // Storage order of the right-hand side matrix
1346 {
1347  using blaze::subAssign;
1348 
1349  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1350  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1351  }
1352 
1353  if( !IsZero_v<MT> ) {
1354  subAssign( *this, ~rhs );
1355  }
1356 
1357  return *this;
1358 }
1359 //*************************************************************************************************
1360 
1361 
1362 //*************************************************************************************************
1373 template< typename Type // Data type of the matrix
1374  , bool SO > // Storage order
1375 template< typename MT // Type of the right-hand side dense matrix
1376  , bool SO2 > // Storage order of the right-hand side dense matrix
1379 {
1380  using blaze::schurAssign;
1381 
1382  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1383  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1384  }
1385 
1386  if( (~rhs).canAlias( this ) ) {
1387  CompressedMatrix tmp( *this % (~rhs) );
1388  swap( tmp );
1389  }
1390  else {
1391  CompositeType_t<MT> tmp( ~rhs );
1392  schurAssign( *this, tmp );
1393  }
1394 
1395  return *this;
1396 }
1397 //*************************************************************************************************
1398 
1399 
1400 //*************************************************************************************************
1411 template< typename Type // Data type of the matrix
1412  , bool SO > // Storage order
1413 template< typename MT // Type of the right-hand side sparse matrix
1414  , bool SO2 > // Storage order of the right-hand side sparse matrix
1417 {
1418  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1419  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1420  }
1421 
1422  if( !IsZero_v<MT> ) {
1423  CompressedMatrix tmp( *this % (~rhs) );
1424  swap( tmp );
1425  }
1426  else {
1427  reset();
1428  }
1429 
1430  return *this;
1431 }
1432 //*************************************************************************************************
1433 
1434 
1435 
1436 
1437 //=================================================================================================
1438 //
1439 // UTILITY FUNCTIONS
1440 //
1441 //=================================================================================================
1442 
1443 //*************************************************************************************************
1448 template< typename Type // Data type of the matrix
1449  , bool SO > // Storage order
1450 inline size_t CompressedMatrix<Type,SO>::rows() const noexcept
1451 {
1452  return m_;
1453 }
1454 //*************************************************************************************************
1455 
1456 
1457 //*************************************************************************************************
1462 template< typename Type // Data type of the matrix
1463  , bool SO > // Storage order
1464 inline size_t CompressedMatrix<Type,SO>::columns() const noexcept
1465 {
1466  return n_;
1467 }
1468 //*************************************************************************************************
1469 
1470 
1471 //*************************************************************************************************
1476 template< typename Type // Data type of the matrix
1477  , bool SO > // Storage order
1478 inline size_t CompressedMatrix<Type,SO>::capacity() const noexcept
1479 {
1480  if( begin_ != nullptr )
1481  return end_[m_] - begin_[0UL];
1482  else return 0UL;
1483 }
1484 //*************************************************************************************************
1485 
1486 
1487 //*************************************************************************************************
1498 template< typename Type // Data type of the matrix
1499  , bool SO > // Storage order
1500 inline size_t CompressedMatrix<Type,SO>::capacity( size_t i ) const noexcept
1501 {
1502  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1503  return begin_[i+1UL] - begin_[i];
1504 }
1505 //*************************************************************************************************
1506 
1507 
1508 //*************************************************************************************************
1513 template< typename Type // Data type of the matrix
1514  , bool SO > // Storage order
1516 {
1517  size_t nonzeros( 0UL );
1518 
1519  for( size_t i=0UL; i<m_; ++i )
1520  nonzeros += nonZeros( i );
1521 
1522  return nonzeros;
1523 }
1524 //*************************************************************************************************
1525 
1526 
1527 //*************************************************************************************************
1538 template< typename Type // Data type of the matrix
1539  , bool SO > // Storage order
1540 inline size_t CompressedMatrix<Type,SO>::nonZeros( size_t i ) const
1541 {
1542  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1543  return end_[i] - begin_[i];
1544 }
1545 //*************************************************************************************************
1546 
1547 
1548 //*************************************************************************************************
1553 template< typename Type // Data type of the matrix
1554  , bool SO > // Storage order
1556 {
1557  for( size_t i=0UL; i<m_; ++i )
1558  end_[i] = begin_[i];
1559 }
1560 //*************************************************************************************************
1561 
1562 
1563 //*************************************************************************************************
1574 template< typename Type // Data type of the matrix
1575  , bool SO > // Storage order
1576 inline void CompressedMatrix<Type,SO>::reset( size_t i )
1577 {
1578  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1579  end_[i] = begin_[i];
1580 }
1581 //*************************************************************************************************
1582 
1583 
1584 //*************************************************************************************************
1591 template< typename Type // Data type of the matrix
1592  , bool SO > // Storage order
1594 {
1595  if( end_ != nullptr )
1596  end_[0UL] = end_[m_];
1597  m_ = 0UL;
1598  n_ = 0UL;
1599 }
1600 //*************************************************************************************************
1601 
1602 
1603 //*************************************************************************************************
1618 template< typename Type // Data type of the matrix
1619  , bool SO > // Storage order
1620 void CompressedMatrix<Type,SO>::resize( size_t m, size_t n, bool preserve )
1621 {
1622  using std::swap;
1623 
1624  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1625  BLAZE_INTERNAL_ASSERT( begin_ == nullptr || size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1626 
1627  if( m == m_ && n == n_ ) return;
1628 
1629  if( begin_ == nullptr )
1630  {
1631  begin_ = new Iterator[2UL*m+2UL];
1632  end_ = begin_+m+1UL;
1633 
1634  for( size_t i=0UL; i<2UL*m+2UL; ++i ) {
1635  begin_[i] = nullptr;
1636  }
1637 
1638  capacity_ = m;
1639  }
1640  else if( m > capacity_ )
1641  {
1642  Iterator* newBegin( new Iterator[2UL*m+2UL] );
1643  Iterator* newEnd ( newBegin+m+1UL );
1644 
1645  newBegin[0UL] = begin_[0UL];
1646 
1647  if( preserve ) {
1648  for( size_t i=0UL; i<m_; ++i ) {
1649  newEnd [i] = end_ [i];
1650  newBegin[i+1UL] = begin_[i+1UL];
1651  }
1652  for( size_t i=m_; i<m; ++i ) {
1653  newBegin[i+1UL] = newEnd[i] = begin_[m_];
1654  }
1655  }
1656  else {
1657  for( size_t i=0UL; i<m; ++i ) {
1658  newBegin[i+1UL] = newEnd[i] = begin_[0UL];
1659  }
1660  }
1661 
1662  newEnd[m] = end_[m_];
1663 
1664  swap( newBegin, begin_ );
1665  delete[] newBegin;
1666  end_ = newEnd;
1667  capacity_ = m;
1668  }
1669  else if( m > m_ )
1670  {
1671  end_[m] = end_[m_];
1672 
1673  if( !preserve ) {
1674  for( size_t i=0UL; i<m_; ++i )
1675  end_[i] = begin_[i];
1676  }
1677 
1678  for( size_t i=m_; i<m; ++i ) {
1679  begin_[i+1UL] = end_[i] = begin_[m_];
1680  }
1681  }
1682  else
1683  {
1684  if( preserve ) {
1685  for( size_t i=0UL; i<m; ++i )
1686  end_[i] = lowerBound( i, n );
1687  }
1688  else {
1689  for( size_t i=0UL; i<m; ++i )
1690  end_[i] = begin_[i];
1691  }
1692 
1693  end_[m] = end_[m_];
1694  }
1695 
1696  m_ = m;
1697  n_ = n;
1698 
1699  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1700  BLAZE_INTERNAL_ASSERT( size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1701 }
1702 //*************************************************************************************************
1703 
1704 
1705 //*************************************************************************************************
1715 template< typename Type // Data type of the matrix
1716  , bool SO > // Storage order
1717 inline void CompressedMatrix<Type,SO>::reserve( size_t nonzeros )
1718 {
1719  if( nonzeros > capacity() )
1720  reserveElements( nonzeros );
1721 }
1722 //*************************************************************************************************
1723 
1724 
1725 //*************************************************************************************************
1739 template< typename Type // Data type of the matrix
1740  , bool SO > // Storage order
1741 void CompressedMatrix<Type,SO>::reserve( size_t i, size_t nonzeros )
1742 {
1743  using std::swap;
1744 
1745  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1746 
1747  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1748  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1749 
1750  const size_t current( capacity(i) );
1751 
1752  if( current >= nonzeros ) return;
1753 
1754  const ptrdiff_t additional( nonzeros - current );
1755 
1756  if( end_[m_] - begin_[m_] < additional )
1757  {
1758  const size_t newCapacity( begin_[m_] - begin_[0UL] + additional );
1759  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
1760 
1761  Iterator* newBegin( new Iterator[2UL*m_+2UL] );
1762  Iterator* newEnd ( newBegin+m_+1UL );
1763 
1764  newBegin[0UL] = allocate<Element>( newCapacity );
1765  newEnd [m_ ] = newBegin[0UL]+newCapacity;
1766 
1767  for( size_t k=0UL; k<i; ++k ) {
1768  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
1769  newBegin[k+1UL] = newBegin[k] + capacity(k);
1770  }
1771  newEnd [i ] = castDown( transfer( begin_[i], end_[i], castUp( newBegin[i] ) ) );
1772  newBegin[i+1UL] = newBegin[i] + nonzeros;
1773  for( size_t k=i+1UL; k<m_; ++k ) {
1774  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
1775  newBegin[k+1UL] = newBegin[k] + capacity(k);
1776  }
1777 
1778  BLAZE_INTERNAL_ASSERT( newBegin[m_] == newEnd[m_], "Invalid pointer calculations" );
1779 
1780  swap( newBegin, begin_ );
1781  deallocate( newBegin[0UL] );
1782  delete[] newBegin;
1783  end_ = newEnd;
1784  capacity_ = m_;
1785  }
1786  else
1787  {
1788  begin_[m_] += additional;
1789  for( size_t j=m_-1UL; j>i; --j ) {
1790  begin_[j] = castDown( std::move_backward( begin_[j], end_[j], castUp( end_[j]+additional ) ) );
1791  end_ [j] += additional;
1792  }
1793  }
1794 
1795  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1796  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1797 }
1798 //*************************************************************************************************
1799 
1800 
1801 //*************************************************************************************************
1811 template< typename Type // Data type of the matrix
1812  , bool SO > // Storage order
1814 {
1815  for( size_t i=0UL; i<m_; ++i )
1816  trim( i );
1817 }
1818 //*************************************************************************************************
1819 
1820 
1821 //*************************************************************************************************
1832 template< typename Type // Data type of the matrix
1833  , bool SO > // Storage order
1834 inline void CompressedMatrix<Type,SO>::trim( size_t i )
1835 {
1836  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1837 
1838  if( i < ( m_ - 1UL ) )
1839  end_[i+1] = castDown( std::move( begin_[i+1], end_[i+1], castUp( end_[i] ) ) );
1840  begin_[i+1] = end_[i];
1841 }
1842 //*************************************************************************************************
1843 
1844 
1845 //*************************************************************************************************
1854 template< typename Type // Data type of the matrix
1855  , bool SO > // Storage order
1857 {
1858  if( nonZeros() < capacity() ) {
1859  CompressedMatrix( *this ).swap( *this );
1860  }
1861 }
1862 //*************************************************************************************************
1863 
1864 
1865 //*************************************************************************************************
1871 template< typename Type // Data type of the matrix
1872  , bool SO > // Storage order
1874 {
1875  using std::swap;
1876 
1877  swap( m_, sm.m_ );
1878  swap( n_, sm.n_ );
1879  swap( capacity_, sm.capacity_ );
1880  swap( begin_, sm.begin_ );
1881  swap( end_ , sm.end_ );
1882 }
1883 //*************************************************************************************************
1884 
1885 
1886 //*************************************************************************************************
1894 template< typename Type // Data type of the matrix
1895  , bool SO > // Storage order
1896 inline size_t CompressedMatrix<Type,SO>::extendCapacity() const noexcept
1897 {
1898  size_t nonzeros( 2UL*capacity()+1UL );
1899  nonzeros = blaze::max( nonzeros, 7UL );
1900 
1901  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
1902 
1903  return nonzeros;
1904 }
1905 //*************************************************************************************************
1906 
1907 
1908 //*************************************************************************************************
1914 template< typename Type // Data type of the matrix
1915  , bool SO > // Storage order
1917 {
1918  using std::swap;
1919 
1920  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1921  Iterator* newEnd = newBegin+capacity_+1UL;
1922 
1923  newBegin[0UL] = allocate<Element>( nonzeros );
1924 
1925  for( size_t k=0UL; k<m_; ++k ) {
1926  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid row pointers" );
1927  newEnd [k] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
1928  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
1929  }
1930 
1931  newEnd[m_] = newBegin[0UL]+nonzeros;
1932 
1933  swap( newBegin, begin_ );
1934  end_ = newEnd;
1935 
1936  if( newBegin != nullptr ) {
1937  deallocate( newBegin[0UL] );
1938  delete[] newBegin;
1939  }
1940 }
1941 //*************************************************************************************************
1942 
1943 
1944 //*************************************************************************************************
1952 template< typename Type // Data type of the matrix
1953  , bool SO > // Storage order
1956 {
1957  return static_cast<Iterator>( it );
1958 }
1959 //*************************************************************************************************
1960 
1961 
1962 //*************************************************************************************************
1970 template< typename Type // Data type of the matrix
1971  , bool SO > // Storage order
1974 {
1975  return static_cast<IteratorBase>( it );
1976 }
1977 //*************************************************************************************************
1978 
1979 
1980 
1981 
1982 //=================================================================================================
1983 //
1984 // INSERTION FUNCTIONS
1985 //
1986 //=================================================================================================
1987 
1988 //*************************************************************************************************
2000 template< typename Type // Data type of the matrix
2001  , bool SO > // Storage order
2003  CompressedMatrix<Type,SO>::set( size_t i, size_t j, const Type& value )
2004 {
2005  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2006  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2007 
2008  const Iterator pos( lowerBound( i, j ) );
2009 
2010  if( pos != end_[i] && pos->index_ == j ) {
2011  pos->value() = value;
2012  return pos;
2013  }
2014  else return insert( pos, i, j, value );
2015 }
2016 //*************************************************************************************************
2017 
2018 
2019 //*************************************************************************************************
2032 template< typename Type // Data type of the matrix
2033  , bool SO > // Storage order
2035  CompressedMatrix<Type,SO>::insert( size_t i, size_t j, const Type& value )
2036 {
2037  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2038  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2039 
2040  const Iterator pos( lowerBound( i, j ) );
2041 
2042  if( pos != end_[i] && pos->index_ == j ) {
2043  BLAZE_THROW_INVALID_ARGUMENT( "Bad access index" );
2044  }
2045 
2046  return insert( pos, i, j, value );
2047 }
2048 //*************************************************************************************************
2049 
2050 
2051 //*************************************************************************************************
2061 template< typename Type // Data type of the matrix
2062  , bool SO > // Storage order
2064  CompressedMatrix<Type,SO>::insert( Iterator pos, size_t i, size_t j, const Type& value )
2065 {
2066  using std::swap;
2067 
2068  if( begin_[i+1UL] - end_[i] != 0 ) {
2069  std::move_backward( pos, end_[i], castUp( end_[i]+1UL ) );
2070  pos->value_ = value;
2071  pos->index_ = j;
2072  ++end_[i];
2073 
2074  return pos;
2075  }
2076  else if( end_[m_] - begin_[m_] != 0 ) {
2077  std::move_backward( pos, end_[m_-1UL], castUp( end_[m_-1UL]+1UL ) );
2078 
2079  pos->value_ = value;
2080  pos->index_ = j;
2081 
2082  for( size_t k=i+1UL; k<m_+1UL; ++k ) {
2083  ++begin_[k];
2084  ++end_[k-1UL];
2085  }
2086 
2087  return pos;
2088  }
2089  else {
2090  size_t newCapacity( extendCapacity() );
2091 
2092  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
2093  Iterator* newEnd = newBegin+capacity_+1UL;
2094 
2095  newBegin[0UL] = allocate<Element>( newCapacity );
2096 
2097  for( size_t k=0UL; k<i; ++k ) {
2098  const size_t nonzeros( end_[k] - begin_[k] );
2099  const size_t total( begin_[k+1UL] - begin_[k] );
2100  newEnd [k] = newBegin[k] + nonzeros;
2101  newBegin[k+1UL] = newBegin[k] + total;
2102  }
2103  newEnd [i] = newBegin[i] + ( end_[i] - begin_[i] ) + 1;
2104  newBegin[i+1UL] = newBegin[i] + ( begin_[i+1] - begin_[i] ) + 1;
2105  for( size_t k=i+1UL; k<m_; ++k ) {
2106  const size_t nonzeros( end_[k] - begin_[k] );
2107  const size_t total( begin_[k+1UL] - begin_[k] );
2108  newEnd [k] = newBegin[k] + nonzeros;
2109  newBegin[k+1UL] = newBegin[k] + total;
2110  }
2111 
2112  newEnd[m_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
2113 
2114  Iterator tmp = castDown( std::move( begin_[0UL], pos, castUp( newBegin[0UL] ) ) );
2115  tmp->value_ = value;
2116  tmp->index_ = j;
2117  std::move( pos, end_[m_-1UL], castUp( tmp+1UL ) );
2118 
2119  swap( newBegin, begin_ );
2120  end_ = newEnd;
2121  deallocate( newBegin[0UL] );
2122  delete[] newBegin;
2123 
2124  return tmp;
2125  }
2126 }
2127 //*************************************************************************************************
2128 
2129 
2130 //*************************************************************************************************
2183 template< typename Type // Data type of the matrix
2184  , bool SO > // Storage order
2185 inline void CompressedMatrix<Type,SO>::append( size_t i, size_t j, const Type& value, bool check )
2186 {
2187  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2188  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
2189  BLAZE_USER_ASSERT( end_[i] < end_[m_], "Not enough reserved capacity left" );
2190  BLAZE_USER_ASSERT( begin_[i] == end_[i] || j > ( end_[i]-1UL )->index_, "Index is not strictly increasing" );
2191 
2192  end_[i]->value_ = value;
2193 
2194  if( !check || !isDefault<strict>( end_[i]->value_ ) ) {
2195  end_[i]->index_ = j;
2196  ++end_[i];
2197  }
2198 }
2199 //*************************************************************************************************
2200 
2201 
2202 //*************************************************************************************************
2215 template< typename Type // Data type of the matrix
2216  , bool SO > // Storage order
2218 {
2219  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2220 
2221  begin_[i+1UL] = end_[i];
2222  if( i != m_-1UL )
2223  end_[i+1UL] = end_[i];
2224 }
2225 //*************************************************************************************************
2226 
2227 
2228 
2229 
2230 //=================================================================================================
2231 //
2232 // ERASE FUNCTIONS
2233 //
2234 //=================================================================================================
2235 
2236 //*************************************************************************************************
2245 template< typename Type // Data type of the matrix
2246  , bool SO > // Storage order
2247 inline void CompressedMatrix<Type,SO>::erase( size_t i, size_t j )
2248 {
2249  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2250  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2251 
2252  const Iterator pos( find( i, j ) );
2253  if( pos != end_[i] )
2254  end_[i] = castDown( std::move( pos+1, end_[i], castUp( pos ) ) );
2255 }
2256 //*************************************************************************************************
2257 
2258 
2259 //*************************************************************************************************
2270 template< typename Type // Data type of the matrix
2271  , bool SO > // Storage order
2274 {
2275  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2276  BLAZE_USER_ASSERT( pos >= begin_[i] && pos <= end_[i], "Invalid compressed matrix iterator" );
2277 
2278  if( pos != end_[i] )
2279  end_[i] = castDown( std::move( pos+1, end_[i], castUp( pos ) ) );
2280 
2281  return pos;
2282 }
2283 //*************************************************************************************************
2284 
2285 
2286 //*************************************************************************************************
2298 template< typename Type // Data type of the matrix
2299  , bool SO > // Storage order
2302 {
2303  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2304  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
2305  BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i], "Invalid compressed matrix iterator" );
2306  BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i], "Invalid compressed matrix iterator" );
2307 
2308  if( first != last )
2309  end_[i] = castDown( std::move( last, end_[i], castUp( first ) ) );
2310 
2311  return first;
2312 }
2313 //*************************************************************************************************
2314 
2315 
2316 //*************************************************************************************************
2337 template< typename Type // Data type of the matrix
2338  , bool SO > // Storage order
2339 template< typename Pred > // Type of the unary predicate
2340 inline void CompressedMatrix<Type,SO>::erase( Pred predicate )
2341 {
2342  for( size_t i=0UL; i<m_; ++i ) {
2343  end_[i] = castDown( std::remove_if( castUp( begin_[i] ), castUp( end_[i] ),
2344  [predicate=predicate]( const ElementBase& element) {
2345  return predicate( element.value() );
2346  } ) );
2347  }
2348 }
2349 //*************************************************************************************************
2350 
2351 
2352 //*************************************************************************************************
2379 template< typename Type // Data type of the matrix
2380  , bool SO > // Storage order
2381 template< typename Pred > // Type of the unary predicate
2382 inline void CompressedMatrix<Type,SO>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
2383 {
2384  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2385  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
2386  BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i], "Invalid compressed matrix iterator" );
2387  BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i], "Invalid compressed matrix iterator" );
2388 
2389  const auto pos = std::remove_if( castUp( first ), castUp( last ),
2390  [predicate=predicate]( const ElementBase& element ) {
2391  return predicate( element.value() );
2392  } );
2393 
2394  end_[i] = castDown( std::move( last, end_[i], pos ) );
2395 }
2396 //*************************************************************************************************
2397 
2398 
2399 
2400 
2401 //=================================================================================================
2402 //
2403 // LOOKUP FUNCTIONS
2404 //
2405 //=================================================================================================
2406 
2407 //*************************************************************************************************
2422 template< typename Type // Data type of the matrix
2423  , bool SO > // Storage order
2425  CompressedMatrix<Type,SO>::find( size_t i, size_t j )
2426 {
2427  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
2428 }
2429 //*************************************************************************************************
2430 
2431 
2432 //*************************************************************************************************
2447 template< typename Type // Data type of the matrix
2448  , bool SO > // Storage order
2450  CompressedMatrix<Type,SO>::find( size_t i, size_t j ) const
2451 {
2452  const ConstIterator pos( lowerBound( i, j ) );
2453  if( pos != end_[i] && pos->index_ == j )
2454  return pos;
2455  else return end_[i];
2456 }
2457 //*************************************************************************************************
2458 
2459 
2460 //*************************************************************************************************
2475 template< typename Type // Data type of the matrix
2476  , bool SO > // Storage order
2479 {
2480  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
2481 }
2482 //*************************************************************************************************
2483 
2484 
2485 //*************************************************************************************************
2500 template< typename Type // Data type of the matrix
2501  , bool SO > // Storage order
2503  CompressedMatrix<Type,SO>::lowerBound( size_t i, size_t j ) const
2504 {
2505  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2506  return std::lower_bound( begin_[i], end_[i], j,
2507  []( const Element& element, size_t index )
2508  {
2509  return element.index() < index;
2510  } );
2511 }
2512 //*************************************************************************************************
2513 
2514 
2515 //*************************************************************************************************
2530 template< typename Type // Data type of the matrix
2531  , bool SO > // Storage order
2534 {
2535  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
2536 }
2537 //*************************************************************************************************
2538 
2539 
2540 //*************************************************************************************************
2555 template< typename Type // Data type of the matrix
2556  , bool SO > // Storage order
2558  CompressedMatrix<Type,SO>::upperBound( size_t i, size_t j ) const
2559 {
2560  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2561  return std::upper_bound( begin_[i], end_[i], j,
2562  []( size_t index, const Element& element )
2563  {
2564  return index < element.index();
2565  } );
2566 }
2567 //*************************************************************************************************
2568 
2569 
2570 
2571 
2572 //=================================================================================================
2573 //
2574 // NUMERIC FUNCTIONS
2575 //
2576 //=================================================================================================
2577 
2578 //*************************************************************************************************
2583 template< typename Type // Data type of the matrix
2584  , bool SO > // Storage order
2586 {
2587  CompressedMatrix tmp( trans( *this ) );
2588  swap( tmp );
2589  return *this;
2590 }
2591 //*************************************************************************************************
2592 
2593 
2594 //*************************************************************************************************
2599 template< typename Type // Data type of the matrix
2600  , bool SO > // Storage order
2602 {
2603  CompressedMatrix tmp( ctrans( *this ) );
2604  swap( tmp );
2605  return *this;
2606 }
2607 //*************************************************************************************************
2608 
2609 
2610 //*************************************************************************************************
2627 template< typename Type // Data type of the matrix
2628  , bool SO > // Storage order
2629 template< typename Other > // Data type of the scalar value
2631 {
2632  for( size_t i=0UL; i<m_; ++i )
2633  for( auto element=begin_[i]; element!=end_[i]; ++element )
2634  element->value_ *= scalar;
2635 
2636  return *this;
2637 }
2638 //*************************************************************************************************
2639 
2640 
2641 
2642 
2643 //=================================================================================================
2644 //
2645 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2646 //
2647 //=================================================================================================
2648 
2649 //*************************************************************************************************
2659 template< typename Type // Data type of the matrix
2660  , bool SO > // Storage order
2661 template< typename Other > // Data type of the foreign expression
2662 inline bool CompressedMatrix<Type,SO>::canAlias( const Other* alias ) const noexcept
2663 {
2664  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2665 }
2666 //*************************************************************************************************
2667 
2668 
2669 //*************************************************************************************************
2679 template< typename Type // Data type of the matrix
2680  , bool SO > // Storage order
2681 template< typename Other > // Data type of the foreign expression
2682 inline bool CompressedMatrix<Type,SO>::isAliased( const Other* alias ) const noexcept
2683 {
2684  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2685 }
2686 //*************************************************************************************************
2687 
2688 
2689 //*************************************************************************************************
2699 template< typename Type // Data type of the matrix
2700  , bool SO > // Storage order
2701 inline bool CompressedMatrix<Type,SO>::canSMPAssign() const noexcept
2702 {
2703  return false;
2704 }
2705 //*************************************************************************************************
2706 
2707 
2708 //*************************************************************************************************
2719 template< typename Type // Data type of the matrix
2720  , bool SO > // Storage order
2721 template< typename MT // Type of the right-hand side dense matrix
2722  , bool SO2 > // Storage order of the right-hand side dense matrix
2724 {
2725  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2726  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2727 
2728  if( m_ == 0UL || n_ == 0UL )
2729  return;
2730 
2731  size_t nonzeros( 0UL );
2732 
2733  for( size_t i=1UL; i<=m_; ++i )
2734  begin_[i] = end_[i] = end_[m_];
2735 
2736  for( size_t i=0UL; i<m_; ++i )
2737  {
2738  begin_[i] = end_[i] = begin_[0UL]+nonzeros;
2739 
2740  const size_t jbegin( ( IsUpper_v<MT> )
2741  ?( IsStrictlyUpper_v<MT> ? i+1UL : i )
2742  :( 0UL ) );
2743  const size_t jend ( ( IsLower_v<MT> )
2744  ?( IsStrictlyLower_v<MT> ? i : i+1UL )
2745  :( n_ ) );
2746 
2747  for( size_t j=jbegin; j<jend; ++j )
2748  {
2749  if( nonzeros == capacity() ) {
2750  reserveElements( extendCapacity() );
2751  for( size_t k=i+1UL; k<=m_; ++k )
2752  begin_[k] = end_[k] = end_[m_];
2753  }
2754 
2755  end_[i]->value_ = (~rhs)(i,j);
2756 
2757  if( !isDefault<strict>( end_[i]->value_ ) ) {
2758  end_[i]->index_ = j;
2759  ++end_[i];
2760  ++nonzeros;
2761  }
2762  }
2763  }
2764 
2765  begin_[m_] = begin_[0UL]+nonzeros;
2766 }
2767 //*************************************************************************************************
2768 
2769 
2770 //*************************************************************************************************
2781 template< typename Type // Data type of the matrix
2782  , bool SO > // Storage order
2783 template< typename MT > // Type of the right-hand side compressed matrix
2785 {
2786  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2787  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2788  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2789  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
2790 
2791  if( m_ == 0UL || begin_[0] == nullptr )
2792  return;
2793 
2794  for( size_t i=0UL; i<m_; ++i ) {
2795  end_[i] = castDown( std::copy( (~rhs).begin(i), (~rhs).end(i), castUp( begin_[i] ) ) );
2796  begin_[i+1UL] = end_[i];
2797  }
2798 }
2799 //*************************************************************************************************
2800 
2801 
2802 //*************************************************************************************************
2813 template< typename Type // Data type of the matrix
2814  , bool SO > // Storage order
2815 template< typename MT > // Type of the right-hand side compressed matrix
2817 {
2819 
2820  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2821  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2822  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2823  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
2824 
2825  // Counting the number of elements per row
2826  std::vector<size_t> rowLengths( m_, 0UL );
2827  for( size_t j=0UL; j<n_; ++j ) {
2828  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2829  ++rowLengths[element->index()];
2830  }
2831 
2832  // Resizing the compressed matrix
2833  for( size_t i=0UL; i<m_; ++i ) {
2834  begin_[i+1UL] = end_[i+1UL] = begin_[i] + rowLengths[i];
2835  }
2836 
2837  // Appending the elements to the rows of the compressed matrix
2838  for( size_t j=0UL; j<n_; ++j ) {
2839  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2840  append( element->index(), j, element->value() );
2841  }
2842 }
2843 //*************************************************************************************************
2844 
2845 
2846 //*************************************************************************************************
2857 template< typename Type // Data type of the matrix
2858  , bool SO > // Storage order
2859 template< typename MT // Type of the right-hand side dense matrix
2860  , bool SO2 > // Storage order of the right-hand side dense matrix
2862 {
2863  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2864  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2865 
2866  CompressedMatrix tmp( serial( *this + (~rhs) ) );
2867  swap( tmp );
2868 }
2869 //*************************************************************************************************
2870 
2871 
2872 //*************************************************************************************************
2883 template< typename Type // Data type of the matrix
2884  , bool SO > // Storage order
2885 template< typename MT // Type of the right-hand side compressed matrix
2886  , bool SO2 > // Storage order of the right-hand side compressed matrix
2888 {
2889  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2890  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2891 
2892  CompressedMatrix tmp( serial( *this + (~rhs) ) );
2893  swap( tmp );
2894 }
2895 //*************************************************************************************************
2896 
2897 
2898 //*************************************************************************************************
2909 template< typename Type // Data type of the matrix
2910  , bool SO > // Storage order
2911 template< typename MT // Type of the right-hand side dense matrix
2912  , bool SO2 > // Storage order of the right-hand side dense matrix
2914 {
2915  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2916  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2917 
2918  CompressedMatrix tmp( serial( *this - (~rhs) ) );
2919  swap( tmp );
2920 }
2921 //*************************************************************************************************
2922 
2923 
2924 //*************************************************************************************************
2935 template< typename Type // Data type of the matrix
2936  , bool SO > // Storage order
2937 template< typename MT // Type of the right-hand side compressed matrix
2938  , bool SO2 > // Storage order of the right-hand compressed matrix
2940 {
2941  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2942  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2943 
2944  CompressedMatrix tmp( serial( *this - (~rhs) ) );
2945  swap( tmp );
2946 }
2947 //*************************************************************************************************
2948 
2949 
2950 //*************************************************************************************************
2961 template< typename Type // Data type of the matrix
2962  , bool SO > // Storage order
2963 template< typename MT // Type of the right-hand side dense matrix
2964  , bool SO2 > // Storage order of the right-hand side dense matrix
2966 {
2967  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2968  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2969 
2971 
2972  for( size_t i=0UL; i<m_; ++i ) {
2973  const Iterator last( end(i) );
2974  for( auto element=begin(i); element!=last; ++element )
2975  element->value_ *= (~rhs)(i,element->index_);
2976  }
2977 }
2978 //*************************************************************************************************
2979 
2980 
2981 
2982 
2983 
2984 
2985 
2986 
2987 //=================================================================================================
2988 //
2989 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2990 //
2991 //=================================================================================================
2992 
2993 //*************************************************************************************************
3001 template< typename Type > // Data type of the matrix
3002 class CompressedMatrix<Type,true>
3003  : public SparseMatrix< CompressedMatrix<Type,true>, true >
3004 {
3005  private:
3006  //**Type definitions****************************************************************************
3008  using IteratorBase = ElementBase*;
3009  //**********************************************************************************************
3010 
3011  //**Private class Element***********************************************************************
3017  struct Element
3018  : public ElementBase
3019  {
3020  //**Constructors*****************************************************************************
3021  explicit Element() = default;
3022  Element( const Element& rhs ) = default;
3023  Element( Element&& rhs ) = default;
3024  //*******************************************************************************************
3025 
3026  //**Assignment operators*********************************************************************
3027  inline Element& operator=( const Element& rhs )
3028  {
3029  this->value_ = rhs.value_;
3030  return *this;
3031  }
3032 
3033  inline Element& operator=( Element&& rhs )
3034  {
3035  this->value_ = std::move( rhs.value_ );
3036  return *this;
3037  }
3038 
3039  template< typename Other >
3040  inline auto operator=( const Other& rhs )
3041  -> EnableIf_t< IsSparseElement_v<Other>, Element& >
3042  {
3043  this->value_ = rhs.value();
3044  return *this;
3045  }
3046 
3047  template< typename Other >
3048  inline auto operator=( Other&& rhs )
3049  -> EnableIf_t< IsSparseElement_v< RemoveReference_t<Other> > &&
3050  IsRValueReference_v<Other&&>, Element& >
3051  {
3052  this->value_ = std::move( rhs.value() );
3053  return *this;
3054  }
3055 
3056  template< typename Other >
3057  inline auto operator=( const Other& v )
3058  -> EnableIf_t< !IsSparseElement_v<Other>, Element& >
3059  {
3060  this->value_ = v;
3061  return *this;
3062  }
3063 
3064  template< typename Other >
3065  inline auto operator=( Other&& v )
3066  -> EnableIf_t< !IsSparseElement_v< RemoveReference_t<Other> > &&
3067  IsRValueReference_v<Other&&>, Element& >
3068  {
3069  this->value_ = std::move( v );
3070  return *this;
3071  }
3072  //*******************************************************************************************
3073 
3074  //**Friend declarations**********************************************************************
3075  friend class CompressedMatrix;
3076  //*******************************************************************************************
3077  };
3078  //**********************************************************************************************
3079 
3080  //**Private class Uninitialized*****************************************************************
3083  struct Uninitialized {};
3084  //**********************************************************************************************
3085 
3086  public:
3087  //**Type definitions****************************************************************************
3088  using This = CompressedMatrix<Type,true>;
3089  using BaseType = SparseMatrix<This,true>;
3090  using ResultType = This;
3091  using OppositeType = CompressedMatrix<Type,false>;
3092  using TransposeType = CompressedMatrix<Type,false>;
3093  using ElementType = Type;
3094  using ReturnType = const Type&;
3095  using CompositeType = const This&;
3096  using Reference = MatrixAccessProxy<This>;
3097  using ConstReference = const Type&;
3098  using Iterator = Element*;
3099  using ConstIterator = const Element*;
3100  //**********************************************************************************************
3101 
3102  //**Rebind struct definition********************************************************************
3105  template< typename NewType > // Data type of the other matrix
3106  struct Rebind {
3107  using Other = CompressedMatrix<NewType,true>;
3108  };
3109  //**********************************************************************************************
3110 
3111  //**Resize struct definition********************************************************************
3114  template< size_t NewM // Number of rows of the other matrix
3115  , size_t NewN > // Number of columns of the other matrix
3116  struct Resize {
3117  using Other = CompressedMatrix<Type,true>;
3118  };
3119  //**********************************************************************************************
3120 
3121  //**Compilation flags***************************************************************************
3123 
3126  static constexpr bool smpAssignable = !IsSMPAssignable_v<Type>;
3127  //**********************************************************************************************
3128 
3129  //**Constructors********************************************************************************
3132  explicit inline CompressedMatrix();
3133  explicit inline CompressedMatrix( size_t m, size_t n );
3134  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
3135  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
3136  inline CompressedMatrix( initializer_list< initializer_list<Type> > list );
3137 
3138  inline CompressedMatrix( const CompressedMatrix& sm );
3139  inline CompressedMatrix( CompressedMatrix&& sm ) noexcept;
3140 
3141  template< typename MT, bool SO > inline CompressedMatrix( const DenseMatrix<MT,SO>& dm );
3142  template< typename MT, bool SO > inline CompressedMatrix( const SparseMatrix<MT,SO>& sm );
3144  //**********************************************************************************************
3145 
3146  //**Destructor**********************************************************************************
3149  inline ~CompressedMatrix();
3151  //**********************************************************************************************
3152 
3153  //**Data access functions***********************************************************************
3156  inline Reference operator()( size_t i, size_t j ) noexcept;
3157  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3158  inline Reference at( size_t i, size_t j );
3159  inline ConstReference at( size_t i, size_t j ) const;
3160  inline Iterator begin ( size_t j ) noexcept;
3161  inline ConstIterator begin ( size_t j ) const noexcept;
3162  inline ConstIterator cbegin( size_t j ) const noexcept;
3163  inline Iterator end ( size_t j ) noexcept;
3164  inline ConstIterator end ( size_t j ) const noexcept;
3165  inline ConstIterator cend ( size_t j ) const noexcept;
3167  //**********************************************************************************************
3168 
3169  //**Assignment operators************************************************************************
3172  inline CompressedMatrix& operator=( initializer_list< initializer_list<Type> > list );
3173  inline CompressedMatrix& operator=( const CompressedMatrix& rhs );
3174  inline CompressedMatrix& operator=( CompressedMatrix&& rhs ) noexcept;
3175 
3176  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO>& rhs );
3177  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO>& rhs );
3178  template< typename MT, bool SO > inline CompressedMatrix& operator+=( const Matrix<MT,SO>& rhs );
3179  template< typename MT, bool SO > inline CompressedMatrix& operator-=( const Matrix<MT,SO>& rhs );
3180  template< typename MT, bool SO > inline CompressedMatrix& operator%=( const DenseMatrix<MT,SO>& rhs );
3181  template< typename MT, bool SO > inline CompressedMatrix& operator%=( const SparseMatrix<MT,SO>& rhs );
3183  //**********************************************************************************************
3184 
3185  //**Utility functions***************************************************************************
3188  inline size_t rows() const noexcept;
3189  inline size_t columns() const noexcept;
3190  inline size_t capacity() const noexcept;
3191  inline size_t capacity( size_t j ) const noexcept;
3192  inline size_t nonZeros() const;
3193  inline size_t nonZeros( size_t j ) const;
3194  inline void reset();
3195  inline void reset( size_t j );
3196  inline void clear();
3197  void resize ( size_t m, size_t n, bool preserve=true );
3198  inline void reserve( size_t nonzeros );
3199  void reserve( size_t j, size_t nonzeros );
3200  inline void trim ();
3201  inline void trim ( size_t j );
3202  inline void shrinkToFit();
3203  inline void swap( CompressedMatrix& sm ) noexcept;
3205  //**********************************************************************************************
3206 
3207  //**Insertion functions*************************************************************************
3210  inline Iterator set ( size_t i, size_t j, const Type& value );
3211  inline Iterator insert ( size_t i, size_t j, const Type& value );
3212  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
3213  inline void finalize( size_t j );
3215  //**********************************************************************************************
3216 
3217  //**Erase functions*****************************************************************************
3220  inline void erase( size_t i, size_t j );
3221  inline Iterator erase( size_t j, Iterator pos );
3222  inline Iterator erase( size_t j, Iterator first, Iterator last );
3223 
3224  template< typename Pred >
3225  inline void erase( Pred predicate );
3226 
3227  template< typename Pred >
3228  inline void erase( size_t j, Iterator first, Iterator last, Pred predicate );
3230  //**********************************************************************************************
3231 
3232  //**Lookup functions****************************************************************************
3235  inline Iterator find ( size_t i, size_t j );
3236  inline ConstIterator find ( size_t i, size_t j ) const;
3237  inline Iterator lowerBound( size_t i, size_t j );
3238  inline ConstIterator lowerBound( size_t i, size_t j ) const;
3239  inline Iterator upperBound( size_t i, size_t j );
3240  inline ConstIterator upperBound( size_t i, size_t j ) const;
3242  //**********************************************************************************************
3243 
3244  //**Numeric functions***************************************************************************
3247  inline CompressedMatrix& transpose();
3248  inline CompressedMatrix& ctranspose();
3249 
3250  template< typename Other > inline CompressedMatrix& scale( const Other& scalar );
3252  //**********************************************************************************************
3253 
3254  //**Expression template evaluation functions****************************************************
3257  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3258  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3259 
3260  inline bool canSMPAssign() const noexcept;
3261 
3262  template< typename MT, bool SO > inline void assign ( const DenseMatrix<MT,SO>& rhs );
3263  template< typename MT > inline void assign ( const SparseMatrix<MT,true>& rhs );
3264  template< typename MT > inline void assign ( const SparseMatrix<MT,false>& rhs );
3265  template< typename MT, bool SO > inline void addAssign ( const DenseMatrix<MT,SO>& rhs );
3266  template< typename MT, bool SO > inline void addAssign ( const SparseMatrix<MT,SO>& rhs );
3267  template< typename MT, bool SO > inline void subAssign ( const DenseMatrix<MT,SO>& rhs );
3268  template< typename MT, bool SO > inline void subAssign ( const SparseMatrix<MT,SO>& rhs );
3269  template< typename MT, bool SO > inline void schurAssign( const DenseMatrix<MT,SO>& rhs );
3271  //**********************************************************************************************
3272 
3273  private:
3274  //**Constructors********************************************************************************
3277  explicit inline CompressedMatrix( size_t m, size_t n, Uninitialized );
3279  //**********************************************************************************************
3280 
3281  //**Utility functions***************************************************************************
3284  inline size_t extendCapacity() const noexcept;
3285  void reserveElements( size_t nonzeros );
3286 
3287  inline Iterator castDown( IteratorBase it ) const noexcept;
3288  inline IteratorBase castUp ( Iterator it ) const noexcept;
3290  //**********************************************************************************************
3291 
3292  //**Insertion functions*************************************************************************
3295  Iterator insert( Iterator pos, size_t i, size_t j, const Type& value );
3297  //**********************************************************************************************
3298 
3299  //**Member variables****************************************************************************
3302  size_t m_;
3303  size_t n_;
3304  size_t capacity_;
3305  Iterator* begin_;
3306  Iterator* end_;
3307 
3308  static const Type zero_;
3309 
3310  //**********************************************************************************************
3311 
3312  //**Compile time checks*************************************************************************
3318  //**********************************************************************************************
3319 };
3321 //*************************************************************************************************
3322 
3323 
3324 
3325 
3326 //=================================================================================================
3327 //
3328 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
3329 //
3330 //=================================================================================================
3331 
3332 template< typename Type >
3333 const Type CompressedMatrix<Type,true>::zero_{};
3334 
3335 
3336 
3337 
3338 //=================================================================================================
3339 //
3340 // CONSTRUCTORS
3341 //
3342 //=================================================================================================
3343 
3344 //*************************************************************************************************
3348 template< typename Type > // Data type of the matrix
3350  : m_ ( 0UL ) // The current number of rows of the compressed matrix
3351  , n_ ( 0UL ) // The current number of columns of the compressed matrix
3352  , capacity_( 0UL ) // The current capacity of the pointer array
3353  , begin_ ( nullptr ) // Pointers to the first non-zero element of each column
3354  , end_ ( nullptr ) // Pointers one past the last non-zero element of each column
3355 {}
3357 //*************************************************************************************************
3358 
3359 
3360 //*************************************************************************************************
3369 template< typename Type > // Data type of the matrix
3370 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n )
3371  : CompressedMatrix( m, n, Uninitialized() )
3372 {
3373  for( size_t j=1UL; j<2UL*n_+2UL; ++j )
3374  begin_[j] = nullptr;
3375 }
3377 //*************************************************************************************************
3378 
3379 
3380 //*************************************************************************************************
3390 template< typename Type > // Data type of the matrix
3391 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
3392  : CompressedMatrix( m, n, Uninitialized() )
3393 {
3394  begin_[0UL] = allocate<Element>( nonzeros );
3395  for( size_t j=1UL; j<(2UL*n_+1UL); ++j )
3396  begin_[j] = begin_[0UL];
3397  end_[n_] = begin_[0UL]+nonzeros;
3398 }
3400 //*************************************************************************************************
3401 
3402 
3403 //*************************************************************************************************
3414 template< typename Type > // Data type of the matrix
3415 CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
3416  : CompressedMatrix( m, n, Uninitialized() )
3417 {
3418  BLAZE_USER_ASSERT( nonzeros.size() == n, "Size of capacity vector and number of columns don't match" );
3419 
3420  size_t newCapacity( 0UL );
3421  for( auto it=nonzeros.begin(); it!=nonzeros.end(); ++it )
3422  newCapacity += *it;
3423 
3424  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
3425  for( size_t j=0UL; j<n_; ++j ) {
3426  begin_[j+1UL] = end_[j+1UL] = begin_[j] + nonzeros[j];
3427  }
3428 }
3430 //*************************************************************************************************
3431 
3432 
3433 //*************************************************************************************************
3454 template< typename Type > // Data type of the matrix
3455 inline CompressedMatrix<Type,true>::CompressedMatrix( initializer_list< initializer_list<Type> > list )
3456  : CompressedMatrix( list.size(), determineColumns( list ), blaze::nonZeros( list ) )
3457 {
3458  for( size_t j=0UL; j<n_; ++j )
3459  {
3460  size_t i( 0UL );
3461 
3462  for( const auto& rowList : list )
3463  {
3464  if( rowList.size() <= j ) {
3465  ++i;
3466  continue;
3467  }
3468 
3469  auto pos( rowList.begin() );
3470  std::advance( pos, j );
3471  if( !isDefault<strict>( *pos ) )
3472  append( i, j, *pos );
3473  ++i;
3474  }
3475 
3476  finalize( j );
3477  }
3478 }
3480 //*************************************************************************************************
3481 
3482 
3483 //*************************************************************************************************
3489 template< typename Type > // Data type of the matrix
3490 inline CompressedMatrix<Type,true>::CompressedMatrix( const CompressedMatrix& sm )
3491  : CompressedMatrix( sm.m_, sm.n_, Uninitialized() )
3492 {
3493  const size_t nonzeros( sm.nonZeros() );
3494 
3495  begin_[0UL] = allocate<Element>( nonzeros );
3496  for( size_t j=0UL; j<n_; ++j ) {
3497  end_[j] = castDown( std::copy( sm.begin(j), sm.end(j), castUp( begin_[j] ) ) );
3498  begin_[j+1UL] = end_[j];
3499  }
3500  end_[n_] = begin_[0UL]+nonzeros;
3501 }
3503 //*************************************************************************************************
3504 
3505 
3506 //*************************************************************************************************
3512 template< typename Type > // Data type of the matrix
3513 inline CompressedMatrix<Type,true>::CompressedMatrix( CompressedMatrix&& sm ) noexcept
3514  : m_ ( sm.m_ ) // The current number of rows of the compressed matrix
3515  , n_ ( sm.n_ ) // The current number of columns of the compressed matrix
3516  , capacity_( sm.capacity_ ) // The current capacity of the pointer array
3517  , begin_ ( sm.begin_ ) // Pointers to the first non-zero element of each column
3518  , end_ ( sm.end_ ) // Pointers one past the last non-zero element of each column
3519 {
3520  sm.m_ = 0UL;
3521  sm.n_ = 0UL;
3522  sm.capacity_ = 0UL;
3523  sm.begin_ = nullptr;
3524  sm.end_ = nullptr;
3525 }
3527 //*************************************************************************************************
3528 
3529 
3530 //*************************************************************************************************
3536 template< typename Type > // Data type of the matrix
3537 template< typename MT // Type of the foreign dense matrix
3538  , bool SO > // Storage order of the foreign dense matrix
3539 inline CompressedMatrix<Type,true>::CompressedMatrix( const DenseMatrix<MT,SO>& dm )
3540  : CompressedMatrix( (~dm).rows(), (~dm).columns() )
3541 {
3542  using blaze::assign;
3543 
3544  assign( *this, ~dm );
3545 }
3547 //*************************************************************************************************
3548 
3549 
3550 //*************************************************************************************************
3556 template< typename Type > // Data type of the matrix
3557 template< typename MT // Type of the foreign compressed matrix
3558  , bool SO > // Storage order of the foreign compressed matrix
3559 inline CompressedMatrix<Type,true>::CompressedMatrix( const SparseMatrix<MT,SO>& sm )
3560  : CompressedMatrix( (~sm).rows(), (~sm).columns(), (~sm).nonZeros() )
3561 {
3562  using blaze::assign;
3563 
3564  assign( *this, ~sm );
3565 }
3567 //*************************************************************************************************
3568 
3569 
3570 //*************************************************************************************************
3577 template< typename Type > // Data type of the matrix
3578 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, Uninitialized )
3579  : m_ ( m ) // The current number of rows of the compressed matrix
3580  , n_ ( n ) // The current number of columns of the compressed matrix
3581  , capacity_( n ) // The current capacity of the pointer array
3582  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
3583  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
3584 {
3585  begin_[0UL] = nullptr;
3586 }
3588 //*************************************************************************************************
3589 
3590 
3591 
3592 
3593 //=================================================================================================
3594 //
3595 // DESTRUCTOR
3596 //
3597 //=================================================================================================
3598 
3599 //*************************************************************************************************
3603 template< typename Type > // Data type of the matrix
3605 {
3606  if( begin_ != nullptr ) {
3607  deallocate( begin_[0UL] );
3608  delete[] begin_;
3609  }
3610 }
3612 //*************************************************************************************************
3613 
3614 
3615 
3616 
3617 //=================================================================================================
3618 //
3619 // DATA ACCESS FUNCTIONS
3620 //
3621 //=================================================================================================
3622 
3623 //*************************************************************************************************
3637 template< typename Type > // Data type of the matrix
3639  CompressedMatrix<Type,true>::operator()( size_t i, size_t j ) noexcept
3640 {
3641  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3642  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3643 
3644  return Reference( *this, i, j );
3645 }
3647 //*************************************************************************************************
3648 
3649 
3650 //*************************************************************************************************
3661 template< typename Type > // Data type of the matrix
3663  CompressedMatrix<Type,true>::operator()( size_t i, size_t j ) const noexcept
3664 {
3665  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3666  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3667 
3668  const ConstIterator pos( lowerBound( i, j ) );
3669 
3670  if( pos == end_[j] || pos->index_ != i )
3671  return zero_;
3672  else
3673  return pos->value_;
3674 }
3676 //*************************************************************************************************
3677 
3678 
3679 //*************************************************************************************************
3693 template< typename Type > // Data type of the matrix
3695  CompressedMatrix<Type,true>::at( size_t i, size_t j )
3696 {
3697  if( i >= m_ ) {
3698  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3699  }
3700  if( j >= n_ ) {
3701  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3702  }
3703  return (*this)(i,j);
3704 }
3706 //*************************************************************************************************
3707 
3708 
3709 //*************************************************************************************************
3721 template< typename Type > // Data type of the matrix
3723  CompressedMatrix<Type,true>::at( size_t i, size_t j ) const
3724 {
3725  if( i >= m_ ) {
3726  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3727  }
3728  if( j >= n_ ) {
3729  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3730  }
3731  return (*this)(i,j);
3732 }
3734 //*************************************************************************************************
3735 
3736 
3737 //*************************************************************************************************
3744 template< typename Type > // Data type of the matrix
3746  CompressedMatrix<Type,true>::begin( size_t j ) noexcept
3747 {
3748  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3749  return begin_[j];
3750 }
3752 //*************************************************************************************************
3753 
3754 
3755 //*************************************************************************************************
3762 template< typename Type > // Data type of the matrix
3764  CompressedMatrix<Type,true>::begin( size_t j ) const noexcept
3765 {
3766  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3767  return begin_[j];
3768 }
3770 //*************************************************************************************************
3771 
3772 
3773 //*************************************************************************************************
3780 template< typename Type > // Data type of the matrix
3782  CompressedMatrix<Type,true>::cbegin( size_t j ) const noexcept
3783 {
3784  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3785  return begin_[j];
3786 }
3788 //*************************************************************************************************
3789 
3790 
3791 //*************************************************************************************************
3798 template< typename Type > // Data type of the matrix
3800  CompressedMatrix<Type,true>::end( size_t j ) noexcept
3801 {
3802  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3803  return end_[j];
3804 }
3806 //*************************************************************************************************
3807 
3808 
3809 //*************************************************************************************************
3816 template< typename Type > // Data type of the matrix
3818  CompressedMatrix<Type,true>::end( size_t j ) const noexcept
3819 {
3820  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3821  return end_[j];
3822 }
3824 //*************************************************************************************************
3825 
3826 
3827 //*************************************************************************************************
3834 template< typename Type > // Data type of the matrix
3836  CompressedMatrix<Type,true>::cend( size_t j ) const noexcept
3837 {
3838  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3839  return end_[j];
3840 }
3842 //*************************************************************************************************
3843 
3844 
3845 
3846 
3847 //=================================================================================================
3848 //
3849 // ASSIGNMENT OPERATORS
3850 //
3851 //=================================================================================================
3852 
3853 //*************************************************************************************************
3875 template< typename Type > // Data type of the matrix
3876 inline CompressedMatrix<Type,true>&
3877  CompressedMatrix<Type,true>::operator=( initializer_list< initializer_list<Type> > list )
3878 {
3879  using blaze::nonZeros;
3880 
3881  resize( list.size(), determineColumns( list ), false );
3882  reserve( nonZeros( list ) );
3883 
3884  for( size_t j=0UL; j<n_; ++j )
3885  {
3886  size_t i( 0UL );
3887 
3888  for( const auto& rowList : list )
3889  {
3890  if( rowList.size() <= j ) {
3891  ++i;
3892  continue;
3893  }
3894 
3895  auto pos( rowList.begin() );
3896  std::advance( pos, j );
3897  if( !isDefault<strict>( *pos ) )
3898  append( i, j, *pos );
3899  ++i;
3900  }
3901 
3902  finalize( j );
3903  }
3904 
3905  return *this;
3906 }
3908 //*************************************************************************************************
3909 
3910 
3911 //*************************************************************************************************
3921 template< typename Type > // Data type of the matrix
3922 inline CompressedMatrix<Type,true>&
3923  CompressedMatrix<Type,true>::operator=( const CompressedMatrix& rhs )
3924 {
3925  using std::swap;
3926 
3927  if( &rhs == this ) return *this;
3928 
3929  const size_t nonzeros( rhs.nonZeros() );
3930 
3931  if( rhs.n_ > capacity_ || nonzeros > capacity() )
3932  {
3933  Iterator* newBegin( new Iterator[2UL*rhs.n_+2UL] );
3934  Iterator* newEnd ( newBegin+(rhs.n_+1UL) );
3935 
3936  newBegin[0UL] = allocate<Element>( nonzeros );
3937  for( size_t j=0UL; j<rhs.n_; ++j ) {
3938  newEnd[j] = castDown( std::copy( rhs.begin_[j], rhs.end_[j], castUp( newBegin[j] ) ) );
3939  newBegin[j+1UL] = newEnd[j];
3940  }
3941  newEnd[rhs.n_] = newBegin[0UL]+nonzeros;
3942 
3943  swap( begin_, newBegin );
3944  end_ = newEnd;
3945  capacity_ = rhs.n_;
3946 
3947  if( newBegin != nullptr ) {
3948  deallocate( newBegin[0UL] );
3949  delete[] newBegin;
3950  }
3951  }
3952  else {
3953  for( size_t j=0UL; j<rhs.n_; ++j ) {
3954  end_[j] = castDown( std::copy( rhs.begin_[j], rhs.end_[j], castUp( begin_[j] ) ) );
3955  begin_[j+1UL] = end_[j];
3956  }
3957  }
3958 
3959  m_ = rhs.m_;
3960  n_ = rhs.n_;
3961 
3962  return *this;
3963 }
3965 //*************************************************************************************************
3966 
3967 
3968 //*************************************************************************************************
3975 template< typename Type > // Data type of the matrix
3976 inline CompressedMatrix<Type,true>&
3977  CompressedMatrix<Type,true>::operator=( CompressedMatrix&& rhs ) noexcept
3978 {
3979  if( begin_ != nullptr ) {
3980  deallocate( begin_[0UL] );
3981  delete[] begin_;
3982  }
3983 
3984  m_ = rhs.m_;
3985  n_ = rhs.n_;
3986  capacity_ = rhs.capacity_;
3987  begin_ = rhs.begin_;
3988  end_ = rhs.end_;
3989 
3990  rhs.m_ = 0UL;
3991  rhs.n_ = 0UL;
3992  rhs.capacity_ = 0UL;
3993  rhs.begin_ = nullptr;
3994  rhs.end_ = nullptr;
3995 
3996  return *this;
3997 }
3999 //*************************************************************************************************
4000 
4001 
4002 //*************************************************************************************************
4012 template< typename Type > // Data type of the matrix
4013 template< typename MT // Type of the right-hand side dense matrix
4014  , bool SO > // Storage order of the right-hand side dense matrix
4015 inline CompressedMatrix<Type,true>&
4016  CompressedMatrix<Type,true>::operator=( const DenseMatrix<MT,SO>& rhs )
4017 {
4018  using blaze::assign;
4019 
4020  if( (~rhs).canAlias( this ) ) {
4021  CompressedMatrix tmp( ~rhs );
4022  swap( tmp );
4023  }
4024  else {
4025  resize( (~rhs).rows(), (~rhs).columns(), false );
4026  assign( *this, ~rhs );
4027  }
4028 
4029  return *this;
4030 }
4032 //*************************************************************************************************
4033 
4034 
4035 //*************************************************************************************************
4045 template< typename Type > // Data type of the matrix
4046 template< typename MT // Type of the right-hand side compressed matrix
4047  , bool SO > // Storage order of the right-hand side compressed matrix
4048 inline CompressedMatrix<Type,true>&
4049  CompressedMatrix<Type,true>::operator=( const SparseMatrix<MT,SO>& rhs )
4050 {
4051  using blaze::assign;
4052 
4053  if( (~rhs).canAlias( this ) ||
4054  (~rhs).columns() > capacity_ ||
4055  (~rhs).nonZeros() > capacity() ) {
4056  CompressedMatrix tmp( ~rhs );
4057  swap( tmp );
4058  }
4059  else {
4060  resize( (~rhs).rows(), (~rhs).columns(), false );
4061  reset();
4062 
4063  if( !IsZero_v<MT> ) {
4064  assign( *this, ~rhs );
4065  }
4066  }
4067 
4068  return *this;
4069 }
4071 //*************************************************************************************************
4072 
4073 
4074 //*************************************************************************************************
4085 template< typename Type > // Data type of the matrix
4086 template< typename MT // Type of the right-hand side matrix
4087  , bool SO > // Storage order of the right-hand side matrix
4088 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator+=( const Matrix<MT,SO>& rhs )
4089 {
4090  using blaze::addAssign;
4091 
4092  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4093  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4094  }
4095 
4096  if( !IsZero_v<MT> ) {
4097  addAssign( *this, ~rhs );
4098  }
4099 
4100  return *this;
4101 }
4103 //*************************************************************************************************
4104 
4105 
4106 //*************************************************************************************************
4117 template< typename Type > // Data type of the matrix
4118 template< typename MT // Type of the right-hand side matrix
4119  , bool SO > // Storage order of the right-hand side matrix
4120 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator-=( const Matrix<MT,SO>& rhs )
4121 {
4122  using blaze::subAssign;
4123 
4124  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4125  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4126  }
4127 
4128  if( !IsZero_v<MT> ) {
4129  subAssign( *this, ~rhs );
4130  }
4131 
4132  return *this;
4133 }
4135 //*************************************************************************************************
4136 
4137 
4138 //*************************************************************************************************
4150 template< typename Type > // Data type of the matrix
4151 template< typename MT // Type of the right-hand side dense matrix
4152  , bool SO > // Storage order of the right-hand side dense matrix
4153 inline CompressedMatrix<Type,true>&
4154  CompressedMatrix<Type,true>::operator%=( const DenseMatrix<MT,SO>& rhs )
4155 {
4156  using blaze::schurAssign;
4157 
4158  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4159  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4160  }
4161 
4162  if( (~rhs).canAlias( this ) ) {
4163  CompressedMatrix tmp( *this % (~rhs) );
4164  swap( tmp );
4165  }
4166  else {
4167  CompositeType_t<MT> tmp( ~rhs );
4168  schurAssign( *this, tmp );
4169  }
4170 
4171  return *this;
4172 }
4174 //*************************************************************************************************
4175 
4176 
4177 //*************************************************************************************************
4189 template< typename Type > // Data type of the matrix
4190 template< typename MT // Type of the right-hand side sparse matrix
4191  , bool SO > // Storage order of the right-hand side sparse matrix
4192 inline CompressedMatrix<Type,true>&
4193  CompressedMatrix<Type,true>::operator%=( const SparseMatrix<MT,SO>& rhs )
4194 {
4195  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4196  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4197  }
4198 
4199  if( !IsZero_v<MT> ) {
4200  CompressedMatrix tmp( *this % (~rhs) );
4201  swap( tmp );
4202  }
4203  else {
4204  reset();
4205  }
4206 
4207  return *this;
4208 }
4210 //*************************************************************************************************
4211 
4212 
4213 
4214 
4215 //=================================================================================================
4216 //
4217 // UTILITY FUNCTIONS
4218 //
4219 //=================================================================================================
4220 
4221 //*************************************************************************************************
4227 template< typename Type > // Data type of the matrix
4228 inline size_t CompressedMatrix<Type,true>::rows() const noexcept
4229 {
4230  return m_;
4231 }
4233 //*************************************************************************************************
4234 
4235 
4236 //*************************************************************************************************
4242 template< typename Type > // Data type of the matrix
4243 inline size_t CompressedMatrix<Type,true>::columns() const noexcept
4244 {
4245  return n_;
4246 }
4248 //*************************************************************************************************
4249 
4250 
4251 //*************************************************************************************************
4257 template< typename Type > // Data type of the matrix
4258 inline size_t CompressedMatrix<Type,true>::capacity() const noexcept
4259 {
4260  if( begin_ != nullptr )
4261  return end_[n_] - begin_[0UL];
4262  else return 0UL;
4263 }
4265 //*************************************************************************************************
4266 
4267 
4268 //*************************************************************************************************
4275 template< typename Type > // Data type of the matrix
4276 inline size_t CompressedMatrix<Type,true>::capacity( size_t j ) const noexcept
4277 {
4278  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4279  return begin_[j+1UL] - begin_[j];
4280 }
4282 //*************************************************************************************************
4283 
4284 
4285 //*************************************************************************************************
4291 template< typename Type > // Data type of the matrix
4292 inline size_t CompressedMatrix<Type,true>::nonZeros() const
4293 {
4294  size_t nonzeros( 0UL );
4295 
4296  for( size_t j=0UL; j<n_; ++j )
4297  nonzeros += nonZeros( j );
4298 
4299  return nonzeros;
4300 }
4302 //*************************************************************************************************
4303 
4304 
4305 //*************************************************************************************************
4312 template< typename Type > // Data type of the matrix
4313 inline size_t CompressedMatrix<Type,true>::nonZeros( size_t j ) const
4314 {
4315  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4316  return end_[j] - begin_[j];
4317 }
4319 //*************************************************************************************************
4320 
4321 
4322 //*************************************************************************************************
4328 template< typename Type > // Data type of the matrix
4330 {
4331  for( size_t j=0UL; j<n_; ++j )
4332  end_[j] = begin_[j];
4333 }
4335 //*************************************************************************************************
4336 
4337 
4338 //*************************************************************************************************
4348 template< typename Type > // Data type of the matrix
4349 inline void CompressedMatrix<Type,true>::reset( size_t j )
4350 {
4351  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4352  end_[j] = begin_[j];
4353 }
4355 //*************************************************************************************************
4356 
4357 
4358 //*************************************************************************************************
4366 template< typename Type > // Data type of the matrix
4368 {
4369  if( end_ != nullptr )
4370  end_[0UL] = end_[n_];
4371  m_ = 0UL;
4372  n_ = 0UL;
4373 }
4375 //*************************************************************************************************
4376 
4377 
4378 //*************************************************************************************************
4394 template< typename Type > // Data type of the matrix
4395 void CompressedMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
4396 {
4397  using std::swap;
4398 
4399  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4400  BLAZE_INTERNAL_ASSERT( begin_ == nullptr || size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4401 
4402  if( m == m_ && n == n_ ) return;
4403 
4404  if( begin_ == nullptr )
4405  {
4406  begin_ = new Iterator[2UL*n+2UL];
4407  end_ = begin_+n+1UL;
4408 
4409  for( size_t j=0UL; j<2UL*n+2UL; ++j ) {
4410  begin_[j] = nullptr;
4411  }
4412 
4413  capacity_ = n;
4414  }
4415  else if( n > capacity_ )
4416  {
4417  Iterator* newBegin( new Iterator[2UL*n+2UL] );
4418  Iterator* newEnd ( newBegin+n+1UL );
4419 
4420  newBegin[0UL] = begin_[0UL];
4421 
4422  if( preserve ) {
4423  for( size_t j=0UL; j<n_; ++j ) {
4424  newEnd [j] = end_ [j];
4425  newBegin[j+1UL] = begin_[j+1UL];
4426  }
4427  for( size_t j=n_; j<n; ++j ) {
4428  newBegin[j+1UL] = newEnd[j] = begin_[n_];
4429  }
4430  }
4431  else {
4432  for( size_t j=0UL; j<n; ++j ) {
4433  newBegin[j+1UL] = newEnd[j] = begin_[0UL];
4434  }
4435  }
4436 
4437  newEnd[n] = end_[n_];
4438 
4439  swap( newBegin, begin_ );
4440  delete[] newBegin;
4441  end_ = newEnd;
4442  capacity_ = n;
4443  }
4444  else if( n > n_ )
4445  {
4446  end_[n] = end_[n_];
4447 
4448  if( !preserve ) {
4449  for( size_t j=0UL; j<n_; ++j )
4450  end_[j] = begin_[j];
4451  }
4452 
4453  for( size_t j=n_; j<n; ++j ) {
4454  begin_[j+1UL] = end_[j] = begin_[n_];
4455  }
4456  }
4457  else
4458  {
4459  if( preserve ) {
4460  for( size_t j=0UL; j<n; ++j )
4461  end_[j] = lowerBound( m, j );
4462  }
4463  else {
4464  for( size_t j=0UL; j<n; ++j )
4465  end_[j] = begin_[j];
4466  }
4467 
4468  end_[n] = end_[n_];
4469  }
4470 
4471  m_ = m;
4472  n_ = n;
4473 
4474  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4475  BLAZE_INTERNAL_ASSERT( size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4476 }
4478 //*************************************************************************************************
4479 
4480 
4481 //*************************************************************************************************
4492 template< typename Type > // Data type of the matrix
4493 inline void CompressedMatrix<Type,true>::reserve( size_t nonzeros )
4494 {
4495  if( nonzeros > capacity() )
4496  reserveElements( nonzeros );
4497 }
4499 //*************************************************************************************************
4500 
4501 
4502 //*************************************************************************************************
4514 template< typename Type > // Data type of the matrix
4515 void CompressedMatrix<Type,true>::reserve( size_t j, size_t nonzeros )
4516 {
4517  using std::swap;
4518 
4519  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4520 
4521  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4522  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4523 
4524  const size_t current( capacity(j) );
4525 
4526  if( current >= nonzeros ) return;
4527 
4528  const ptrdiff_t additional( nonzeros - current );
4529 
4530  if( end_[n_] - begin_[n_] < additional )
4531  {
4532  const size_t newCapacity( begin_[n_] - begin_[0UL] + additional );
4533  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
4534 
4535  Iterator* newBegin( new Iterator[2UL*n_+2UL] );
4536  Iterator* newEnd ( newBegin+n_+1UL );
4537 
4538  newBegin[0UL] = allocate<Element>( newCapacity );
4539  newEnd [n_ ] = newBegin[0UL]+newCapacity;
4540 
4541  for( size_t k=0UL; k<j; ++k ) {
4542  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4543  newBegin[k+1UL] = newBegin[k] + capacity(k);
4544  }
4545  newEnd [j ] = castDown( transfer( begin_[j], end_[j], castUp( newBegin[j] ) ) );
4546  newBegin[j+1UL] = newBegin[j] + nonzeros;
4547  for( size_t k=j+1UL; k<n_; ++k ) {
4548  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4549  newBegin[k+1UL] = newBegin[k] + capacity(k);
4550  }
4551 
4552  BLAZE_INTERNAL_ASSERT( newBegin[n_] == newEnd[n_], "Invalid pointer calculations" );
4553 
4554  swap( newBegin, begin_ );
4555  deallocate( newBegin[0UL] );
4556  delete[] newBegin;
4557  end_ = newEnd;
4558  capacity_ = n_;
4559  }
4560  else
4561  {
4562  begin_[n_] += additional;
4563  for( size_t k=n_-1UL; k>j; --k ) {
4564  begin_[k] = castDown( std::move_backward( begin_[k], end_[k], castUp( end_[k]+additional ) ) );
4565  end_ [k] += additional;
4566  }
4567  }
4568 
4569  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4570  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4571 }
4573 //*************************************************************************************************
4574 
4575 
4576 //*************************************************************************************************
4586 template< typename Type > // Data type of the matrix
4588 {
4589  for( size_t j=0UL; j<n_; ++j )
4590  trim( j );
4591 }
4593 //*************************************************************************************************
4594 
4595 
4596 //*************************************************************************************************
4607 template< typename Type > // Data type of the matrix
4608 void CompressedMatrix<Type,true>::trim( size_t j )
4609 {
4610  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4611 
4612  if( j < ( n_ - 1UL ) )
4613  end_[j+1] = castDown( std::move( begin_[j+1], end_[j+1], castUp( end_[j] ) ) );
4614  begin_[j+1] = end_[j];
4615 }
4617 //*************************************************************************************************
4618 
4619 
4620 //*************************************************************************************************
4630 template< typename Type > // Data type of the matrix
4632 {
4633  if( nonZeros() < capacity() ) {
4634  CompressedMatrix( *this ).swap( *this );
4635  }
4636 }
4638 //*************************************************************************************************
4639 
4640 
4641 //*************************************************************************************************
4648 template< typename Type > // Data type of the matrix
4649 inline void CompressedMatrix<Type,true>::swap( CompressedMatrix& sm ) noexcept
4650 {
4651  using std::swap;
4652 
4653  swap( m_, sm.m_ );
4654  swap( n_, sm.n_ );
4655  swap( capacity_, sm.capacity_ );
4656  swap( begin_, sm.begin_ );
4657  swap( end_ , sm.end_ );
4658 }
4660 //*************************************************************************************************
4661 
4662 
4663 //*************************************************************************************************
4672 template< typename Type > // Data type of the matrix
4673 inline size_t CompressedMatrix<Type,true>::extendCapacity() const noexcept
4674 {
4675  size_t nonzeros( 2UL*capacity()+1UL );
4676  nonzeros = blaze::max( nonzeros, 7UL );
4677 
4678  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
4679 
4680  return nonzeros;
4681 }
4683 //*************************************************************************************************
4684 
4685 
4686 //*************************************************************************************************
4693 template< typename Type > // Data type of the matrix
4694 void CompressedMatrix<Type,true>::reserveElements( size_t nonzeros )
4695 {
4696  using std::swap;
4697 
4698  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
4699  Iterator* newEnd = newBegin+capacity_+1UL;
4700 
4701  newBegin[0UL] = allocate<Element>( nonzeros );
4702 
4703  for( size_t k=0UL; k<n_; ++k ) {
4704  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid column pointers" );
4705  newEnd [k] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4706  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
4707  }
4708 
4709  newEnd[n_] = newBegin[0UL]+nonzeros;
4710 
4711  swap( newBegin, begin_ );
4712  end_ = newEnd;
4713 
4714  if( newBegin != nullptr ) {
4715  deallocate( newBegin[0UL] );
4716  delete[] newBegin;
4717  }
4718 }
4720 //*************************************************************************************************
4721 
4722 
4723 //*************************************************************************************************
4731 template< typename Type > // Data type of the matrix
4733  CompressedMatrix<Type,true>::castDown( IteratorBase it ) const noexcept
4734 {
4735  return static_cast<Iterator>( it );
4736 }
4737 //*************************************************************************************************
4738 
4739 
4740 //*************************************************************************************************
4748 template< typename Type > // Data type of the matrix
4750  CompressedMatrix<Type,true>::castUp( Iterator it ) const noexcept
4751 {
4752  return static_cast<IteratorBase>( it );
4753 }
4754 //*************************************************************************************************
4755 
4756 
4757 
4758 
4759 //=================================================================================================
4760 //
4761 // INSERTION FUNCTIONS
4762 //
4763 //=================================================================================================
4764 
4765 //*************************************************************************************************
4778 template< typename Type > // Data type of the matrix
4780  CompressedMatrix<Type,true>::set( size_t i, size_t j, const Type& value )
4781 {
4782  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4783  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4784 
4785  const Iterator pos( lowerBound( i, j ) );
4786 
4787  if( pos != end_[j] && pos->index_ == i ) {
4788  pos->value() = value;
4789  return pos;
4790  }
4791  else return insert( pos, i, j, value );
4792 }
4794 //*************************************************************************************************
4795 
4796 
4797 //*************************************************************************************************
4811 template< typename Type > // Data type of the matrix
4813  CompressedMatrix<Type,true>::insert( size_t i, size_t j, const Type& value )
4814 {
4815  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4816  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4817 
4818  const Iterator pos( lowerBound( i, j ) );
4819 
4820  if( pos != end_[j] && pos->index_ == i ) {
4821  BLAZE_THROW_INVALID_ARGUMENT( "Bad access index" );
4822  }
4823 
4824  return insert( pos, i, j, value );
4825 }
4827 //*************************************************************************************************
4828 
4829 
4830 //*************************************************************************************************
4841 template< typename Type > // Data type of the matrix
4843  CompressedMatrix<Type,true>::insert( Iterator pos, size_t i, size_t j, const Type& value )
4844 {
4845  using std::swap;
4846 
4847  if( begin_[j+1UL] - end_[j] != 0 ) {
4848  std::move_backward( pos, end_[j], castUp( end_[j]+1UL ) );
4849  pos->value_ = value;
4850  pos->index_ = i;
4851  ++end_[j];
4852 
4853  return pos;
4854  }
4855  else if( end_[n_] - begin_[n_] != 0 ) {
4856  std::move_backward( pos, end_[n_-1UL], castUp( end_[n_-1]+1UL ) );
4857 
4858  pos->value_ = value;
4859  pos->index_ = i;
4860 
4861  for( size_t k=j+1UL; k<n_+1UL; ++k ) {
4862  ++begin_[k];
4863  ++end_[k-1UL];
4864  }
4865 
4866  return pos;
4867  }
4868  else {
4869  size_t newCapacity( extendCapacity() );
4870 
4871  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
4872  Iterator* newEnd = newBegin+capacity_+1UL;
4873 
4874  newBegin[0UL] = allocate<Element>( newCapacity );
4875 
4876  for( size_t k=0UL; k<j; ++k ) {
4877  const size_t nonzeros( end_[k] - begin_[k] );
4878  const size_t total( begin_[k+1UL] - begin_[k] );
4879  newEnd [k] = newBegin[k] + nonzeros;
4880  newBegin[k+1UL] = newBegin[k] + total;
4881  }
4882  newEnd [j] = newBegin[j] + ( end_[j] - begin_[j] ) + 1;
4883  newBegin[j+1UL] = newBegin[j] + ( begin_[j+1UL] - begin_[j] ) + 1;
4884  for( size_t k=j+1UL; k<n_; ++k ) {
4885  const size_t nonzeros( end_[k] - begin_[k] );
4886  const size_t total( begin_[k+1UL] - begin_[k] );
4887  newEnd [k] = newBegin[k] + nonzeros;
4888  newBegin[k+1UL] = newBegin[k] + total;
4889  }
4890 
4891  newEnd[n_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
4892 
4893  Iterator tmp = castDown( std::move( begin_[0UL], pos, castUp( newBegin[0UL] ) ) );
4894  tmp->value_ = value;
4895  tmp->index_ = i;
4896  std::move( pos, end_[n_-1UL], castUp( tmp+1UL ) );
4897 
4898  swap( newBegin, begin_ );
4899  end_ = newEnd;
4900  deallocate( newBegin[0UL] );
4901  delete[] newBegin;
4902 
4903  return tmp;
4904  }
4905 }
4907 //*************************************************************************************************
4908 
4909 
4910 //*************************************************************************************************
4963 template< typename Type > // Data type of the matrix
4964 inline void CompressedMatrix<Type,true>::append( size_t i, size_t j, const Type& value, bool check )
4965 {
4966  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
4967  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
4968  BLAZE_USER_ASSERT( end_[j] < end_[n_], "Not enough reserved capacity left" );
4969  BLAZE_USER_ASSERT( begin_[j] == end_[j] || i > ( end_[j]-1UL )->index_, "Index is not strictly increasing" );
4970 
4971  end_[j]->value_ = value;
4972 
4973  if( !check || !isDefault<strict>( end_[j]->value_ ) ) {
4974  end_[j]->index_ = i;
4975  ++end_[j];
4976  }
4977 }
4979 //*************************************************************************************************
4980 
4981 
4982 //*************************************************************************************************
4996 template< typename Type > // Data type of the matrix
4997 inline void CompressedMatrix<Type,true>::finalize( size_t j )
4998 {
4999  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
5000 
5001  begin_[j+1UL] = end_[j];
5002  if( j != n_-1UL )
5003  end_[j+1UL] = end_[j];
5004 }
5006 //*************************************************************************************************
5007 
5008 
5009 
5010 
5011 //=================================================================================================
5012 //
5013 // ERASE FUNCTIONS
5014 //
5015 //=================================================================================================
5016 
5017 //*************************************************************************************************
5027 template< typename Type > // Data type of the matrix
5028 inline void CompressedMatrix<Type,true>::erase( size_t i, size_t j )
5029 {
5030  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
5031  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5032 
5033  const Iterator pos( find( i, j ) );
5034  if( pos != end_[j] )
5035  end_[j] = castDown( std::move( pos+1, end_[j], castUp( pos ) ) );
5036 }
5038 //*************************************************************************************************
5039 
5040 
5041 //*************************************************************************************************
5051 template< typename Type > // Data type of the matrix
5053  CompressedMatrix<Type,true>::erase( size_t j, Iterator pos )
5054 {
5055  BLAZE_USER_ASSERT( j < columns() , "Invalid column access index" );
5056  BLAZE_USER_ASSERT( pos >= begin_[j] && pos <= end_[j], "Invalid compressed matrix iterator" );
5057 
5058  if( pos != end_[j] )
5059  end_[j] = castDown( std::move( pos+1, end_[j], castUp( pos ) ) );
5060 
5061  return pos;
5062 }
5064 //*************************************************************************************************
5065 
5066 
5067 //*************************************************************************************************
5078 template< typename Type > // Data type of the matrix
5080  CompressedMatrix<Type,true>::erase( size_t j, Iterator first, Iterator last )
5081 {
5082  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5083  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
5084  BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j], "Invalid compressed matrix iterator" );
5085  BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j], "Invalid compressed matrix iterator" );
5086 
5087  if( first != last )
5088  end_[j] = castDown( std::move( last, end_[j], castUp( first ) ) );
5089 
5090  return first;
5091 }
5093 //*************************************************************************************************
5094 
5095 
5096 //*************************************************************************************************
5118 template< typename Type > // Data type of the matrix
5119 template< typename Pred > // Type of the unary predicate
5120 inline void CompressedMatrix<Type,true>::erase( Pred predicate )
5121 {
5122  for( size_t j=0UL; j<n_; ++j ) {
5123  end_[j] = castDown( std::remove_if( castUp( begin_[j] ), castUp( end_[j] ),
5124  [predicate=predicate]( const ElementBase& element ) {
5125  return predicate( element.value() );
5126  } ) );
5127  }
5128 }
5130 //*************************************************************************************************
5131 
5132 
5133 //*************************************************************************************************
5158 template< typename Type > // Data type of the matrix
5159 template< typename Pred > // Type of the unary predicate
5160 inline void CompressedMatrix<Type,true>::erase( size_t j, Iterator first, Iterator last, Pred predicate )
5161 {
5162  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5163  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
5164  BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j], "Invalid compressed matrix iterator" );
5165  BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j], "Invalid compressed matrix iterator" );
5166 
5167  const auto pos = std::remove_if( castUp( first ), castUp( last ),
5168  [predicate=predicate]( const ElementBase& element ) {
5169  return predicate( element.value() );
5170  } );
5171 
5172  end_[j] = castDown( std::move( last, end_[j], pos ) );
5173 }
5175 //*************************************************************************************************
5176 
5177 
5178 
5179 
5180 //=================================================================================================
5181 //
5182 // LOOKUP FUNCTIONS
5183 //
5184 //=================================================================================================
5185 
5186 //*************************************************************************************************
5201 template< typename Type > // Data type of the matrix
5203  CompressedMatrix<Type,true>::find( size_t i, size_t j )
5204 {
5205  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
5206 }
5208 //*************************************************************************************************
5209 
5210 
5211 //*************************************************************************************************
5226 template< typename Type > // Data type of the matrix
5228  CompressedMatrix<Type,true>::find( size_t i, size_t j ) const
5229 {
5230  const ConstIterator pos( lowerBound( i, j ) );
5231  if( pos != end_[j] && pos->index_ == i )
5232  return pos;
5233  else return end_[j];
5234 }
5236 //*************************************************************************************************
5237 
5238 
5239 //*************************************************************************************************
5253 template< typename Type > // Data type of the matrix
5255  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j )
5256 {
5257  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
5258 }
5260 //*************************************************************************************************
5261 
5262 
5263 //*************************************************************************************************
5277 template< typename Type > // Data type of the matrix
5279  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j ) const
5280 {
5281  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5282  return std::lower_bound( begin_[j], end_[j], i,
5283  []( const Element& element, size_t index )
5284  {
5285  return element.index() < index;
5286  } );
5287 }
5289 //*************************************************************************************************
5290 
5291 
5292 //*************************************************************************************************
5306 template< typename Type > // Data type of the matrix
5308  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j )
5309 {
5310  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
5311 }
5313 //*************************************************************************************************
5314 
5315 
5316 //*************************************************************************************************
5330 template< typename Type > // Data type of the matrix
5332  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j ) const
5333 {
5334  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5335  return std::upper_bound( begin_[j], end_[j], i,
5336  []( size_t index, const Element& element )
5337  {
5338  return index < element.index();
5339  } );
5340 }
5342 //*************************************************************************************************
5343 
5344 
5345 
5346 
5347 //=================================================================================================
5348 //
5349 // NUMERIC FUNCTIONS
5350 //
5351 //=================================================================================================
5352 
5353 //*************************************************************************************************
5359 template< typename Type > // Data type of the matrix
5360 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::transpose()
5361 {
5362  CompressedMatrix tmp( trans( *this ) );
5363  swap( tmp );
5364  return *this;
5365 }
5367 //*************************************************************************************************
5368 
5369 
5370 //*************************************************************************************************
5376 template< typename Type > // Data type of the matrix
5377 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::ctranspose()
5378 {
5379  CompressedMatrix tmp( ctrans( *this ) );
5380  swap( tmp );
5381  return *this;
5382 }
5384 //*************************************************************************************************
5385 
5386 
5387 //*************************************************************************************************
5405 template< typename Type > // Data type of the matrix
5406 template< typename Other > // Data type of the scalar value
5407 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scale( const Other& scalar )
5408 {
5409  for( size_t j=0UL; j<n_; ++j )
5410  for( auto element=begin_[j]; element!=end_[j]; ++element )
5411  element->value_ *= scalar;
5412 
5413  return *this;
5414 }
5416 //*************************************************************************************************
5417 
5418 
5419 
5420 
5421 //=================================================================================================
5422 //
5423 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5424 //
5425 //=================================================================================================
5426 
5427 //*************************************************************************************************
5438 template< typename Type > // Data type of the matrix
5439 template< typename Other > // Data type of the foreign expression
5440 inline bool CompressedMatrix<Type,true>::canAlias( const Other* alias ) const noexcept
5441 {
5442  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5443 }
5445 //*************************************************************************************************
5446 
5447 
5448 //*************************************************************************************************
5459 template< typename Type > // Data type of the matrix
5460 template< typename Other > // Data type of the foreign expression
5461 inline bool CompressedMatrix<Type,true>::isAliased( const Other* alias ) const noexcept
5462 {
5463  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5464 }
5466 //*************************************************************************************************
5467 
5468 
5469 //*************************************************************************************************
5480 template< typename Type > // Data type of the matrix
5481 inline bool CompressedMatrix<Type,true>::canSMPAssign() const noexcept
5482 {
5483  return false;
5484 }
5486 //*************************************************************************************************
5487 
5488 
5489 //*************************************************************************************************
5501 template< typename Type > // Data type of the matrix
5502 template< typename MT // Type of the right-hand side dense matrix
5503  , bool SO > // Storage order of the right-hand side dense matrix
5504 inline void CompressedMatrix<Type,true>::assign( const DenseMatrix<MT,SO>& rhs )
5505 {
5506  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5507  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5508 
5509  if( m_ == 0UL || n_ == 0UL )
5510  return;
5511 
5512  size_t nonzeros( 0UL );
5513 
5514  for( size_t j=1UL; j<=n_; ++j )
5515  begin_[j] = end_[j] = end_[n_];
5516 
5517  for( size_t j=0UL; j<n_; ++j )
5518  {
5519  begin_[j] = end_[j] = begin_[0UL]+nonzeros;
5520 
5521  const size_t ibegin( ( IsLower_v<MT> )
5522  ?( IsStrictlyLower_v<MT> ? j+1UL : j )
5523  :( 0UL ) );
5524  const size_t iend ( ( IsUpper_v<MT> )
5525  ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
5526  :( m_ ) );
5527 
5528  for( size_t i=ibegin; i<iend; ++i )
5529  {
5530  if( nonzeros == capacity() ) {
5531  reserveElements( extendCapacity() );
5532  for( size_t k=j+1UL; k<=n_; ++k )
5533  begin_[k] = end_[k] = end_[n_];
5534  }
5535 
5536  end_[j]->value_ = (~rhs)(i,j);
5537 
5538  if( !isDefault<strict>( end_[j]->value_ ) ) {
5539  end_[j]->index_ = i;
5540  ++end_[j];
5541  ++nonzeros;
5542  }
5543  }
5544  }
5545 
5546  begin_[n_] = begin_[0UL]+nonzeros;
5547 }
5549 //*************************************************************************************************
5550 
5551 
5552 //*************************************************************************************************
5564 template< typename Type > // Data type of the matrix
5565 template< typename MT > // Type of the right-hand side compressed matrix
5566 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,true>& rhs )
5567 {
5568  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5569  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5570  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
5571  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
5572 
5573  if( n_ == 0UL || begin_[0] == nullptr )
5574  return;
5575 
5576  for( size_t j=0UL; j<n_; ++j ) {
5577  end_[j] = castDown( std::copy( (~rhs).begin(j), (~rhs).end(j), castUp( begin_[j] ) ) );
5578  begin_[j+1UL] = end_[j];
5579  }
5580 }
5582 //*************************************************************************************************
5583 
5584 
5585 //*************************************************************************************************
5597 template< typename Type > // Data type of the matrix
5598 template< typename MT > // Type of the right-hand side compressed matrix
5599 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,false>& rhs )
5600 {
5602 
5603  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5604  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5605  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
5606  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
5607 
5608  // Counting the number of elements per column
5609  std::vector<size_t> columnLengths( n_, 0UL );
5610  for( size_t i=0UL; i<m_; ++i ) {
5611  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5612  ++columnLengths[element->index()];
5613  }
5614 
5615  // Resizing the compressed matrix
5616  for( size_t j=0UL; j<n_; ++j ) {
5617  begin_[j+1UL] = end_[j+1UL] = begin_[j] + columnLengths[j];
5618  }
5619 
5620  // Appending the elements to the columns of the compressed matrix
5621  for( size_t i=0UL; i<m_; ++i ) {
5622  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5623  append( i, element->index(), element->value() );
5624  }
5625 }
5627 //*************************************************************************************************
5628 
5629 
5630 //*************************************************************************************************
5642 template< typename Type > // Data type of the matrix
5643 template< typename MT // Type of the right-hand side dense matrix
5644  , bool SO > // Storage order of the right-hand side dense matrix
5645 inline void CompressedMatrix<Type,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
5646 {
5647  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5648  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5649 
5650  CompressedMatrix tmp( serial( *this + (~rhs) ) );
5651  swap( tmp );
5652 }
5654 //*************************************************************************************************
5655 
5656 
5657 //*************************************************************************************************
5669 template< typename Type > // Data type of the matrix
5670 template< typename MT // Type of the right-hand side compressed matrix
5671  , bool SO > // Storage order of the right-hand side compressed matrix
5672 inline void CompressedMatrix<Type,true>::addAssign( const SparseMatrix<MT,SO>& rhs )
5673 {
5674  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5675  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5676 
5677  CompressedMatrix tmp( serial( *this + (~rhs) ) );
5678  swap( tmp );
5679 }
5681 //*************************************************************************************************
5682 
5683 
5684 //*************************************************************************************************
5696 template< typename Type > // Data type of the matrix
5697 template< typename MT // Type of the right-hand side dense matrix
5698  , bool SO > // Storage order of the right-hand side dense matrix
5699 inline void CompressedMatrix<Type,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
5700 {
5701  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5702  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5703 
5704  CompressedMatrix tmp( serial( *this - (~rhs) ) );
5705  swap( tmp );
5706 }
5708 //*************************************************************************************************
5709 
5710 
5711 //*************************************************************************************************
5723 template< typename Type > // Data type of the matrix
5724 template< typename MT // Type of the right-hand side compressed matrix
5725  , bool SO > // Storage order of the right-hand side compressed matrix
5726 inline void CompressedMatrix<Type,true>::subAssign( const SparseMatrix<MT,SO>& rhs )
5727 {
5728  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5729  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5730 
5731  CompressedMatrix tmp( serial( *this - (~rhs) ) );
5732  swap( tmp );
5733 }
5735 //*************************************************************************************************
5736 
5737 
5738 //*************************************************************************************************
5750 template< typename Type > // Data type of the matrix
5751 template< typename MT // Type of the right-hand side dense matrix
5752  , bool SO > // Storage order of the right-hand side dense matrix
5753 inline void CompressedMatrix<Type,true>::schurAssign( const DenseMatrix<MT,SO>& rhs )
5754 {
5755  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5756  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5757 
5759 
5760  for( size_t j=0UL; j<n_; ++j ) {
5761  const Iterator last( end(j) );
5762  for( auto element=begin(j); element!=last; ++element )
5763  element->value_ *= (~rhs)(element->index_,j);
5764  }
5765 }
5767 //*************************************************************************************************
5768 
5769 
5770 
5771 
5772 
5773 
5774 
5775 
5776 //=================================================================================================
5777 //
5778 // COMPRESSEDMATRIX OPERATORS
5779 //
5780 //=================================================================================================
5781 
5782 //*************************************************************************************************
5785 template< typename Type, bool SO >
5786 void reset( CompressedMatrix<Type,SO>& m );
5787 
5788 template< typename Type, bool SO >
5789 void reset( CompressedMatrix<Type,SO>& m, size_t i );
5790 
5791 template< typename Type, bool SO >
5792 void clear( CompressedMatrix<Type,SO>& m );
5793 
5794 template< bool RF, typename Type, bool SO >
5795 bool isDefault( const CompressedMatrix<Type,SO>& m );
5796 
5797 template< typename Type, bool SO >
5798 bool isIntact( const CompressedMatrix<Type,SO>& m );
5799 
5800 template< typename Type, bool SO >
5801 void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) noexcept;
5803 //*************************************************************************************************
5804 
5805 
5806 //*************************************************************************************************
5813 template< typename Type // Data type of the matrix
5814  , bool SO > // Storage order
5816 {
5817  m.reset();
5818 }
5819 //*************************************************************************************************
5820 
5821 
5822 //*************************************************************************************************
5835 template< typename Type // Data type of the matrix
5836  , bool SO > // Storage order
5837 inline void reset( CompressedMatrix<Type,SO>& m, size_t i )
5838 {
5839  m.reset( i );
5840 }
5841 //*************************************************************************************************
5842 
5843 
5844 //*************************************************************************************************
5851 template< typename Type // Data type of the matrix
5852  , bool SO > // Storage order
5854 {
5855  m.clear();
5856 }
5857 //*************************************************************************************************
5858 
5859 
5860 //*************************************************************************************************
5885 template< bool RF // Relaxation flag
5886  , typename Type // Data type of the matrix
5887  , bool SO > // Storage order
5888 inline bool isDefault( const CompressedMatrix<Type,SO>& m )
5889 {
5890  return ( m.rows() == 0UL && m.columns() == 0UL );
5891 }
5892 //*************************************************************************************************
5893 
5894 
5895 //*************************************************************************************************
5913 template< typename Type // Data type of the matrix
5914  , bool SO > // Storage order
5915 inline bool isIntact( const CompressedMatrix<Type,SO>& m )
5916 {
5917  return ( m.nonZeros() <= m.capacity() );
5918 }
5919 //*************************************************************************************************
5920 
5921 
5922 //*************************************************************************************************
5930 template< typename Type // Data type of the matrix
5931  , bool SO > // Storage order
5933 {
5934  a.swap( b );
5935 }
5936 //*************************************************************************************************
5937 
5938 
5939 
5940 
5941 //=================================================================================================
5942 //
5943 // ISRESIZABLE SPECIALIZATIONS
5944 //
5945 //=================================================================================================
5946 
5947 //*************************************************************************************************
5949 template< typename T, bool SO >
5950 struct IsResizable< CompressedMatrix<T,SO> >
5951  : public TrueType
5952 {};
5954 //*************************************************************************************************
5955 
5956 
5957 
5958 
5959 //=================================================================================================
5960 //
5961 // ISSHRINKABLE SPECIALIZATIONS
5962 //
5963 //=================================================================================================
5964 
5965 //*************************************************************************************************
5967 template< typename T, bool SO >
5968 struct IsShrinkable< CompressedMatrix<T,SO> >
5969  : public TrueType
5970 {};
5972 //*************************************************************************************************
5973 
5974 
5975 
5976 
5977 //=================================================================================================
5978 //
5979 // ADDTRAIT SPECIALIZATIONS
5980 //
5981 //=================================================================================================
5982 
5983 //*************************************************************************************************
5985 template< typename T1, typename T2 >
5986 struct AddTraitEval2< T1, T2
5987  , EnableIf_t< IsSparseMatrix_v<T1> && IsSparseMatrix_v<T2> > >
5988 {
5989  using ET1 = ElementType_t<T1>;
5990  using ET2 = ElementType_t<T2>;
5991 
5992  static constexpr bool SO = ( StorageOrder_v<T1> && StorageOrder_v<T2> );
5993 
5994  using Type = CompressedMatrix< AddTrait_t<ET1,ET2>, SO >;
5995 };
5997 //*************************************************************************************************
5998 
5999 
6000 
6001 
6002 //=================================================================================================
6003 //
6004 // SUBTRAIT SPECIALIZATIONS
6005 //
6006 //=================================================================================================
6007 
6008 //*************************************************************************************************
6010 template< typename T1, typename T2 >
6011 struct SubTraitEval2< T1, T2
6012  , EnableIf_t< IsSparseMatrix_v<T1> && IsSparseMatrix_v<T2> > >
6013 {
6014  using ET1 = ElementType_t<T1>;
6015  using ET2 = ElementType_t<T2>;
6016 
6017  static constexpr bool SO = ( StorageOrder_v<T1> && StorageOrder_v<T2> );
6018 
6019  using Type = CompressedMatrix< SubTrait_t<ET1,ET2>, SO >;
6020 };
6022 //*************************************************************************************************
6023 
6024 
6025 
6026 
6027 //=================================================================================================
6028 //
6029 // SCHURTRAIT SPECIALIZATIONS
6030 //
6031 //=================================================================================================
6032 
6033 //*************************************************************************************************
6035 template< typename T1 // Type of the left-hand side operand
6036  , typename T2 > // Type of the right-hand side operand
6037 struct SchurTraitEval2< T1, T2
6038  , EnableIf_t< IsMatrix_v<T1> &&
6039  IsMatrix_v<T2> &&
6040  ( IsSparseMatrix_v<T1> || IsSparseMatrix_v<T2> ) > >
6041 {
6042  using ET1 = ElementType_t<T1>;
6043  using ET2 = ElementType_t<T2>;
6044 
6045  static constexpr bool SO = ( IsSparseMatrix_v<T1> && IsSparseMatrix_v<T2>
6046  ? ( StorageOrder_v<T1> && StorageOrder_v<T2> )
6047  : ( IsSparseMatrix_v<T1>
6048  ? StorageOrder_v<T1>
6049  : StorageOrder_v<T2> ) );
6050 
6051  using Type = CompressedMatrix< MultTrait_t<ET1,ET2>, SO >;
6052 };
6054 //*************************************************************************************************
6055 
6056 
6057 
6058 
6059 //=================================================================================================
6060 //
6061 // MULTTRAIT SPECIALIZATIONS
6062 //
6063 //=================================================================================================
6064 
6065 //*************************************************************************************************
6067 template< typename T1, typename T2 >
6068 struct MultTraitEval2< T1, T2
6069  , EnableIf_t< IsSparseMatrix_v<T1> && IsNumeric_v<T2> > >
6070 {
6071  using ET1 = ElementType_t<T1>;
6072 
6073  using Type = CompressedMatrix< MultTrait_t<ET1,T2>, StorageOrder_v<T1> >;
6074 };
6075 
6076 template< typename T1, typename T2 >
6077 struct MultTraitEval2< T1, T2
6078  , EnableIf_t< IsNumeric_v<T1> && IsSparseMatrix_v<T2> > >
6079 {
6080  using ET2 = ElementType_t<T2>;
6081 
6082  using Type = CompressedMatrix< MultTrait_t<T1,ET2>, StorageOrder_v<T2> >;
6083 };
6084 
6085 template< typename T1, typename T2 >
6086 struct MultTraitEval2< T1, T2
6087  , EnableIf_t< ( IsSparseVector_v<T1> ||
6088  IsSparseVector_v<T2> ) &&
6089  IsColumnVector_v<T1> &&
6090  IsRowVector_v<T2> > >
6091 {
6092  using ET1 = ElementType_t<T1>;
6093  using ET2 = ElementType_t<T2>;
6094 
6095  static constexpr bool SO = ( IsSparseVector_v<T2> ? rowMajor : columnMajor );
6096 
6097  using Type = CompressedMatrix< MultTrait_t<ET1,ET2>, SO >;
6098 };
6099 
6100 template< typename T1, typename T2 >
6101 struct MultTraitEval2< T1, T2
6102  , EnableIf_t< IsSparseMatrix_v<T1> &&
6103  IsSparseMatrix_v<T2> &&
6104  !( IsIdentity_v<T1> && IsIdentity_v<T2> ) > >
6105 {
6106  using ET1 = ElementType_t<T1>;
6107  using ET2 = ElementType_t<T2>;
6108 
6109  using Type = CompressedMatrix< MultTrait_t<ET1,ET2>, StorageOrder_v<T1> >;
6110 };
6112 //*************************************************************************************************
6113 
6114 
6115 
6116 
6117 //=================================================================================================
6118 //
6119 // KRONTRAIT SPECIALIZATIONS
6120 //
6121 //=================================================================================================
6122 
6123 //*************************************************************************************************
6125 template< typename T1 // Type of the left-hand side operand
6126  , typename T2 > // Type of the right-hand side operand
6127 struct KronTraitEval2< T1, T2
6128  , EnableIf_t< IsMatrix_v<T1> &&
6129  IsMatrix_v<T2> &&
6130  ( IsSparseMatrix_v<T1> || IsSparseMatrix_v<T2> ) > >
6131 {
6132  using ET1 = ElementType_t<T1>;
6133  using ET2 = ElementType_t<T2>;
6134 
6135  static constexpr bool SO = ( IsDenseMatrix_v<T2> ? StorageOrder_v<T1> : StorageOrder_v<T2> );
6136 
6137  using Type = CompressedMatrix< MultTrait_t<ET1,ET2>, SO >;
6138 };
6140 //*************************************************************************************************
6141 
6142 
6143 
6144 
6145 //=================================================================================================
6146 //
6147 // DIVTRAIT SPECIALIZATIONS
6148 //
6149 //=================================================================================================
6150 
6151 //*************************************************************************************************
6153 template< typename T1, typename T2 >
6154 struct DivTraitEval2< T1, T2
6155  , EnableIf_t< IsSparseMatrix_v<T1> && IsNumeric_v<T2> > >
6156 {
6157  using ET1 = ElementType_t<T1>;
6158 
6159  using Type = CompressedMatrix< DivTrait_t<ET1,T2>, StorageOrder_v<T1> >;
6160 };
6162 //*************************************************************************************************
6163 
6164 
6165 
6166 
6167 //=================================================================================================
6168 //
6169 // MAPTRAIT SPECIALIZATIONS
6170 //
6171 //=================================================================================================
6172 
6173 //*************************************************************************************************
6175 template< typename T, typename OP >
6176 struct UnaryMapTraitEval2< T, OP
6177  , EnableIf_t< IsSparseMatrix_v<T> > >
6178 {
6179  using ET = ElementType_t<T>;
6180 
6181  using Type = CompressedMatrix< MapTrait_t<ET,OP>, StorageOrder_v<T> >;
6182 };
6184 //*************************************************************************************************
6185 
6186 
6187 
6188 
6189 //=================================================================================================
6190 //
6191 // EXPANDTRAIT SPECIALIZATIONS
6192 //
6193 //=================================================================================================
6194 
6195 //*************************************************************************************************
6197 template< typename T // Type to be expanded
6198  , size_t E > // Compile time expansion
6199 struct ExpandTraitEval2< T, E
6200  , EnableIf_t< IsSparseVector_v<T> > >
6201 {
6202  static constexpr bool TF = ( IsColumnVector_v<T> ? columnMajor : rowMajor );
6203 
6204  using Type = CompressedMatrix< ElementType_t<T>, TF >;
6205 };
6207 //*************************************************************************************************
6208 
6209 
6210 
6211 
6212 //=================================================================================================
6213 //
6214 // HIGHTYPE SPECIALIZATIONS
6215 //
6216 //=================================================================================================
6217 
6218 //*************************************************************************************************
6220 template< typename T1, bool SO, typename T2 >
6221 struct HighType< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6222 {
6223  using Type = CompressedMatrix< typename HighType<T1,T2>::Type, SO >;
6224 };
6226 //*************************************************************************************************
6227 
6228 
6229 
6230 
6231 //=================================================================================================
6232 //
6233 // LOWTYPE SPECIALIZATIONS
6234 //
6235 //=================================================================================================
6236 
6237 //*************************************************************************************************
6239 template< typename T1, bool SO, typename T2 >
6240 struct LowType< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6241 {
6242  using Type = CompressedMatrix< typename LowType<T1,T2>::Type, SO >;
6243 };
6245 //*************************************************************************************************
6246 
6247 
6248 
6249 
6250 //=================================================================================================
6251 //
6252 // SUBMATRIXTRAIT SPECIALIZATIONS
6253 //
6254 //=================================================================================================
6255 
6256 //*************************************************************************************************
6258 template< typename MT, size_t I, size_t J, size_t M, size_t N >
6259 struct SubmatrixTraitEval2< MT, I, J, M, N
6260  , EnableIf_t< IsSparseMatrix_v<MT> > >
6261 {
6262  using Type = CompressedMatrix< RemoveConst_t< ElementType_t<MT> >, StorageOrder_v<MT> >;
6263 };
6265 //*************************************************************************************************
6266 
6267 
6268 
6269 
6270 //=================================================================================================
6271 //
6272 // ROWSTRAIT SPECIALIZATIONS
6273 //
6274 //=================================================================================================
6275 
6276 //*************************************************************************************************
6278 template< typename MT, size_t M >
6279 struct RowsTraitEval2< MT, M
6280  , EnableIf_t< IsSparseMatrix_v<MT> > >
6281 {
6282  using Type = CompressedMatrix< RemoveConst_t< ElementType_t<MT> >, false >;
6283 };
6285 //*************************************************************************************************
6286 
6287 
6288 
6289 
6290 //=================================================================================================
6291 //
6292 // COLUMNSTRAIT SPECIALIZATIONS
6293 //
6294 //=================================================================================================
6295 
6296 //*************************************************************************************************
6298 template< typename MT, size_t N >
6299 struct ColumnsTraitEval2< MT, N
6300  , EnableIf_t< IsSparseMatrix_v<MT> > >
6301 {
6302  using Type = CompressedMatrix< RemoveConst_t< ElementType_t<MT> >, true >;
6303 };
6305 //*************************************************************************************************
6306 
6307 } // namespace blaze
6308 
6309 #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,...
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:1916
Header file for auxiliary alias declarations.
Headerfile for the generic min algorithm.
Iterator * end_
Pointers one past the last non-zero element of each row.
Definition: CompressedMatrix.h:535
Header file for the Schur product trait.
void schurAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the Schur product assignment of a dense matrix.
Definition: CompressedMatrix.h:2965
constexpr bool IsMatrix_v
Auxiliary variable template for the IsMatrix type trait.The IsMatrix_v variable template provides a c...
Definition: IsMatrix.h:138
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression,...
Definition: Assert.h:117
void shrinkToFit()
Requesting the removal of unused capacity.
Definition: CompressedMatrix.h:1856
Header file for the subtraction trait.
bool canSMPAssign() const noexcept
Returns whether the matrix can be used in SMP assignments.
Definition: CompressedMatrix.h:2701
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:546
Header file for basic type definitions.
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: CompressedMatrix.h:2682
CompressedMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: CompressedMatrix.h:2601
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5932
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:324
Header file for the IsSparseMatrix type trait.
CompressedMatrix()
The default constructor for CompressedMatrix.
Definition: CompressedMatrix.h:579
Header file for the serial shim.
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:227
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: CompressedMatrix.h:355
Iterator end(size_t i) noexcept
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:1028
Reference operator()(size_t i, size_t j) noexcept
2D-access to the compressed matrix elements.
Definition: CompressedMatrix.h:854
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
MatrixAccessProxy< This > Reference
Reference to a compressed matrix value.
Definition: CompressedMatrix.h:325
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:595
void clear()
Clearing the compressed matrix.
Definition: CompressedMatrix.h:1593
Header file for the IsRowVector type trait.
Header file for the IsIdentity type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.In case the given data type is a volatile-qualified type,...
Definition: Volatile.h:79
SparseMatrix< This, SO > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:318
~CompressedMatrix()
The destructor for CompressedMatrix.
Definition: CompressedMatrix.h:820
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:584
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:1464
BoolConstant< true > TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: IntegralConstant.h:132
Header file for all forward declarations of the math module.
Header file for memory allocation and deallocation functionality.
Iterator castDown(IteratorBase it) const noexcept
Performs a down-cast of the given iterator.
Definition: CompressedMatrix.h:1955
Header file for the extended initializer_list functionality.
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first non-zero element of row/column i.
Definition: CompressedMatrix.h:1006
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
constexpr bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes....
Definition: DenseMatrix.h:81
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes....
Definition: Forward.h:145
void swap(CompressedMatrix &sm) noexcept
Swapping the contents of two sparse matrices.
Definition: CompressedMatrix.h:1873
Constraint on the data type.
Header file for the IsMatrix type trait.
CompressedMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:320
Header file for the SparseMatrix base class.
ElementBase * IteratorBase
Iterator over non-constant base elements.
Definition: CompressedMatrix.h:233
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:533
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.The EnableIf_t alias declaration provides a convenient...
Definition: EnableIf.h:138
void reserve(size_t nonzeros)
Setting the minimum capacity of the compressed matrix.
Definition: CompressedMatrix.h:1717
void reset()
Reset to the default initial values.
Definition: CompressedMatrix.h:1555
constexpr bool columnMajor
Storage order flag for column-major matrices.
Definition: StorageOrder.h:99
Headerfile for the generic max algorithm.
Header file for the ValueIndexPair class.
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:58
decltype(auto) ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatMapExpr.h:1361
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:321
Header file for the IsFloatingPoint type trait.
Header file for the IsShrinkable type trait.
Iterator set(size_t i, size_t j, const Type &value)
Setting an element of the compressed matrix.
Definition: CompressedMatrix.h:2003
Header file for the MatrixAccessProxy class.
IteratorBase castUp(Iterator it) const noexcept
Performs an up-cast of the given iterator.
Definition: CompressedMatrix.h:1973
#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.
Header file for the expand trait.
void erase(size_t i, size_t j)
Erasing an element from the compressed matrix.
Definition: CompressedMatrix.h:2247
size_t rows() const noexcept
Returns the current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:1450
#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't have the same size,...
Definition: SameSize.h:60
constexpr bool IsNumeric_v
Auxiliary variable template for the IsNumeric type trait.The IsNumeric_v variable template provides a...
Definition: IsNumeric.h:143
size_t capacity() const noexcept
Returns the maximum capacity of the compressed matrix.
Definition: CompressedMatrix.h:1478
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:537
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:1072
Constraint on the data type.
CompressedMatrix< Type, SO > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:317
Header file for the IsLower type trait.
Header file for the default storage order for all vectors of the Blaze library.
Header file for the Kron product trait.
Iterator insert(size_t i, size_t j, const Type &value)
Inserting an element into the compressed matrix.
Definition: CompressedMatrix.h:2035
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:323
Header file for the exception macros of the math module.
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1198
void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:738
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:438
Constraint on the data type.
void subAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the subtraction assignment of a dense matrix.
Definition: CompressedMatrix.h:2913
size_t nonZeros() const
Returns the number of non-zero elements in the compressed matrix.
Definition: CompressedMatrix.h:1515
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:615
CompressedMatrix & operator=(initializer_list< initializer_list< Type > > list)
List assignment to all matrix elements.
Definition: CompressedMatrix.h:1112
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the compressed matrix.
Definition: CompressedMatrix.h:1620
Header file for the IsNumeric type trait.
Header file for the RemoveConst type trait.
Header file for the IsSparseVector type trait.
#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,...
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:2662
CompressedMatrix< NewType, SO > Other
The type of the other CompressedMatrix.
Definition: CompressedMatrix.h:336
Header file for run time assertion macros.
Header file for the relaxation flag types.
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.The CompositeType_t alias declaration pro...
Definition: Aliases.h:90
Header file for the addition trait.
Resize mechanism to obtain a CompressedMatrix with different fixed dimensions.
Definition: CompressedMatrix.h:345
CompressedMatrix & transpose()
In-place transpose of the matrix.
Definition: CompressedMatrix.h:2585
Header file for the division trait.
void trim()
Removing all excessive capacity from all rows/columns.
Definition: CompressedMatrix.h:1813
Header file for the submatrix trait.
Constraint on the data type.
Header file for the columns trait.
Headerfile for the generic transfer algorithm.
Header file for the IsZero type trait.
#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,...
Definition: Reference.h:79
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:282
const Type & ConstReference
Reference to a constant compressed matrix value.
Definition: CompressedMatrix.h:326
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:114
constexpr Reference value() noexcept
Access to the current value of the value-index-pair.
Definition: ValueIndexPair.h:370
Constraint on the data type.
Constraint on the data type.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:328
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:808
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
void assign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the assignment of a row-major dense matrix.
Definition: CompressedMatrix.h:2723
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
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:2185
void finalize(size_t i)
Finalizing the element insertion of a row/column.
Definition: CompressedMatrix.h:2217
Iterator find(size_t i, size_t j)
Searches for a specific matrix element.
Definition: CompressedMatrix.h:2425
Header file for the rows trait.
Iterator * begin_
Pointers to the first non-zero element of each row.
Definition: CompressedMatrix.h:534
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
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.
void addAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the addition assignment of a dense matrix.
Definition: CompressedMatrix.h:2861
EnableIf_t< IsBuiltin_v< T > > deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:224
Header file for the default transpose flag for all vectors of the Blaze library.
Initializer list type of the Blaze library.
Iterator lowerBound(size_t i, size_t j)
Returns an iterator to the first index not less than the given index.
Definition: CompressedMatrix.h:2478
Iterator upperBound(size_t i, size_t j)
Returns an iterator to the first index greater than the given index.
Definition: CompressedMatrix.h:2533
Header file for the StorageOrder type trait.
Header file for the IntegralConstant class template.
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:327
Header file for the map trait.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:264
CompressedMatrix< Type, SO > Other
The type of the other CompressedMatrix.
Definition: CompressedMatrix.h:346
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:635
size_t extendCapacity() const noexcept
Calculating a new matrix capacity.
Definition: CompressedMatrix.h:1896
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:335
Header file for the IsUpper type trait.
size_t n_
The current number of columns of the compressed matrix.
Definition: CompressedMatrix.h:532
constexpr bool IsSparseVector_v
Auxiliary variable template for the IsSparseVector type trait.The IsSparseVector_v variable template ...
Definition: IsSparseVector.h:138
Header file for the IsColumnVector type trait.
OutputIterator transfer(InputIterator first, InputIterator last, OutputIterator dest)
Transfers the elements from the given source range to the destination range.
Definition: Transfer.h:70
ValueIndexPair< Type > ElementBase
Base class for the compressed matrix element.
Definition: CompressedMatrix.h:232
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: CompressedMatrix.h:908
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:319
Header file for the IsResizable type trait.
size_t m_
The current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:531
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,...
Definition: Assert.h:101
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:322
constexpr size_t determineColumns(initializer_list< initializer_list< Type > > list) noexcept
Determines the maximum number of columns specified by the given initializer list.
Definition: InitializerList.h:108
constexpr bool IsSparseMatrix_v
Auxiliary variable template for the IsSparseMatrix type trait.The IsSparseMatrix_v variable template ...
Definition: IsSparseMatrix.h:138
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:962