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>
85 #include <blaze/util/Assert.h>
91 #include <blaze/util/EnableIf.h>
92 #include <blaze/util/Memory.h>
93 #include <blaze/util/mpl/And.h>
94 #include <blaze/util/mpl/If.h>
95 #include <blaze/util/mpl/Not.h>
96 #include <blaze/util/Types.h>
99 
100 
101 namespace blaze {
102 
103 //=================================================================================================
104 //
105 // CLASS DEFINITION
106 //
107 //=================================================================================================
108 
109 //*************************************************************************************************
219 template< typename Type // Data type of the matrix
220  , bool SO = defaultStorageOrder > // Storage order
222  : public SparseMatrix< CompressedMatrix<Type,SO>, SO >
223 {
224  private:
225  //**Type definitions****************************************************************************
228  //**********************************************************************************************
229 
230  //**Private class Element***********************************************************************
237  struct Element
238  : public ElementBase
239  {
240  //**Constructors*****************************************************************************
241  explicit Element() = default;
242  Element( const Element& rhs ) = default;
243  Element( Element&& rhs ) = default;
244  //*******************************************************************************************
245 
246  //**Assignment operators*********************************************************************
247  inline Element& operator=( const Element& rhs )
248  {
249  this->value_ = rhs.value_;
250  return *this;
251  }
252 
253  inline Element& operator=( Element&& rhs )
254  {
255  this->value_ = std::move( rhs.value_ );
256  return *this;
257  }
258 
259  template< typename Other >
260  inline EnableIf_< IsSparseElement<Other>, Element& >
261  operator=( const Other& rhs )
262  {
263  this->value_ = rhs.value();
264  return *this;
265  }
266 
267  template< typename Other >
269  , IsRValueReference<Other&&> >, Element& >
270  operator=( Other&& rhs )
271  {
272  this->value_ = std::move( rhs.value() );
273  return *this;
274  }
275 
276  template< typename Other >
277  inline EnableIf_< Not< IsSparseElement<Other> >, Element& >
278  operator=( const Other& v )
279  {
280  this->value_ = v;
281  return *this;
282  }
283 
284  template< typename Other >
286  , IsRValueReference<Other&&> >, Element& >
287  operator=( Other&& v )
288  {
289  this->value_ = std::move( v );
290  return *this;
291  }
292  //*******************************************************************************************
293 
294  //**Friend declarations**********************************************************************
295  friend class CompressedMatrix;
296  //*******************************************************************************************
297  };
299  //**********************************************************************************************
300 
301  //**Private class Uninitialized*****************************************************************
305  struct Uninitialized {};
307  //**********************************************************************************************
308 
309  public:
310  //**Type definitions****************************************************************************
313  using ResultType = This;
316  using ElementType = Type;
317  using ReturnType = const Type&;
318  using CompositeType = const This&;
320  using ConstReference = const Type&;
321  using Iterator = Element*;
322  using ConstIterator = const Element*;
323  //**********************************************************************************************
324 
325  //**Rebind struct definition********************************************************************
328  template< typename NewType > // Data type of the other matrix
329  struct Rebind {
331  };
332  //**********************************************************************************************
333 
334  //**Resize struct definition********************************************************************
337  template< size_t NewM // Number of rows of the other matrix
338  , size_t NewN > // Number of columns of the other matrix
339  struct Resize {
341  };
342  //**********************************************************************************************
343 
344  //**Compilation flags***************************************************************************
346 
349  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
350  //**********************************************************************************************
351 
352  //**Constructors********************************************************************************
355  explicit inline CompressedMatrix();
356  explicit inline CompressedMatrix( size_t m, size_t n );
357  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
358  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
359  explicit inline CompressedMatrix( initializer_list< initializer_list<Type> > list );
360 
361  inline CompressedMatrix( const CompressedMatrix& sm );
362  inline CompressedMatrix( CompressedMatrix&& sm ) noexcept;
363 
364  template< typename MT, bool SO2 > inline CompressedMatrix( const DenseMatrix<MT,SO2>& dm );
365  template< typename MT, bool SO2 > inline CompressedMatrix( const SparseMatrix<MT,SO2>& sm );
367  //**********************************************************************************************
368 
369  //**Destructor**********************************************************************************
372  inline ~CompressedMatrix();
374  //**********************************************************************************************
375 
376  //**Data access functions***********************************************************************
379  inline Reference operator()( size_t i, size_t j ) noexcept;
380  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
381  inline Reference at( size_t i, size_t j );
382  inline ConstReference at( size_t i, size_t j ) const;
383  inline Iterator begin ( size_t i ) noexcept;
384  inline ConstIterator begin ( size_t i ) const noexcept;
385  inline ConstIterator cbegin( size_t i ) const noexcept;
386  inline Iterator end ( size_t i ) noexcept;
387  inline ConstIterator end ( size_t i ) const noexcept;
388  inline ConstIterator cend ( size_t i ) const noexcept;
390  //**********************************************************************************************
391 
392  //**Assignment operators************************************************************************
395  inline CompressedMatrix& operator=( initializer_list< initializer_list<Type> > list );
396  inline CompressedMatrix& operator=( const CompressedMatrix& rhs );
397  inline CompressedMatrix& operator=( CompressedMatrix&& rhs ) noexcept;
398 
399  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO2>& rhs );
400  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO2>& rhs );
401  template< typename MT, bool SO2 > inline CompressedMatrix& operator+=( const Matrix<MT,SO2>& rhs );
402  template< typename MT, bool SO2 > inline CompressedMatrix& operator-=( const Matrix<MT,SO2>& rhs );
403  template< typename MT, bool SO2 > inline CompressedMatrix& operator%=( const DenseMatrix<MT,SO2>& rhs );
404  template< typename MT, bool SO2 > inline CompressedMatrix& operator%=( const SparseMatrix<MT,SO2>& rhs );
406  //**********************************************************************************************
407 
408  //**Utility functions***************************************************************************
411  inline size_t rows() const noexcept;
412  inline size_t columns() const noexcept;
413  inline size_t capacity() const noexcept;
414  inline size_t capacity( size_t i ) const noexcept;
415  inline size_t nonZeros() const;
416  inline size_t nonZeros( size_t i ) const;
417  inline void reset();
418  inline void reset( size_t i );
419  inline void clear();
420  void resize ( size_t m, size_t n, bool preserve=true );
421  inline void reserve( size_t nonzeros );
422  void reserve( size_t i, size_t nonzeros );
423  inline void trim ();
424  inline void trim ( size_t i );
425  inline void shrinkToFit();
426  inline void swap( CompressedMatrix& sm ) noexcept;
428  //**********************************************************************************************
429 
430  //**Insertion functions*************************************************************************
433  inline Iterator set ( size_t i, size_t j, const Type& value );
434  inline Iterator insert ( size_t i, size_t j, const Type& value );
435  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
436  inline void finalize( size_t i );
438  //**********************************************************************************************
439 
440  //**Erase functions*****************************************************************************
443  inline void erase( size_t i, size_t j );
444  inline Iterator erase( size_t i, Iterator pos );
445  inline Iterator erase( size_t i, Iterator first, Iterator last );
446 
447  template< typename Pred >
448  inline void erase( Pred predicate );
449 
450  template< typename Pred >
451  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
453  //**********************************************************************************************
454 
455  //**Lookup functions****************************************************************************
458  inline Iterator find ( size_t i, size_t j );
459  inline ConstIterator find ( size_t i, size_t j ) const;
460  inline Iterator lowerBound( size_t i, size_t j );
461  inline ConstIterator lowerBound( size_t i, size_t j ) const;
462  inline Iterator upperBound( size_t i, size_t j );
463  inline ConstIterator upperBound( size_t i, size_t j ) const;
465  //**********************************************************************************************
466 
467  //**Numeric functions***************************************************************************
470  inline CompressedMatrix& transpose();
471  inline CompressedMatrix& ctranspose();
472 
473  template< typename Other > inline CompressedMatrix& scale( const Other& scalar );
475  //**********************************************************************************************
476 
477  //**Expression template evaluation functions****************************************************
480  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
481  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
482 
483  inline bool canSMPAssign() const noexcept;
484 
485  template< typename MT, bool SO2 > inline void assign ( const DenseMatrix<MT,SO2>& rhs );
486  template< typename MT > inline void assign ( const SparseMatrix<MT,SO>& rhs );
487  template< typename MT > inline void assign ( const SparseMatrix<MT,!SO>& rhs );
488  template< typename MT, bool SO2 > inline void addAssign ( const DenseMatrix<MT,SO2>& rhs );
489  template< typename MT, bool SO2 > inline void addAssign ( const SparseMatrix<MT,SO2>& rhs );
490  template< typename MT, bool SO2 > inline void subAssign ( const DenseMatrix<MT,SO2>& rhs );
491  template< typename MT, bool SO2 > inline void subAssign ( const SparseMatrix<MT,SO2>& rhs );
492  template< typename MT, bool SO2 > inline void schurAssign( const DenseMatrix<MT,SO2>& rhs );
494  //**********************************************************************************************
495 
496  private:
497  //**Constructors********************************************************************************
500  explicit inline CompressedMatrix( size_t m, size_t n, Uninitialized );
502  //**********************************************************************************************
503 
504  //**Utility functions***************************************************************************
507  inline size_t extendCapacity() const noexcept;
508  void reserveElements( size_t nonzeros );
509 
510  inline Iterator castDown( IteratorBase it ) const noexcept;
511  inline IteratorBase castUp ( Iterator it ) const noexcept;
513  //**********************************************************************************************
514 
515  //**Insertion functions*************************************************************************
518  Iterator insert( Iterator pos, size_t i, size_t j, const Type& value );
520  //**********************************************************************************************
521 
522  //**Member variables****************************************************************************
525  size_t m_;
526  size_t n_;
527  size_t capacity_;
530 
531  static const Type zero_;
532 
533  //**********************************************************************************************
534 
535  //**Compile time checks*************************************************************************
543  //**********************************************************************************************
544 };
545 //*************************************************************************************************
546 
547 
548 
549 
550 //=================================================================================================
551 //
552 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
553 //
554 //=================================================================================================
555 
556 template< typename Type, bool SO >
558 
559 
560 
561 
562 //=================================================================================================
563 //
564 // CONSTRUCTORS
565 //
566 //=================================================================================================
567 
568 //*************************************************************************************************
571 template< typename Type // Data type of the matrix
572  , bool SO > // Storage order
574  : m_ ( 0UL ) // The current number of rows of the compressed matrix
575  , n_ ( 0UL ) // The current number of columns of the compressed matrix
576  , capacity_( 0UL ) // The current capacity of the pointer array
577  , begin_ ( nullptr ) // Pointers to the first non-zero element of each row
578  , end_ ( nullptr ) // Pointers one past the last non-zero element of each row
579 {}
580 //*************************************************************************************************
581 
582 
583 //*************************************************************************************************
591 template< typename Type // Data type of the matrix
592  , bool SO > // Storage order
594  : CompressedMatrix( m, n, Uninitialized() )
595 {
596  for( size_t i=1UL; i<2UL*m_+2UL; ++i )
597  begin_[i] = nullptr;
598 }
599 //*************************************************************************************************
600 
601 
602 //*************************************************************************************************
611 template< typename Type // Data type of the matrix
612  , bool SO > // Storage order
613 inline CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
614  : CompressedMatrix( m, n, Uninitialized() )
615 {
616  begin_[0UL] = allocate<Element>( nonzeros );
617  for( size_t i=1UL; i<(2UL*m_+1UL); ++i )
618  begin_[i] = begin_[0UL];
619  end_[m_] = begin_[0UL]+nonzeros;
620 }
621 //*************************************************************************************************
622 
623 
624 //*************************************************************************************************
635 template< typename Type // Data type of the matrix
636  , bool SO > // Storage order
637 CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
638  : CompressedMatrix( m, n, Uninitialized() )
639 {
640  BLAZE_USER_ASSERT( nonzeros.size() == m, "Size of capacity vector and number of rows don't match" );
641 
642  size_t newCapacity( 0UL );
643  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
644  newCapacity += *it;
645 
646  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
647  for( size_t i=0UL; i<m_; ++i ) {
648  begin_[i+1UL] = end_[i+1UL] = begin_[i] + nonzeros[i];
649  }
650 }
651 //*************************************************************************************************
652 
653 
654 //*************************************************************************************************
674 template< typename Type // Data type of the matrix
675  , bool SO > // Storage order
677  : CompressedMatrix( list.size(), determineColumns( list ), blaze::nonZeros( list ) )
678 {
679  size_t i( 0UL );
680 
681  for( const auto& rowList : list )
682  {
683  size_t j( 0UL );
684 
685  for( const Type& element : rowList ) {
686  if( !isDefault<strict>( element ) )
687  append( i, j, element );
688  ++j;
689  }
690 
691  finalize( i );
692  ++i;
693  }
694 }
695 //*************************************************************************************************
696 
697 
698 //*************************************************************************************************
703 template< typename Type // Data type of the matrix
704  , bool SO > // Storage order
706  : CompressedMatrix( sm.m_, sm.n_, Uninitialized() )
707 {
708  const size_t nonzeros( sm.nonZeros() );
709 
710  begin_[0UL] = allocate<Element>( nonzeros );
711  for( size_t i=0UL; i<m_; ++i ) {
712  end_[i] = castDown( std::copy( sm.begin(i), sm.end(i), castUp( begin_[i] ) ) );
713  begin_[i+1UL] = end_[i];
714  }
715  end_[m_] = begin_[0UL]+nonzeros;
716 }
717 //*************************************************************************************************
718 
719 
720 //*************************************************************************************************
725 template< typename Type // Data type of the matrix
726  , bool SO > // Storage order
728  : m_ ( sm.m_ ) // The current number of rows of the compressed matrix
729  , n_ ( sm.n_ ) // The current number of columns of the compressed matrix
730  , capacity_( sm.capacity_ ) // The current capacity of the pointer array
731  , begin_ ( sm.begin_ ) // Pointers to the first non-zero element of each row
732  , end_ ( sm.end_ ) // Pointers one past the last non-zero element of each row
733 {
734  sm.m_ = 0UL;
735  sm.n_ = 0UL;
736  sm.capacity_ = 0UL;
737  sm.begin_ = nullptr;
738  sm.end_ = nullptr;
739 }
740 //*************************************************************************************************
741 
742 
743 //*************************************************************************************************
748 template< typename Type // Data type of the matrix
749  , bool SO > // Storage order
750 template< typename MT // Type of the foreign dense matrix
751  , bool SO2 > // Storage order of the foreign dense matrix
753  : CompressedMatrix( (~dm).rows(), (~dm).columns() )
754 {
755  using blaze::assign;
756 
757  assign( *this, ~dm );
758 }
759 //*************************************************************************************************
760 
761 
762 //*************************************************************************************************
767 template< typename Type // Data type of the matrix
768  , bool SO > // Storage order
769 template< typename MT // Type of the foreign compressed matrix
770  , bool SO2 > // Storage order of the foreign compressed matrix
772  : CompressedMatrix( (~sm).rows(), (~sm).columns(), (~sm).nonZeros() )
773 {
774  using blaze::assign;
775 
776  assign( *this, ~sm );
777 }
778 //*************************************************************************************************
779 
780 
781 //*************************************************************************************************
787 template< typename Type // Data type of the matrix
788  , bool SO > // Storage order
789 inline CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, Uninitialized )
790  : m_ ( m ) // The current number of rows of the compressed matrix
791  , n_ ( n ) // The current number of columns of the compressed matrix
792  , capacity_( m ) // The current capacity of the pointer array
793  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
794  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
795 {
796  begin_[0] = nullptr;
797 }
798 //*************************************************************************************************
799 
800 
801 
802 
803 //=================================================================================================
804 //
805 // DESTRUCTOR
806 //
807 //=================================================================================================
808 
809 //*************************************************************************************************
812 template< typename Type // Data type of the matrix
813  , bool SO > // Storage order
815 {
816  if( begin_ != nullptr ) {
817  deallocate( begin_[0UL] );
818  delete[] begin_;
819  }
820 }
821 //*************************************************************************************************
822 
823 
824 
825 
826 //=================================================================================================
827 //
828 // DATA ACCESS FUNCTIONS
829 //
830 //=================================================================================================
831 
832 //*************************************************************************************************
845 template< typename Type // Data type of the matrix
846  , bool SO > // Storage order
848  CompressedMatrix<Type,SO>::operator()( size_t i, size_t j ) noexcept
849 {
850  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
851  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
852 
853  return Reference( *this, i, j );
854 }
855 //*************************************************************************************************
856 
857 
858 //*************************************************************************************************
868 template< typename Type // Data type of the matrix
869  , bool SO > // Storage order
871  CompressedMatrix<Type,SO>::operator()( size_t i, size_t j ) const noexcept
872 {
873  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
874  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
875 
876  const ConstIterator pos( lowerBound( i, j ) );
877 
878  if( pos == end_[i] || pos->index_ != j )
879  return zero_;
880  else
881  return pos->value_;
882 }
883 //*************************************************************************************************
884 
885 
886 //*************************************************************************************************
899 template< typename Type // Data type of the matrix
900  , bool SO > // Storage order
902  CompressedMatrix<Type,SO>::at( size_t i, size_t j )
903 {
904  if( i >= m_ ) {
905  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
906  }
907  if( j >= n_ ) {
908  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
909  }
910  return (*this)(i,j);
911 }
912 //*************************************************************************************************
913 
914 
915 //*************************************************************************************************
926 template< typename Type // Data type of the matrix
927  , bool SO > // Storage order
929  CompressedMatrix<Type,SO>::at( size_t i, size_t j ) const
930 {
931  if( i >= m_ ) {
932  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
933  }
934  if( j >= n_ ) {
935  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
936  }
937  return (*this)(i,j);
938 }
939 //*************************************************************************************************
940 
941 
942 //*************************************************************************************************
953 template< typename Type // Data type of the matrix
954  , bool SO > // Storage order
956  CompressedMatrix<Type,SO>::begin( size_t i ) noexcept
957 {
958  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
959  return begin_[i];
960 }
961 //*************************************************************************************************
962 
963 
964 //*************************************************************************************************
975 template< typename Type // Data type of the matrix
976  , bool SO > // Storage order
978  CompressedMatrix<Type,SO>::begin( size_t i ) const noexcept
979 {
980  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
981  return begin_[i];
982 }
983 //*************************************************************************************************
984 
985 
986 //*************************************************************************************************
997 template< typename Type // Data type of the matrix
998  , bool SO > // Storage order
1000  CompressedMatrix<Type,SO>::cbegin( size_t i ) const noexcept
1001 {
1002  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1003  return begin_[i];
1004 }
1005 //*************************************************************************************************
1006 
1007 
1008 //*************************************************************************************************
1019 template< typename Type // Data type of the matrix
1020  , bool SO > // Storage order
1022  CompressedMatrix<Type,SO>::end( size_t i ) noexcept
1023 {
1024  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1025  return end_[i];
1026 }
1027 //*************************************************************************************************
1028 
1029 
1030 //*************************************************************************************************
1041 template< typename Type // Data type of the matrix
1042  , bool SO > // Storage order
1044  CompressedMatrix<Type,SO>::end( size_t i ) const noexcept
1045 {
1046  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1047  return end_[i];
1048 }
1049 //*************************************************************************************************
1050 
1051 
1052 //*************************************************************************************************
1063 template< typename Type // Data type of the matrix
1064  , bool SO > // Storage order
1066  CompressedMatrix<Type,SO>::cend( size_t i ) const noexcept
1067 {
1068  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1069  return end_[i];
1070 }
1071 //*************************************************************************************************
1072 
1073 
1074 
1075 
1076 //=================================================================================================
1077 //
1078 // ASSIGNMENT OPERATORS
1079 //
1080 //=================================================================================================
1081 
1082 //*************************************************************************************************
1103 template< typename Type // Data type of the matrix
1104  , bool SO > // Storage order
1107 {
1108  using blaze::nonZeros;
1109 
1110  resize( list.size(), determineColumns( list ), false );
1111  reserve( nonZeros( list ) );
1112 
1113  size_t i( 0UL );
1114 
1115  for( const auto& rowList : list )
1116  {
1117  size_t j( 0UL );
1118 
1119  for( const Type& element : rowList ) {
1120  if( !isDefault<strict>( element ) )
1121  append( i, j, element );
1122  ++j;
1123  }
1124 
1125  finalize( i );
1126  ++i;
1127  }
1128 
1129  return *this;
1130 }
1131 //*************************************************************************************************
1132 
1133 
1134 //*************************************************************************************************
1143 template< typename Type // Data type of the matrix
1144  , bool SO > // Storage order
1147 {
1148  using std::swap;
1149 
1150  if( &rhs == this ) return *this;
1151 
1152  const size_t nonzeros( rhs.nonZeros() );
1153 
1154  if( rhs.m_ > capacity_ || nonzeros > capacity() )
1155  {
1156  Iterator* newBegin( new Iterator[2UL*rhs.m_+2UL] );
1157  Iterator* newEnd ( newBegin+(rhs.m_+1UL) );
1158 
1159  newBegin[0UL] = allocate<Element>( nonzeros );
1160  for( size_t i=0UL; i<rhs.m_; ++i ) {
1161  newEnd[i] = castDown( std::copy( rhs.begin_[i], rhs.end_[i], castUp( newBegin[i] ) ) );
1162  newBegin[i+1UL] = newEnd[i];
1163  }
1164  newEnd[rhs.m_] = newBegin[0UL]+nonzeros;
1165 
1166  swap( begin_, newBegin );
1167  end_ = newEnd;
1168  capacity_ = rhs.m_;
1169 
1170  if( newBegin != nullptr ) {
1171  deallocate( newBegin[0UL] );
1172  delete[] newBegin;
1173  }
1174  }
1175  else {
1176  for( size_t i=0UL; i<rhs.m_; ++i ) {
1177  end_[i] = castDown( std::copy( rhs.begin_[i], rhs.end_[i], castUp( begin_[i] ) ) );
1178  begin_[i+1UL] = end_[i];
1179  }
1180  }
1181 
1182  m_ = rhs.m_;
1183  n_ = rhs.n_;
1184 
1185  return *this;
1186 }
1187 //*************************************************************************************************
1188 
1189 
1190 //*************************************************************************************************
1196 template< typename Type // Data type of the matrix
1197  , bool SO > // Storage order
1200 {
1201  if( begin_ != nullptr ) {
1202  deallocate( begin_[0UL] );
1203  delete[] begin_;
1204  }
1205 
1206  m_ = rhs.m_;
1207  n_ = rhs.n_;
1208  capacity_ = rhs.capacity_;
1209  begin_ = rhs.begin_;
1210  end_ = rhs.end_;
1211 
1212  rhs.m_ = 0UL;
1213  rhs.n_ = 0UL;
1214  rhs.capacity_ = 0UL;
1215  rhs.begin_ = nullptr;
1216  rhs.end_ = nullptr;
1217 
1218  return *this;
1219 }
1220 //*************************************************************************************************
1221 
1222 
1223 //*************************************************************************************************
1232 template< typename Type // Data type of the matrix
1233  , bool SO > // Storage order
1234 template< typename MT // Type of the right-hand side dense matrix
1235  , bool SO2 > // Storage order of the right-hand side dense matrix
1238 {
1239  using blaze::assign;
1240 
1241  if( (~rhs).canAlias( this ) ) {
1242  CompressedMatrix tmp( ~rhs );
1243  swap( tmp );
1244  }
1245  else {
1246  resize( (~rhs).rows(), (~rhs).columns(), false );
1247  assign( *this, ~rhs );
1248  }
1249 
1250  return *this;
1251 }
1252 //*************************************************************************************************
1253 
1254 
1255 //*************************************************************************************************
1264 template< typename Type // Data type of the matrix
1265  , bool SO > // Storage order
1266 template< typename MT // Type of the right-hand side compressed matrix
1267  , bool SO2 > // Storage order of the right-hand side compressed matrix
1270 {
1271  using blaze::assign;
1272 
1273  if( (~rhs).canAlias( this ) ||
1274  (~rhs).rows() > capacity_ ||
1275  (~rhs).nonZeros() > capacity() ) {
1276  CompressedMatrix tmp( ~rhs );
1277  swap( tmp );
1278  }
1279  else {
1280  resize( (~rhs).rows(), (~rhs).columns(), false );
1281  reset();
1282  assign( *this, ~rhs );
1283  }
1284 
1285  return *this;
1286 }
1287 //*************************************************************************************************
1288 
1289 
1290 //*************************************************************************************************
1300 template< typename Type // Data type of the matrix
1301  , bool SO > // Storage order
1302 template< typename MT // Type of the right-hand side matrix
1303  , bool SO2 > // Storage order of the right-hand side matrix
1306 {
1307  using blaze::addAssign;
1308 
1309  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1310  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1311  }
1312 
1313  addAssign( *this, ~rhs );
1314  return *this;
1315 }
1316 //*************************************************************************************************
1317 
1318 
1319 //*************************************************************************************************
1329 template< typename Type // Data type of the matrix
1330  , bool SO > // Storage order
1331 template< typename MT // Type of the right-hand side matrix
1332  , bool SO2 > // Storage order of the right-hand side matrix
1334 {
1335  using blaze::subAssign;
1336 
1337  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1338  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1339  }
1340 
1341  subAssign( *this, ~rhs );
1342  return *this;
1343 }
1344 //*************************************************************************************************
1345 
1346 
1347 //*************************************************************************************************
1358 template< typename Type // Data type of the matrix
1359  , bool SO > // Storage order
1360 template< typename MT // Type of the right-hand side dense matrix
1361  , bool SO2 > // Storage order of the right-hand side dense matrix
1364 {
1365  using blaze::schurAssign;
1366 
1367  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1368  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1369  }
1370 
1371  if( (~rhs).canAlias( this ) ) {
1372  CompressedMatrix tmp( *this % (~rhs) );
1373  swap( tmp );
1374  }
1375  else {
1376  CompositeType_<MT> tmp( ~rhs );
1377  schurAssign( *this, tmp );
1378  }
1379 
1380  return *this;
1381 }
1382 //*************************************************************************************************
1383 
1384 
1385 //*************************************************************************************************
1396 template< typename Type // Data type of the matrix
1397  , bool SO > // Storage order
1398 template< typename MT // Type of the right-hand side sparse matrix
1399  , bool SO2 > // Storage order of the right-hand side sparse matrix
1402 {
1403  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1404  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1405  }
1406 
1407  CompressedMatrix tmp( *this % (~rhs) );
1408  swap( tmp );
1409 
1410  return *this;
1411 }
1412 //*************************************************************************************************
1413 
1414 
1415 
1416 
1417 //=================================================================================================
1418 //
1419 // UTILITY FUNCTIONS
1420 //
1421 //=================================================================================================
1422 
1423 //*************************************************************************************************
1428 template< typename Type // Data type of the matrix
1429  , bool SO > // Storage order
1430 inline size_t CompressedMatrix<Type,SO>::rows() const noexcept
1431 {
1432  return m_;
1433 }
1434 //*************************************************************************************************
1435 
1436 
1437 //*************************************************************************************************
1442 template< typename Type // Data type of the matrix
1443  , bool SO > // Storage order
1444 inline size_t CompressedMatrix<Type,SO>::columns() const noexcept
1445 {
1446  return n_;
1447 }
1448 //*************************************************************************************************
1449 
1450 
1451 //*************************************************************************************************
1456 template< typename Type // Data type of the matrix
1457  , bool SO > // Storage order
1458 inline size_t CompressedMatrix<Type,SO>::capacity() const noexcept
1459 {
1460  if( begin_ != nullptr )
1461  return end_[m_] - begin_[0UL];
1462  else return 0UL;
1463 }
1464 //*************************************************************************************************
1465 
1466 
1467 //*************************************************************************************************
1478 template< typename Type // Data type of the matrix
1479  , bool SO > // Storage order
1480 inline size_t CompressedMatrix<Type,SO>::capacity( size_t i ) const noexcept
1481 {
1482  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1483  return begin_[i+1UL] - begin_[i];
1484 }
1485 //*************************************************************************************************
1486 
1487 
1488 //*************************************************************************************************
1493 template< typename Type // Data type of the matrix
1494  , bool SO > // Storage order
1496 {
1497  size_t nonzeros( 0UL );
1498 
1499  for( size_t i=0UL; i<m_; ++i )
1500  nonzeros += nonZeros( i );
1501 
1502  return nonzeros;
1503 }
1504 //*************************************************************************************************
1505 
1506 
1507 //*************************************************************************************************
1518 template< typename Type // Data type of the matrix
1519  , bool SO > // Storage order
1520 inline size_t CompressedMatrix<Type,SO>::nonZeros( size_t i ) const
1521 {
1522  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1523  return end_[i] - begin_[i];
1524 }
1525 //*************************************************************************************************
1526 
1527 
1528 //*************************************************************************************************
1533 template< typename Type // Data type of the matrix
1534  , bool SO > // Storage order
1536 {
1537  for( size_t i=0UL; i<m_; ++i )
1538  end_[i] = begin_[i];
1539 }
1540 //*************************************************************************************************
1541 
1542 
1543 //*************************************************************************************************
1554 template< typename Type // Data type of the matrix
1555  , bool SO > // Storage order
1556 inline void CompressedMatrix<Type,SO>::reset( size_t i )
1557 {
1558  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1559  end_[i] = begin_[i];
1560 }
1561 //*************************************************************************************************
1562 
1563 
1564 //*************************************************************************************************
1571 template< typename Type // Data type of the matrix
1572  , bool SO > // Storage order
1574 {
1575  if( end_ != nullptr )
1576  end_[0UL] = end_[m_];
1577  m_ = 0UL;
1578  n_ = 0UL;
1579 }
1580 //*************************************************************************************************
1581 
1582 
1583 //*************************************************************************************************
1598 template< typename Type // Data type of the matrix
1599  , bool SO > // Storage order
1600 void CompressedMatrix<Type,SO>::resize( size_t m, size_t n, bool preserve )
1601 {
1602  using std::swap;
1603 
1604  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1605  BLAZE_INTERNAL_ASSERT( begin_ == nullptr || size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1606 
1607  if( m == m_ && n == n_ ) return;
1608 
1609  if( begin_ == nullptr )
1610  {
1611  begin_ = new Iterator[2UL*m+2UL];
1612  end_ = begin_+m+1UL;
1613 
1614  for( size_t i=0UL; i<2UL*m+2UL; ++i ) {
1615  begin_[i] = nullptr;
1616  }
1617 
1618  capacity_ = m;
1619  }
1620  else if( m > capacity_ )
1621  {
1622  Iterator* newBegin( new Iterator[2UL*m+2UL] );
1623  Iterator* newEnd ( newBegin+m+1UL );
1624 
1625  newBegin[0UL] = begin_[0UL];
1626 
1627  if( preserve ) {
1628  for( size_t i=0UL; i<m_; ++i ) {
1629  newEnd [i] = end_ [i];
1630  newBegin[i+1UL] = begin_[i+1UL];
1631  }
1632  for( size_t i=m_; i<m; ++i ) {
1633  newBegin[i+1UL] = newEnd[i] = begin_[m_];
1634  }
1635  }
1636  else {
1637  for( size_t i=0UL; i<m; ++i ) {
1638  newBegin[i+1UL] = newEnd[i] = begin_[0UL];
1639  }
1640  }
1641 
1642  newEnd[m] = end_[m_];
1643 
1644  swap( newBegin, begin_ );
1645  delete[] newBegin;
1646  end_ = newEnd;
1647  capacity_ = m;
1648  }
1649  else if( m > m_ )
1650  {
1651  end_[m] = end_[m_];
1652 
1653  if( !preserve ) {
1654  for( size_t i=0UL; i<m_; ++i )
1655  end_[i] = begin_[i];
1656  }
1657 
1658  for( size_t i=m_; i<m; ++i ) {
1659  begin_[i+1UL] = end_[i] = begin_[m_];
1660  }
1661  }
1662  else
1663  {
1664  if( preserve ) {
1665  for( size_t i=0UL; i<m; ++i )
1666  end_[i] = lowerBound( i, n );
1667  }
1668  else {
1669  for( size_t i=0UL; i<m; ++i )
1670  end_[i] = begin_[i];
1671  }
1672 
1673  end_[m] = end_[m_];
1674  }
1675 
1676  m_ = m;
1677  n_ = n;
1678 
1679  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1680  BLAZE_INTERNAL_ASSERT( size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1681 }
1682 //*************************************************************************************************
1683 
1684 
1685 //*************************************************************************************************
1695 template< typename Type // Data type of the matrix
1696  , bool SO > // Storage order
1697 inline void CompressedMatrix<Type,SO>::reserve( size_t nonzeros )
1698 {
1699  if( nonzeros > capacity() )
1700  reserveElements( nonzeros );
1701 }
1702 //*************************************************************************************************
1703 
1704 
1705 //*************************************************************************************************
1719 template< typename Type // Data type of the matrix
1720  , bool SO > // Storage order
1721 void CompressedMatrix<Type,SO>::reserve( size_t i, size_t nonzeros )
1722 {
1723  using std::swap;
1724 
1725  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1726 
1727  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1728  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1729 
1730  const size_t current( capacity(i) );
1731 
1732  if( current >= nonzeros ) return;
1733 
1734  const ptrdiff_t additional( nonzeros - current );
1735 
1736  if( end_[m_] - begin_[m_] < additional )
1737  {
1738  const size_t newCapacity( begin_[m_] - begin_[0UL] + additional );
1739  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
1740 
1741  Iterator* newBegin( new Iterator[2UL*m_+2UL] );
1742  Iterator* newEnd ( newBegin+m_+1UL );
1743 
1744  newBegin[0UL] = allocate<Element>( newCapacity );
1745  newEnd [m_ ] = newBegin[0UL]+newCapacity;
1746 
1747  for( size_t k=0UL; k<i; ++k ) {
1748  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
1749  newBegin[k+1UL] = newBegin[k] + capacity(k);
1750  }
1751  newEnd [i ] = castDown( transfer( begin_[i], end_[i], castUp( newBegin[i] ) ) );
1752  newBegin[i+1UL] = newBegin[i] + nonzeros;
1753  for( size_t k=i+1UL; k<m_; ++k ) {
1754  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
1755  newBegin[k+1UL] = newBegin[k] + capacity(k);
1756  }
1757 
1758  BLAZE_INTERNAL_ASSERT( newBegin[m_] == newEnd[m_], "Invalid pointer calculations" );
1759 
1760  swap( newBegin, begin_ );
1761  deallocate( newBegin[0UL] );
1762  delete[] newBegin;
1763  end_ = newEnd;
1764  capacity_ = m_;
1765  }
1766  else
1767  {
1768  begin_[m_] += additional;
1769  for( size_t j=m_-1UL; j>i; --j ) {
1770  begin_[j] = castDown( std::move_backward( begin_[j], end_[j], castUp( end_[j]+additional ) ) );
1771  end_ [j] += additional;
1772  }
1773  }
1774 
1775  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1776  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1777 }
1778 //*************************************************************************************************
1779 
1780 
1781 //*************************************************************************************************
1791 template< typename Type // Data type of the matrix
1792  , bool SO > // Storage order
1794 {
1795  for( size_t i=0UL; i<m_; ++i )
1796  trim( i );
1797 }
1798 //*************************************************************************************************
1799 
1800 
1801 //*************************************************************************************************
1812 template< typename Type // Data type of the matrix
1813  , bool SO > // Storage order
1814 inline void CompressedMatrix<Type,SO>::trim( size_t i )
1815 {
1816  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1817 
1818  if( i < ( m_ - 1UL ) )
1819  end_[i+1] = castDown( std::move( begin_[i+1], end_[i+1], castUp( end_[i] ) ) );
1820  begin_[i+1] = end_[i];
1821 }
1822 //*************************************************************************************************
1823 
1824 
1825 //*************************************************************************************************
1834 template< typename Type // Data type of the matrix
1835  , bool SO > // Storage order
1837 {
1838  if( nonZeros() < capacity() ) {
1839  CompressedMatrix( *this ).swap( *this );
1840  }
1841 }
1842 //*************************************************************************************************
1843 
1844 
1845 //*************************************************************************************************
1851 template< typename Type // Data type of the matrix
1852  , bool SO > // Storage order
1854 {
1855  using std::swap;
1856 
1857  swap( m_, sm.m_ );
1858  swap( n_, sm.n_ );
1859  swap( capacity_, sm.capacity_ );
1860  swap( begin_, sm.begin_ );
1861  swap( end_ , sm.end_ );
1862 }
1863 //*************************************************************************************************
1864 
1865 
1866 //*************************************************************************************************
1874 template< typename Type // Data type of the matrix
1875  , bool SO > // Storage order
1876 inline size_t CompressedMatrix<Type,SO>::extendCapacity() const noexcept
1877 {
1878  size_t nonzeros( 2UL*capacity()+1UL );
1879  nonzeros = blaze::max( nonzeros, 7UL );
1880 
1881  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
1882 
1883  return nonzeros;
1884 }
1885 //*************************************************************************************************
1886 
1887 
1888 //*************************************************************************************************
1894 template< typename Type // Data type of the matrix
1895  , bool SO > // Storage order
1897 {
1898  using std::swap;
1899 
1900  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1901  Iterator* newEnd = newBegin+capacity_+1UL;
1902 
1903  newBegin[0UL] = allocate<Element>( nonzeros );
1904 
1905  for( size_t k=0UL; k<m_; ++k ) {
1906  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid row pointers" );
1907  newEnd [k] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
1908  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
1909  }
1910 
1911  newEnd[m_] = newBegin[0UL]+nonzeros;
1912 
1913  swap( newBegin, begin_ );
1914  end_ = newEnd;
1915 
1916  if( newBegin != nullptr ) {
1917  deallocate( newBegin[0UL] );
1918  delete[] newBegin;
1919  }
1920 }
1921 //*************************************************************************************************
1922 
1923 
1924 //*************************************************************************************************
1932 template< typename Type // Data type of the matrix
1933  , bool SO > // Storage order
1936 {
1937  return static_cast<Iterator>( it );
1938 }
1939 //*************************************************************************************************
1940 
1941 
1942 //*************************************************************************************************
1950 template< typename Type // Data type of the matrix
1951  , bool SO > // Storage order
1954 {
1955  return static_cast<IteratorBase>( it );
1956 }
1957 //*************************************************************************************************
1958 
1959 
1960 
1961 
1962 //=================================================================================================
1963 //
1964 // INSERTION FUNCTIONS
1965 //
1966 //=================================================================================================
1967 
1968 //*************************************************************************************************
1980 template< typename Type // Data type of the matrix
1981  , bool SO > // Storage order
1983  CompressedMatrix<Type,SO>::set( size_t i, size_t j, const Type& value )
1984 {
1985  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1986  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1987 
1988  const Iterator pos( lowerBound( i, j ) );
1989 
1990  if( pos != end_[i] && pos->index_ == j ) {
1991  pos->value() = value;
1992  return pos;
1993  }
1994  else return insert( pos, i, j, value );
1995 }
1996 //*************************************************************************************************
1997 
1998 
1999 //*************************************************************************************************
2012 template< typename Type // Data type of the matrix
2013  , bool SO > // Storage order
2015  CompressedMatrix<Type,SO>::insert( size_t i, size_t j, const Type& value )
2016 {
2017  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2018  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2019 
2020  const Iterator pos( lowerBound( i, j ) );
2021 
2022  if( pos != end_[i] && pos->index_ == j ) {
2023  BLAZE_THROW_INVALID_ARGUMENT( "Bad access index" );
2024  }
2025 
2026  return insert( pos, i, j, value );
2027 }
2028 //*************************************************************************************************
2029 
2030 
2031 //*************************************************************************************************
2041 template< typename Type // Data type of the matrix
2042  , bool SO > // Storage order
2044  CompressedMatrix<Type,SO>::insert( Iterator pos, size_t i, size_t j, const Type& value )
2045 {
2046  using std::swap;
2047 
2048  if( begin_[i+1UL] - end_[i] != 0 ) {
2049  std::move_backward( pos, end_[i], castUp( end_[i]+1UL ) );
2050  pos->value_ = value;
2051  pos->index_ = j;
2052  ++end_[i];
2053 
2054  return pos;
2055  }
2056  else if( end_[m_] - begin_[m_] != 0 ) {
2057  std::move_backward( pos, end_[m_-1UL], castUp( end_[m_-1UL]+1UL ) );
2058 
2059  pos->value_ = value;
2060  pos->index_ = j;
2061 
2062  for( size_t k=i+1UL; k<m_+1UL; ++k ) {
2063  ++begin_[k];
2064  ++end_[k-1UL];
2065  }
2066 
2067  return pos;
2068  }
2069  else {
2070  size_t newCapacity( extendCapacity() );
2071 
2072  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
2073  Iterator* newEnd = newBegin+capacity_+1UL;
2074 
2075  newBegin[0UL] = allocate<Element>( newCapacity );
2076 
2077  for( size_t k=0UL; k<i; ++k ) {
2078  const size_t nonzeros( end_[k] - begin_[k] );
2079  const size_t total( begin_[k+1UL] - begin_[k] );
2080  newEnd [k] = newBegin[k] + nonzeros;
2081  newBegin[k+1UL] = newBegin[k] + total;
2082  }
2083  newEnd [i] = newBegin[i] + ( end_[i] - begin_[i] ) + 1;
2084  newBegin[i+1UL] = newBegin[i] + ( begin_[i+1] - begin_[i] ) + 1;
2085  for( size_t k=i+1UL; k<m_; ++k ) {
2086  const size_t nonzeros( end_[k] - begin_[k] );
2087  const size_t total( begin_[k+1UL] - begin_[k] );
2088  newEnd [k] = newBegin[k] + nonzeros;
2089  newBegin[k+1UL] = newBegin[k] + total;
2090  }
2091 
2092  newEnd[m_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
2093 
2094  Iterator tmp = castDown( std::move( begin_[0UL], pos, castUp( newBegin[0UL] ) ) );
2095  tmp->value_ = value;
2096  tmp->index_ = j;
2097  std::move( pos, end_[m_-1UL], castUp( tmp+1UL ) );
2098 
2099  swap( newBegin, begin_ );
2100  end_ = newEnd;
2101  deallocate( newBegin[0UL] );
2102  delete[] newBegin;
2103 
2104  return tmp;
2105  }
2106 }
2107 //*************************************************************************************************
2108 
2109 
2110 //*************************************************************************************************
2163 template< typename Type // Data type of the matrix
2164  , bool SO > // Storage order
2165 inline void CompressedMatrix<Type,SO>::append( size_t i, size_t j, const Type& value, bool check )
2166 {
2167  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2168  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
2169  BLAZE_USER_ASSERT( end_[i] < end_[m_], "Not enough reserved capacity left" );
2170  BLAZE_USER_ASSERT( begin_[i] == end_[i] || j > ( end_[i]-1UL )->index_, "Index is not strictly increasing" );
2171 
2172  end_[i]->value_ = value;
2173 
2174  if( !check || !isDefault<strict>( end_[i]->value_ ) ) {
2175  end_[i]->index_ = j;
2176  ++end_[i];
2177  }
2178 }
2179 //*************************************************************************************************
2180 
2181 
2182 //*************************************************************************************************
2195 template< typename Type // Data type of the matrix
2196  , bool SO > // Storage order
2198 {
2199  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2200 
2201  begin_[i+1UL] = end_[i];
2202  if( i != m_-1UL )
2203  end_[i+1UL] = end_[i];
2204 }
2205 //*************************************************************************************************
2206 
2207 
2208 
2209 
2210 //=================================================================================================
2211 //
2212 // ERASE FUNCTIONS
2213 //
2214 //=================================================================================================
2215 
2216 //*************************************************************************************************
2225 template< typename Type // Data type of the matrix
2226  , bool SO > // Storage order
2227 inline void CompressedMatrix<Type,SO>::erase( size_t i, size_t j )
2228 {
2229  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2230  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2231 
2232  const Iterator pos( find( i, j ) );
2233  if( pos != end_[i] )
2234  end_[i] = castDown( std::move( pos+1, end_[i], castUp( pos ) ) );
2235 }
2236 //*************************************************************************************************
2237 
2238 
2239 //*************************************************************************************************
2250 template< typename Type // Data type of the matrix
2251  , bool SO > // Storage order
2254 {
2255  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2256  BLAZE_USER_ASSERT( pos >= begin_[i] && pos <= end_[i], "Invalid compressed matrix iterator" );
2257 
2258  if( pos != end_[i] )
2259  end_[i] = castDown( std::move( pos+1, end_[i], castUp( pos ) ) );
2260 
2261  return pos;
2262 }
2263 //*************************************************************************************************
2264 
2265 
2266 //*************************************************************************************************
2278 template< typename Type // Data type of the matrix
2279  , bool SO > // Storage order
2282 {
2283  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2284  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
2285  BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i], "Invalid compressed matrix iterator" );
2286  BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i], "Invalid compressed matrix iterator" );
2287 
2288  if( first != last )
2289  end_[i] = castDown( std::move( last, end_[i], castUp( first ) ) );
2290 
2291  return first;
2292 }
2293 //*************************************************************************************************
2294 
2295 
2296 //*************************************************************************************************
2317 template< typename Type // Data type of the matrix
2318  , bool SO > // Storage order
2319 template< typename Pred > // Type of the unary predicate
2320 inline void CompressedMatrix<Type,SO>::erase( Pred predicate )
2321 {
2322  for( size_t i=0UL; i<m_; ++i ) {
2323  end_[i] = castDown( std::remove_if( castUp( begin_[i] ), castUp( end_[i] ),
2324  [predicate=predicate]( const ElementBase& element) {
2325  return predicate( element.value() );
2326  } ) );
2327  }
2328 }
2329 //*************************************************************************************************
2330 
2331 
2332 //*************************************************************************************************
2359 template< typename Type // Data type of the matrix
2360  , bool SO > // Storage order
2361 template< typename Pred > // Type of the unary predicate
2362 inline void CompressedMatrix<Type,SO>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
2363 {
2364  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2365  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
2366  BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i], "Invalid compressed matrix iterator" );
2367  BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i], "Invalid compressed matrix iterator" );
2368 
2369  const auto pos = std::remove_if( castUp( first ), castUp( last ),
2370  [predicate=predicate]( const ElementBase& element ) {
2371  return predicate( element.value() );
2372  } );
2373 
2374  end_[i] = castDown( std::move( last, end_[i], pos ) );
2375 }
2376 //*************************************************************************************************
2377 
2378 
2379 
2380 
2381 //=================================================================================================
2382 //
2383 // LOOKUP FUNCTIONS
2384 //
2385 //=================================================================================================
2386 
2387 //*************************************************************************************************
2402 template< typename Type // Data type of the matrix
2403  , bool SO > // Storage order
2405  CompressedMatrix<Type,SO>::find( size_t i, size_t j )
2406 {
2407  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
2408 }
2409 //*************************************************************************************************
2410 
2411 
2412 //*************************************************************************************************
2427 template< typename Type // Data type of the matrix
2428  , bool SO > // Storage order
2430  CompressedMatrix<Type,SO>::find( size_t i, size_t j ) const
2431 {
2432  const ConstIterator pos( lowerBound( i, j ) );
2433  if( pos != end_[i] && pos->index_ == j )
2434  return pos;
2435  else return end_[i];
2436 }
2437 //*************************************************************************************************
2438 
2439 
2440 //*************************************************************************************************
2455 template< typename Type // Data type of the matrix
2456  , bool SO > // Storage order
2459 {
2460  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
2461 }
2462 //*************************************************************************************************
2463 
2464 
2465 //*************************************************************************************************
2480 template< typename Type // Data type of the matrix
2481  , bool SO > // Storage order
2483  CompressedMatrix<Type,SO>::lowerBound( size_t i, size_t j ) const
2484 {
2485  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2486  return std::lower_bound( begin_[i], end_[i], j,
2487  []( const Element& element, size_t index )
2488  {
2489  return element.index() < index;
2490  } );
2491 }
2492 //*************************************************************************************************
2493 
2494 
2495 //*************************************************************************************************
2510 template< typename Type // Data type of the matrix
2511  , bool SO > // Storage order
2514 {
2515  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
2516 }
2517 //*************************************************************************************************
2518 
2519 
2520 //*************************************************************************************************
2535 template< typename Type // Data type of the matrix
2536  , bool SO > // Storage order
2538  CompressedMatrix<Type,SO>::upperBound( size_t i, size_t j ) const
2539 {
2540  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2541  return std::upper_bound( begin_[i], end_[i], j,
2542  []( size_t index, const Element& element )
2543  {
2544  return index < element.index();
2545  } );
2546 }
2547 //*************************************************************************************************
2548 
2549 
2550 
2551 
2552 //=================================================================================================
2553 //
2554 // NUMERIC FUNCTIONS
2555 //
2556 //=================================================================================================
2557 
2558 //*************************************************************************************************
2563 template< typename Type // Data type of the matrix
2564  , bool SO > // Storage order
2566 {
2567  CompressedMatrix tmp( trans( *this ) );
2568  swap( tmp );
2569  return *this;
2570 }
2571 //*************************************************************************************************
2572 
2573 
2574 //*************************************************************************************************
2579 template< typename Type // Data type of the matrix
2580  , bool SO > // Storage order
2582 {
2583  CompressedMatrix tmp( ctrans( *this ) );
2584  swap( tmp );
2585  return *this;
2586 }
2587 //*************************************************************************************************
2588 
2589 
2590 //*************************************************************************************************
2607 template< typename Type // Data type of the matrix
2608  , bool SO > // Storage order
2609 template< typename Other > // Data type of the scalar value
2611 {
2612  for( size_t i=0UL; i<m_; ++i )
2613  for( Iterator element=begin_[i]; element!=end_[i]; ++element )
2614  element->value_ *= scalar;
2615 
2616  return *this;
2617 }
2618 //*************************************************************************************************
2619 
2620 
2621 
2622 
2623 //=================================================================================================
2624 //
2625 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2626 //
2627 //=================================================================================================
2628 
2629 //*************************************************************************************************
2639 template< typename Type // Data type of the matrix
2640  , bool SO > // Storage order
2641 template< typename Other > // Data type of the foreign expression
2642 inline bool CompressedMatrix<Type,SO>::canAlias( const Other* alias ) const noexcept
2643 {
2644  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2645 }
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>::isAliased( 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 inline bool CompressedMatrix<Type,SO>::canSMPAssign() const noexcept
2682 {
2683  return false;
2684 }
2685 //*************************************************************************************************
2686 
2687 
2688 //*************************************************************************************************
2699 template< typename Type // Data type of the matrix
2700  , bool SO > // Storage order
2701 template< typename MT // Type of the right-hand side dense matrix
2702  , bool SO2 > // Storage order of the right-hand side dense matrix
2704 {
2705  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2706  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2707 
2708  if( m_ == 0UL || n_ == 0UL )
2709  return;
2710 
2711  size_t nonzeros( 0UL );
2712 
2713  for( size_t i=1UL; i<=m_; ++i )
2714  begin_[i] = end_[i] = end_[m_];
2715 
2716  for( size_t i=0UL; i<m_; ++i )
2717  {
2718  begin_[i] = end_[i] = begin_[0UL]+nonzeros;
2719 
2720  const size_t jbegin( ( IsUpper<MT>::value )
2721  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2722  :( 0UL ) );
2723  const size_t jend ( ( IsLower<MT>::value )
2724  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2725  :( n_ ) );
2726 
2727  for( size_t j=jbegin; j<jend; ++j )
2728  {
2729  if( nonzeros == capacity() ) {
2731  for( size_t k=i+1UL; k<=m_; ++k )
2732  begin_[k] = end_[k] = end_[m_];
2733  }
2734 
2735  end_[i]->value_ = (~rhs)(i,j);
2736 
2737  if( !isDefault<strict>( end_[i]->value_ ) ) {
2738  end_[i]->index_ = j;
2739  ++end_[i];
2740  ++nonzeros;
2741  }
2742  }
2743  }
2744 
2745  begin_[m_] = begin_[0UL]+nonzeros;
2746 }
2747 //*************************************************************************************************
2748 
2749 
2750 //*************************************************************************************************
2761 template< typename Type // Data type of the matrix
2762  , bool SO > // Storage order
2763 template< typename MT > // Type of the right-hand side compressed matrix
2765 {
2766  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2767  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2768  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2769  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
2770 
2771  if( m_ == 0UL || begin_[0] == nullptr )
2772  return;
2773 
2774  for( size_t i=0UL; i<m_; ++i ) {
2775  end_[i] = castDown( std::copy( (~rhs).begin(i), (~rhs).end(i), castUp( begin_[i] ) ) );
2776  begin_[i+1UL] = end_[i];
2777  }
2778 }
2779 //*************************************************************************************************
2780 
2781 
2782 //*************************************************************************************************
2793 template< typename Type // Data type of the matrix
2794  , bool SO > // Storage order
2795 template< typename MT > // Type of the right-hand side compressed matrix
2797 {
2799 
2800  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2801  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2802  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2803  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
2804 
2805  using RhsIterator = ConstIterator_<MT>;
2806 
2807  // Counting the number of elements per row
2808  std::vector<size_t> rowLengths( m_, 0UL );
2809  for( size_t j=0UL; j<n_; ++j ) {
2810  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2811  ++rowLengths[element->index()];
2812  }
2813 
2814  // Resizing the compressed matrix
2815  for( size_t i=0UL; i<m_; ++i ) {
2816  begin_[i+1UL] = end_[i+1UL] = begin_[i] + rowLengths[i];
2817  }
2818 
2819  // Appending the elements to the rows of the compressed matrix
2820  for( size_t j=0UL; j<n_; ++j ) {
2821  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2822  append( element->index(), j, element->value() );
2823  }
2824 }
2825 //*************************************************************************************************
2826 
2827 
2828 //*************************************************************************************************
2839 template< typename Type // Data type of the matrix
2840  , bool SO > // Storage order
2841 template< typename MT // Type of the right-hand side dense matrix
2842  , bool SO2 > // Storage order of the right-hand side dense matrix
2844 {
2845  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2846  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2847 
2848  CompressedMatrix tmp( serial( *this + (~rhs) ) );
2849  swap( tmp );
2850 }
2851 //*************************************************************************************************
2852 
2853 
2854 //*************************************************************************************************
2865 template< typename Type // Data type of the matrix
2866  , bool SO > // Storage order
2867 template< typename MT // Type of the right-hand side compressed matrix
2868  , bool SO2 > // Storage order of the right-hand side compressed matrix
2870 {
2871  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2872  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2873 
2874  CompressedMatrix tmp( serial( *this + (~rhs) ) );
2875  swap( tmp );
2876 }
2877 //*************************************************************************************************
2878 
2879 
2880 //*************************************************************************************************
2891 template< typename Type // Data type of the matrix
2892  , bool SO > // Storage order
2893 template< typename MT // Type of the right-hand side dense matrix
2894  , bool SO2 > // Storage order of the right-hand side dense matrix
2896 {
2897  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2898  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2899 
2900  CompressedMatrix tmp( serial( *this - (~rhs) ) );
2901  swap( tmp );
2902 }
2903 //*************************************************************************************************
2904 
2905 
2906 //*************************************************************************************************
2917 template< typename Type // Data type of the matrix
2918  , bool SO > // Storage order
2919 template< typename MT // Type of the right-hand side compressed matrix
2920  , bool SO2 > // Storage order of the right-hand compressed matrix
2922 {
2923  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2924  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2925 
2926  CompressedMatrix tmp( serial( *this - (~rhs) ) );
2927  swap( tmp );
2928 }
2929 //*************************************************************************************************
2930 
2931 
2932 //*************************************************************************************************
2943 template< typename Type // Data type of the matrix
2944  , bool SO > // Storage order
2945 template< typename MT // Type of the right-hand side dense matrix
2946  , bool SO2 > // Storage order of the right-hand side dense matrix
2948 {
2949  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2950  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2951 
2953 
2954  for( size_t i=0UL; i<m_; ++i ) {
2955  const Iterator last( end(i) );
2956  for( Iterator element=begin(i); element!=last; ++element )
2957  element->value_ *= (~rhs)(i,element->index_);
2958  }
2959 }
2960 //*************************************************************************************************
2961 
2962 
2963 
2964 
2965 
2966 
2967 
2968 
2969 //=================================================================================================
2970 //
2971 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2972 //
2973 //=================================================================================================
2974 
2975 //*************************************************************************************************
2983 template< typename Type > // Data type of the matrix
2984 class CompressedMatrix<Type,true>
2985  : public SparseMatrix< CompressedMatrix<Type,true>, true >
2986 {
2987  private:
2988  //**Type definitions****************************************************************************
2990  using IteratorBase = ElementBase*;
2991  //**********************************************************************************************
2992 
2993  //**Private class Element***********************************************************************
3000  struct Element
3001  : public ElementBase
3002  {
3003  //**Constructors*****************************************************************************
3004  explicit Element() = default;
3005  Element( const Element& rhs ) = default;
3006  Element( Element&& rhs ) = default;
3007  //*******************************************************************************************
3008 
3009  //**Assignment operators*********************************************************************
3010  inline Element& operator=( const Element& rhs )
3011  {
3012  this->value_ = rhs.value_;
3013  return *this;
3014  }
3015 
3016  inline Element& operator=( Element&& rhs )
3017  {
3018  this->value_ = std::move( rhs.value_ );
3019  return *this;
3020  }
3021 
3022  template< typename Other >
3023  inline EnableIf_< IsSparseElement<Other>, Element& >
3024  operator=( const Other& rhs )
3025  {
3026  this->value_ = rhs.value();
3027  return *this;
3028  }
3029 
3030  template< typename Other >
3032  , IsRValueReference<Other&&> >, Element& >
3033  operator=( Other&& rhs )
3034  {
3035  this->value_ = std::move( rhs.value() );
3036  return *this;
3037  }
3038 
3039  template< typename Other >
3040  inline EnableIf_< Not< IsSparseElement<Other> >, Element& >
3041  operator=( const Other& v )
3042  {
3043  this->value_ = v;
3044  return *this;
3045  }
3046 
3047  template< typename Other >
3049  , IsRValueReference<Other&&> >, Element& >
3050  operator=( Other&& v )
3051  {
3052  this->value_ = std::move( v );
3053  return *this;
3054  }
3055  //*******************************************************************************************
3056 
3057  //**Friend declarations**********************************************************************
3058  friend class CompressedMatrix;
3059  //*******************************************************************************************
3060  };
3062  //**********************************************************************************************
3063 
3064  //**Private class Uninitialized*****************************************************************
3068  struct Uninitialized {};
3070  //**********************************************************************************************
3071 
3072  public:
3073  //**Type definitions****************************************************************************
3076  using ResultType = This;
3079  using ElementType = Type;
3080  using ReturnType = const Type&;
3081  using CompositeType = const This&;
3083  using ConstReference = const Type&;
3084  using Iterator = Element*;
3085  using ConstIterator = const Element*;
3086  //**********************************************************************************************
3087 
3088  //**Rebind struct definition********************************************************************
3091  template< typename NewType > // Data type of the other matrix
3092  struct Rebind {
3094  };
3095  //**********************************************************************************************
3096 
3097  //**Resize struct definition********************************************************************
3100  template< size_t NewM // Number of rows of the other matrix
3101  , size_t NewN > // Number of columns of the other matrix
3102  struct Resize {
3104  };
3105  //**********************************************************************************************
3106 
3107  //**Compilation flags***************************************************************************
3109 
3112  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
3113  //**********************************************************************************************
3114 
3115  //**Constructors********************************************************************************
3118  explicit inline CompressedMatrix();
3119  explicit inline CompressedMatrix( size_t m, size_t n );
3120  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
3121  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
3122  explicit inline CompressedMatrix( initializer_list< initializer_list<Type> > list );
3123 
3124  inline CompressedMatrix( const CompressedMatrix& sm );
3125  inline CompressedMatrix( CompressedMatrix&& sm ) noexcept;
3126 
3127  template< typename MT, bool SO > inline CompressedMatrix( const DenseMatrix<MT,SO>& dm );
3128  template< typename MT, bool SO > inline CompressedMatrix( const SparseMatrix<MT,SO>& sm );
3130  //**********************************************************************************************
3131 
3132  //**Destructor**********************************************************************************
3135  inline ~CompressedMatrix();
3137  //**********************************************************************************************
3138 
3139  //**Data access functions***********************************************************************
3142  inline Reference operator()( size_t i, size_t j ) noexcept;
3143  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3144  inline Reference at( size_t i, size_t j );
3145  inline ConstReference at( size_t i, size_t j ) const;
3146  inline Iterator begin ( size_t j ) noexcept;
3147  inline ConstIterator begin ( size_t j ) const noexcept;
3148  inline ConstIterator cbegin( size_t j ) const noexcept;
3149  inline Iterator end ( size_t j ) noexcept;
3150  inline ConstIterator end ( size_t j ) const noexcept;
3151  inline ConstIterator cend ( size_t j ) const noexcept;
3153  //**********************************************************************************************
3154 
3155  //**Assignment operators************************************************************************
3158  inline CompressedMatrix& operator=( initializer_list< initializer_list<Type> > list );
3159  inline CompressedMatrix& operator=( const CompressedMatrix& rhs );
3160  inline CompressedMatrix& operator=( CompressedMatrix&& rhs ) noexcept;
3161 
3162  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO>& rhs );
3163  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO>& rhs );
3164  template< typename MT, bool SO > inline CompressedMatrix& operator+=( const Matrix<MT,SO>& rhs );
3165  template< typename MT, bool SO > inline CompressedMatrix& operator-=( const Matrix<MT,SO>& rhs );
3166  template< typename MT, bool SO > inline CompressedMatrix& operator%=( const DenseMatrix<MT,SO>& rhs );
3167  template< typename MT, bool SO > inline CompressedMatrix& operator%=( const SparseMatrix<MT,SO>& rhs );
3169  //**********************************************************************************************
3170 
3171  //**Utility functions***************************************************************************
3174  inline size_t rows() const noexcept;
3175  inline size_t columns() const noexcept;
3176  inline size_t capacity() const noexcept;
3177  inline size_t capacity( size_t j ) const noexcept;
3178  inline size_t nonZeros() const;
3179  inline size_t nonZeros( size_t j ) const;
3180  inline void reset();
3181  inline void reset( size_t j );
3182  inline void clear();
3183  void resize ( size_t m, size_t n, bool preserve=true );
3184  inline void reserve( size_t nonzeros );
3185  void reserve( size_t j, size_t nonzeros );
3186  inline void trim ();
3187  inline void trim ( size_t j );
3188  inline void shrinkToFit();
3189  inline void swap( CompressedMatrix& sm ) noexcept;
3191  //**********************************************************************************************
3192 
3193  //**Insertion functions*************************************************************************
3196  inline Iterator set ( size_t i, size_t j, const Type& value );
3197  inline Iterator insert ( size_t i, size_t j, const Type& value );
3198  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
3199  inline void finalize( size_t j );
3201  //**********************************************************************************************
3202 
3203  //**Erase functions*****************************************************************************
3206  inline void erase( size_t i, size_t j );
3207  inline Iterator erase( size_t j, Iterator pos );
3208  inline Iterator erase( size_t j, Iterator first, Iterator last );
3209 
3210  template< typename Pred >
3211  inline void erase( Pred predicate );
3212 
3213  template< typename Pred >
3214  inline void erase( size_t j, Iterator first, Iterator last, Pred predicate );
3216  //**********************************************************************************************
3217 
3218  //**Lookup functions****************************************************************************
3221  inline Iterator find ( size_t i, size_t j );
3222  inline ConstIterator find ( size_t i, size_t j ) const;
3223  inline Iterator lowerBound( size_t i, size_t j );
3224  inline ConstIterator lowerBound( size_t i, size_t j ) const;
3225  inline Iterator upperBound( size_t i, size_t j );
3226  inline ConstIterator upperBound( size_t i, size_t j ) const;
3228  //**********************************************************************************************
3229 
3230  //**Numeric functions***************************************************************************
3233  inline CompressedMatrix& transpose();
3234  inline CompressedMatrix& ctranspose();
3235 
3236  template< typename Other > inline CompressedMatrix& scale( const Other& scalar );
3238  //**********************************************************************************************
3239 
3240  //**Expression template evaluation functions****************************************************
3243  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3244  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3245 
3246  inline bool canSMPAssign() const noexcept;
3247 
3248  template< typename MT, bool SO > inline void assign ( const DenseMatrix<MT,SO>& rhs );
3249  template< typename MT > inline void assign ( const SparseMatrix<MT,true>& rhs );
3250  template< typename MT > inline void assign ( const SparseMatrix<MT,false>& rhs );
3251  template< typename MT, bool SO > inline void addAssign ( const DenseMatrix<MT,SO>& rhs );
3252  template< typename MT, bool SO > inline void addAssign ( const SparseMatrix<MT,SO>& rhs );
3253  template< typename MT, bool SO > inline void subAssign ( const DenseMatrix<MT,SO>& rhs );
3254  template< typename MT, bool SO > inline void subAssign ( const SparseMatrix<MT,SO>& rhs );
3255  template< typename MT, bool SO > inline void schurAssign( const DenseMatrix<MT,SO>& rhs );
3257  //**********************************************************************************************
3258 
3259  private:
3260  //**Constructors********************************************************************************
3263  explicit inline CompressedMatrix( size_t m, size_t n, Uninitialized );
3265  //**********************************************************************************************
3266 
3267  //**Utility functions***************************************************************************
3270  inline size_t extendCapacity() const noexcept;
3271  void reserveElements( size_t nonzeros );
3272 
3273  inline Iterator castDown( IteratorBase it ) const noexcept;
3274  inline IteratorBase castUp ( Iterator it ) const noexcept;
3276  //**********************************************************************************************
3277 
3278  //**Insertion functions*************************************************************************
3281  Iterator insert( Iterator pos, size_t i, size_t j, const Type& value );
3283  //**********************************************************************************************
3284 
3285  //**Member variables****************************************************************************
3288  size_t m_;
3289  size_t n_;
3290  size_t capacity_;
3293 
3294  static const Type zero_;
3295 
3296  //**********************************************************************************************
3297 
3298  //**Compile time checks*************************************************************************
3306  //**********************************************************************************************
3307 };
3309 //*************************************************************************************************
3310 
3311 
3312 
3313 
3314 //=================================================================================================
3315 //
3316 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
3317 //
3318 //=================================================================================================
3319 
3320 template< typename Type >
3322 
3323 
3324 
3325 
3326 //=================================================================================================
3327 //
3328 // CONSTRUCTORS
3329 //
3330 //=================================================================================================
3331 
3332 //*************************************************************************************************
3336 template< typename Type > // Data type of the matrix
3338  : m_ ( 0UL ) // The current number of rows of the compressed matrix
3339  , n_ ( 0UL ) // The current number of columns of the compressed matrix
3340  , capacity_( 0UL ) // The current capacity of the pointer array
3341  , begin_ ( nullptr ) // Pointers to the first non-zero element of each column
3342  , end_ ( nullptr ) // Pointers one past the last non-zero element of each column
3343 {}
3345 //*************************************************************************************************
3346 
3347 
3348 //*************************************************************************************************
3357 template< typename Type > // Data type of the matrix
3358 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n )
3359  : CompressedMatrix( m, n, Uninitialized() )
3360 {
3361  for( size_t j=1UL; j<2UL*n_+2UL; ++j )
3362  begin_[j] = nullptr;
3363 }
3365 //*************************************************************************************************
3366 
3367 
3368 //*************************************************************************************************
3378 template< typename Type > // Data type of the matrix
3379 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
3380  : CompressedMatrix( m, n, Uninitialized() )
3381 {
3382  begin_[0UL] = allocate<Element>( nonzeros );
3383  for( size_t j=1UL; j<(2UL*n_+1UL); ++j )
3384  begin_[j] = begin_[0UL];
3385  end_[n_] = begin_[0UL]+nonzeros;
3386 }
3388 //*************************************************************************************************
3389 
3390 
3391 //*************************************************************************************************
3402 template< typename Type > // Data type of the matrix
3403 CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
3404  : CompressedMatrix( m, n, Uninitialized() )
3405 {
3406  BLAZE_USER_ASSERT( nonzeros.size() == n, "Size of capacity vector and number of columns don't match" );
3407 
3408  size_t newCapacity( 0UL );
3409  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
3410  newCapacity += *it;
3411 
3412  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
3413  for( size_t j=0UL; j<n_; ++j ) {
3414  begin_[j+1UL] = end_[j+1UL] = begin_[j] + nonzeros[j];
3415  }
3416 }
3418 //*************************************************************************************************
3419 
3420 
3421 //*************************************************************************************************
3442 template< typename Type > // Data type of the matrix
3444  : CompressedMatrix( list.size(), determineColumns( list ), blaze::nonZeros( list ) )
3445 {
3446  for( size_t j=0UL; j<n_; ++j )
3447  {
3448  size_t i( 0UL );
3449 
3450  for( const auto& rowList : list )
3451  {
3452  if( rowList.size() <= j ) {
3453  ++i;
3454  continue;
3455  }
3456 
3457  auto pos( rowList.begin() );
3458  std::advance( pos, j );
3459  if( !isDefault<strict>( *pos ) )
3460  append( i, j, *pos );
3461  ++i;
3462  }
3463 
3464  finalize( j );
3465  }
3466 }
3468 //*************************************************************************************************
3469 
3470 
3471 //*************************************************************************************************
3477 template< typename Type > // Data type of the matrix
3479  : CompressedMatrix( sm.m_, sm.n_, Uninitialized() )
3480 {
3481  const size_t nonzeros( sm.nonZeros() );
3482 
3483  begin_[0UL] = allocate<Element>( nonzeros );
3484  for( size_t j=0UL; j<n_; ++j ) {
3485  end_[j] = castDown( std::copy( sm.begin(j), sm.end(j), castUp( begin_[j] ) ) );
3486  begin_[j+1UL] = end_[j];
3487  }
3488  end_[n_] = begin_[0UL]+nonzeros;
3489 }
3491 //*************************************************************************************************
3492 
3493 
3494 //*************************************************************************************************
3500 template< typename Type > // Data type of the matrix
3502  : m_ ( sm.m_ ) // The current number of rows of the compressed matrix
3503  , n_ ( sm.n_ ) // The current number of columns of the compressed matrix
3504  , capacity_( sm.capacity_ ) // The current capacity of the pointer array
3505  , begin_ ( sm.begin_ ) // Pointers to the first non-zero element of each column
3506  , end_ ( sm.end_ ) // Pointers one past the last non-zero element of each column
3507 {
3508  sm.m_ = 0UL;
3509  sm.n_ = 0UL;
3510  sm.capacity_ = 0UL;
3511  sm.begin_ = nullptr;
3512  sm.end_ = nullptr;
3513 }
3515 //*************************************************************************************************
3516 
3517 
3518 //*************************************************************************************************
3524 template< typename Type > // Data type of the matrix
3525 template< typename MT // Type of the foreign dense matrix
3526  , bool SO > // Storage order of the foreign dense matrix
3528  : CompressedMatrix( (~dm).rows(), (~dm).columns() )
3529 {
3530  using blaze::assign;
3531 
3532  assign( *this, ~dm );
3533 }
3535 //*************************************************************************************************
3536 
3537 
3538 //*************************************************************************************************
3544 template< typename Type > // Data type of the matrix
3545 template< typename MT // Type of the foreign compressed matrix
3546  , bool SO > // Storage order of the foreign compressed matrix
3548  : CompressedMatrix( (~sm).rows(), (~sm).columns(), (~sm).nonZeros() )
3549 {
3550  using blaze::assign;
3551 
3552  assign( *this, ~sm );
3553 }
3555 //*************************************************************************************************
3556 
3557 
3558 //*************************************************************************************************
3565 template< typename Type > // Data type of the matrix
3566 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, Uninitialized )
3567  : m_ ( m ) // The current number of rows of the compressed matrix
3568  , n_ ( n ) // The current number of columns of the compressed matrix
3569  , capacity_( n ) // The current capacity of the pointer array
3570  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
3571  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
3572 {
3573  begin_[0UL] = nullptr;
3574 }
3576 //*************************************************************************************************
3577 
3578 
3579 
3580 
3581 //=================================================================================================
3582 //
3583 // DESTRUCTOR
3584 //
3585 //=================================================================================================
3586 
3587 //*************************************************************************************************
3591 template< typename Type > // Data type of the matrix
3593 {
3594  if( begin_ != nullptr ) {
3595  deallocate( begin_[0UL] );
3596  delete[] begin_;
3597  }
3598 }
3600 //*************************************************************************************************
3601 
3602 
3603 
3604 
3605 //=================================================================================================
3606 //
3607 // DATA ACCESS FUNCTIONS
3608 //
3609 //=================================================================================================
3610 
3611 //*************************************************************************************************
3625 template< typename Type > // Data type of the matrix
3627  CompressedMatrix<Type,true>::operator()( size_t i, size_t j ) noexcept
3628 {
3629  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3630  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3631 
3632  return Reference( *this, i, j );
3633 }
3635 //*************************************************************************************************
3636 
3637 
3638 //*************************************************************************************************
3649 template< typename Type > // Data type of the matrix
3651  CompressedMatrix<Type,true>::operator()( size_t i, size_t j ) const noexcept
3652 {
3653  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3654  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3655 
3656  const ConstIterator pos( lowerBound( i, j ) );
3657 
3658  if( pos == end_[j] || pos->index_ != i )
3659  return zero_;
3660  else
3661  return pos->value_;
3662 }
3664 //*************************************************************************************************
3665 
3666 
3667 //*************************************************************************************************
3681 template< typename Type > // Data type of the matrix
3683  CompressedMatrix<Type,true>::at( size_t i, size_t j )
3684 {
3685  if( i >= m_ ) {
3686  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3687  }
3688  if( j >= n_ ) {
3689  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3690  }
3691  return (*this)(i,j);
3692 }
3694 //*************************************************************************************************
3695 
3696 
3697 //*************************************************************************************************
3709 template< typename Type > // Data type of the matrix
3711  CompressedMatrix<Type,true>::at( size_t i, size_t j ) const
3712 {
3713  if( i >= m_ ) {
3714  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3715  }
3716  if( j >= n_ ) {
3717  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3718  }
3719  return (*this)(i,j);
3720 }
3722 //*************************************************************************************************
3723 
3724 
3725 //*************************************************************************************************
3732 template< typename Type > // Data type of the matrix
3734  CompressedMatrix<Type,true>::begin( size_t j ) noexcept
3735 {
3736  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3737  return begin_[j];
3738 }
3740 //*************************************************************************************************
3741 
3742 
3743 //*************************************************************************************************
3750 template< typename Type > // Data type of the matrix
3752  CompressedMatrix<Type,true>::begin( size_t j ) const noexcept
3753 {
3754  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3755  return begin_[j];
3756 }
3758 //*************************************************************************************************
3759 
3760 
3761 //*************************************************************************************************
3768 template< typename Type > // Data type of the matrix
3770  CompressedMatrix<Type,true>::cbegin( size_t j ) const noexcept
3771 {
3772  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3773  return begin_[j];
3774 }
3776 //*************************************************************************************************
3777 
3778 
3779 //*************************************************************************************************
3786 template< typename Type > // Data type of the matrix
3788  CompressedMatrix<Type,true>::end( size_t j ) noexcept
3789 {
3790  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3791  return end_[j];
3792 }
3794 //*************************************************************************************************
3795 
3796 
3797 //*************************************************************************************************
3804 template< typename Type > // Data type of the matrix
3806  CompressedMatrix<Type,true>::end( size_t j ) const noexcept
3807 {
3808  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3809  return end_[j];
3810 }
3812 //*************************************************************************************************
3813 
3814 
3815 //*************************************************************************************************
3822 template< typename Type > // Data type of the matrix
3824  CompressedMatrix<Type,true>::cend( size_t j ) const noexcept
3825 {
3826  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3827  return end_[j];
3828 }
3830 //*************************************************************************************************
3831 
3832 
3833 
3834 
3835 //=================================================================================================
3836 //
3837 // ASSIGNMENT OPERATORS
3838 //
3839 //=================================================================================================
3840 
3841 //*************************************************************************************************
3863 template< typename Type > // Data type of the matrix
3866 {
3867  using blaze::nonZeros;
3868 
3869  resize( list.size(), determineColumns( list ), false );
3870  reserve( nonZeros( list ) );
3871 
3872  for( size_t j=0UL; j<n_; ++j )
3873  {
3874  size_t i( 0UL );
3875 
3876  for( const auto& rowList : list )
3877  {
3878  if( rowList.size() <= j ) {
3879  ++i;
3880  continue;
3881  }
3882 
3883  auto pos( rowList.begin() );
3884  std::advance( pos, j );
3885  if( !isDefault<strict>( *pos ) )
3886  append( i, j, *pos );
3887  ++i;
3888  }
3889 
3890  finalize( j );
3891  }
3892 
3893  return *this;
3894 }
3896 //*************************************************************************************************
3897 
3898 
3899 //*************************************************************************************************
3909 template< typename Type > // Data type of the matrix
3912 {
3913  using std::swap;
3914 
3915  if( &rhs == this ) return *this;
3916 
3917  const size_t nonzeros( rhs.nonZeros() );
3918 
3919  if( rhs.n_ > capacity_ || nonzeros > capacity() )
3920  {
3921  Iterator* newBegin( new Iterator[2UL*rhs.n_+2UL] );
3922  Iterator* newEnd ( newBegin+(rhs.n_+1UL) );
3923 
3924  newBegin[0UL] = allocate<Element>( nonzeros );
3925  for( size_t j=0UL; j<rhs.n_; ++j ) {
3926  newEnd[j] = castDown( std::copy( rhs.begin_[j], rhs.end_[j], castUp( newBegin[j] ) ) );
3927  newBegin[j+1UL] = newEnd[j];
3928  }
3929  newEnd[rhs.n_] = newBegin[0UL]+nonzeros;
3930 
3931  swap( begin_, newBegin );
3932  end_ = newEnd;
3933  capacity_ = rhs.n_;
3934 
3935  if( newBegin != nullptr ) {
3936  deallocate( newBegin[0UL] );
3937  delete[] newBegin;
3938  }
3939  }
3940  else {
3941  for( size_t j=0UL; j<rhs.n_; ++j ) {
3942  end_[j] = castDown( std::copy( rhs.begin_[j], rhs.end_[j], castUp( begin_[j] ) ) );
3943  begin_[j+1UL] = end_[j];
3944  }
3945  }
3946 
3947  m_ = rhs.m_;
3948  n_ = rhs.n_;
3949 
3950  return *this;
3951 }
3953 //*************************************************************************************************
3954 
3955 
3956 //*************************************************************************************************
3963 template< typename Type > // Data type of the matrix
3966 {
3967  if( begin_ != nullptr ) {
3968  deallocate( begin_[0UL] );
3969  delete[] begin_;
3970  }
3971 
3972  m_ = rhs.m_;
3973  n_ = rhs.n_;
3974  capacity_ = rhs.capacity_;
3975  begin_ = rhs.begin_;
3976  end_ = rhs.end_;
3977 
3978  rhs.m_ = 0UL;
3979  rhs.n_ = 0UL;
3980  rhs.capacity_ = 0UL;
3981  rhs.begin_ = nullptr;
3982  rhs.end_ = nullptr;
3983 
3984  return *this;
3985 }
3987 //*************************************************************************************************
3988 
3989 
3990 //*************************************************************************************************
4000 template< typename Type > // Data type of the matrix
4001 template< typename MT // Type of the right-hand side dense matrix
4002  , bool SO > // Storage order of the right-hand side dense matrix
4005 {
4006  using blaze::assign;
4007 
4008  if( (~rhs).canAlias( this ) ) {
4009  CompressedMatrix tmp( ~rhs );
4010  swap( tmp );
4011  }
4012  else {
4013  resize( (~rhs).rows(), (~rhs).columns(), false );
4014  assign( *this, ~rhs );
4015  }
4016 
4017  return *this;
4018 }
4020 //*************************************************************************************************
4021 
4022 
4023 //*************************************************************************************************
4033 template< typename Type > // Data type of the matrix
4034 template< typename MT // Type of the right-hand side compressed matrix
4035  , bool SO > // Storage order of the right-hand side compressed matrix
4038 {
4039  using blaze::assign;
4040 
4041  if( (~rhs).canAlias( this ) ||
4042  (~rhs).columns() > capacity_ ||
4043  (~rhs).nonZeros() > capacity() ) {
4044  CompressedMatrix tmp( ~rhs );
4045  swap( tmp );
4046  }
4047  else {
4048  resize( (~rhs).rows(), (~rhs).columns(), false );
4049  reset();
4050  assign( *this, ~rhs );
4051  }
4052 
4053  return *this;
4054 }
4056 //*************************************************************************************************
4057 
4058 
4059 //*************************************************************************************************
4070 template< typename Type > // Data type of the matrix
4071 template< typename MT // Type of the right-hand side matrix
4072  , bool SO > // Storage order of the right-hand side matrix
4074 {
4075  using blaze::addAssign;
4076 
4077  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4078  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4079  }
4080 
4081  addAssign( *this, ~rhs );
4082  return *this;
4083 }
4085 //*************************************************************************************************
4086 
4087 
4088 //*************************************************************************************************
4099 template< typename Type > // Data type of the matrix
4100 template< typename MT // Type of the right-hand side matrix
4101  , bool SO > // Storage order of the right-hand side matrix
4103 {
4104  using blaze::subAssign;
4105 
4106  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4107  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4108  }
4109 
4110  subAssign( *this, ~rhs );
4111  return *this;
4112 }
4114 //*************************************************************************************************
4115 
4116 
4117 //*************************************************************************************************
4129 template< typename Type > // Data type of the matrix
4130 template< typename MT // Type of the right-hand side dense matrix
4131  , bool SO > // Storage order of the right-hand side dense matrix
4134 {
4135  using blaze::schurAssign;
4136 
4137  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4138  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4139  }
4140 
4141  if( (~rhs).canAlias( this ) ) {
4142  CompressedMatrix tmp( *this % (~rhs) );
4143  swap( tmp );
4144  }
4145  else {
4146  CompositeType_<MT> tmp( ~rhs );
4147  schurAssign( *this, tmp );
4148  }
4149 
4150  return *this;
4151 }
4153 //*************************************************************************************************
4154 
4155 
4156 //*************************************************************************************************
4168 template< typename Type > // Data type of the matrix
4169 template< typename MT // Type of the right-hand side sparse matrix
4170  , bool SO > // Storage order of the right-hand side sparse matrix
4173 {
4174  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4175  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4176  }
4177 
4178  CompressedMatrix tmp( *this % (~rhs) );
4179  swap( tmp );
4180 
4181  return *this;
4182 }
4184 //*************************************************************************************************
4185 
4186 
4187 
4188 
4189 //=================================================================================================
4190 //
4191 // UTILITY FUNCTIONS
4192 //
4193 //=================================================================================================
4194 
4195 //*************************************************************************************************
4201 template< typename Type > // Data type of the matrix
4202 inline size_t CompressedMatrix<Type,true>::rows() const noexcept
4203 {
4204  return m_;
4205 }
4207 //*************************************************************************************************
4208 
4209 
4210 //*************************************************************************************************
4216 template< typename Type > // Data type of the matrix
4217 inline size_t CompressedMatrix<Type,true>::columns() const noexcept
4218 {
4219  return n_;
4220 }
4222 //*************************************************************************************************
4223 
4224 
4225 //*************************************************************************************************
4231 template< typename Type > // Data type of the matrix
4232 inline size_t CompressedMatrix<Type,true>::capacity() const noexcept
4233 {
4234  if( begin_ != nullptr )
4235  return end_[n_] - begin_[0UL];
4236  else return 0UL;
4237 }
4239 //*************************************************************************************************
4240 
4241 
4242 //*************************************************************************************************
4249 template< typename Type > // Data type of the matrix
4250 inline size_t CompressedMatrix<Type,true>::capacity( size_t j ) const noexcept
4251 {
4252  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4253  return begin_[j+1UL] - begin_[j];
4254 }
4256 //*************************************************************************************************
4257 
4258 
4259 //*************************************************************************************************
4265 template< typename Type > // Data type of the matrix
4266 inline size_t CompressedMatrix<Type,true>::nonZeros() const
4267 {
4268  size_t nonzeros( 0UL );
4269 
4270  for( size_t j=0UL; j<n_; ++j )
4271  nonzeros += nonZeros( j );
4272 
4273  return nonzeros;
4274 }
4276 //*************************************************************************************************
4277 
4278 
4279 //*************************************************************************************************
4286 template< typename Type > // Data type of the matrix
4287 inline size_t CompressedMatrix<Type,true>::nonZeros( size_t j ) const
4288 {
4289  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4290  return end_[j] - begin_[j];
4291 }
4293 //*************************************************************************************************
4294 
4295 
4296 //*************************************************************************************************
4302 template< typename Type > // Data type of the matrix
4304 {
4305  for( size_t j=0UL; j<n_; ++j )
4306  end_[j] = begin_[j];
4307 }
4309 //*************************************************************************************************
4310 
4311 
4312 //*************************************************************************************************
4322 template< typename Type > // Data type of the matrix
4323 inline void CompressedMatrix<Type,true>::reset( size_t j )
4324 {
4325  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4326  end_[j] = begin_[j];
4327 }
4329 //*************************************************************************************************
4330 
4331 
4332 //*************************************************************************************************
4340 template< typename Type > // Data type of the matrix
4342 {
4343  if( end_ != nullptr )
4344  end_[0UL] = end_[n_];
4345  m_ = 0UL;
4346  n_ = 0UL;
4347 }
4349 //*************************************************************************************************
4350 
4351 
4352 //*************************************************************************************************
4368 template< typename Type > // Data type of the matrix
4369 void CompressedMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
4370 {
4371  using std::swap;
4372 
4373  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4374  BLAZE_INTERNAL_ASSERT( begin_ == nullptr || size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4375 
4376  if( m == m_ && n == n_ ) return;
4377 
4378  if( begin_ == nullptr )
4379  {
4380  begin_ = new Iterator[2UL*n+2UL];
4381  end_ = begin_+n+1UL;
4382 
4383  for( size_t j=0UL; j<2UL*n+2UL; ++j ) {
4384  begin_[j] = nullptr;
4385  }
4386 
4387  capacity_ = n;
4388  }
4389  else if( n > capacity_ )
4390  {
4391  Iterator* newBegin( new Iterator[2UL*n+2UL] );
4392  Iterator* newEnd ( newBegin+n+1UL );
4393 
4394  newBegin[0UL] = begin_[0UL];
4395 
4396  if( preserve ) {
4397  for( size_t j=0UL; j<n_; ++j ) {
4398  newEnd [j] = end_ [j];
4399  newBegin[j+1UL] = begin_[j+1UL];
4400  }
4401  for( size_t j=n_; j<n; ++j ) {
4402  newBegin[j+1UL] = newEnd[j] = begin_[n_];
4403  }
4404  }
4405  else {
4406  for( size_t j=0UL; j<n; ++j ) {
4407  newBegin[j+1UL] = newEnd[j] = begin_[0UL];
4408  }
4409  }
4410 
4411  newEnd[n] = end_[n_];
4412 
4413  swap( newBegin, begin_ );
4414  delete[] newBegin;
4415  end_ = newEnd;
4416  capacity_ = n;
4417  }
4418  else if( n > n_ )
4419  {
4420  end_[n] = end_[n_];
4421 
4422  if( !preserve ) {
4423  for( size_t j=0UL; j<n_; ++j )
4424  end_[j] = begin_[j];
4425  }
4426 
4427  for( size_t j=n_; j<n; ++j ) {
4428  begin_[j+1UL] = end_[j] = begin_[n_];
4429  }
4430  }
4431  else
4432  {
4433  if( preserve ) {
4434  for( size_t j=0UL; j<n; ++j )
4435  end_[j] = lowerBound( m, j );
4436  }
4437  else {
4438  for( size_t j=0UL; j<n; ++j )
4439  end_[j] = begin_[j];
4440  }
4441 
4442  end_[n] = end_[n_];
4443  }
4444 
4445  m_ = m;
4446  n_ = n;
4447 
4448  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4449  BLAZE_INTERNAL_ASSERT( size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4450 }
4452 //*************************************************************************************************
4453 
4454 
4455 //*************************************************************************************************
4466 template< typename Type > // Data type of the matrix
4467 inline void CompressedMatrix<Type,true>::reserve( size_t nonzeros )
4468 {
4469  if( nonzeros > capacity() )
4470  reserveElements( nonzeros );
4471 }
4473 //*************************************************************************************************
4474 
4475 
4476 //*************************************************************************************************
4488 template< typename Type > // Data type of the matrix
4489 void CompressedMatrix<Type,true>::reserve( size_t j, size_t nonzeros )
4490 {
4491  using std::swap;
4492 
4493  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4494 
4495  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4496  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4497 
4498  const size_t current( capacity(j) );
4499 
4500  if( current >= nonzeros ) return;
4501 
4502  const ptrdiff_t additional( nonzeros - current );
4503 
4504  if( end_[n_] - begin_[n_] < additional )
4505  {
4506  const size_t newCapacity( begin_[n_] - begin_[0UL] + additional );
4507  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
4508 
4509  Iterator* newBegin( new Iterator[2UL*n_+2UL] );
4510  Iterator* newEnd ( newBegin+n_+1UL );
4511 
4512  newBegin[0UL] = allocate<Element>( newCapacity );
4513  newEnd [n_ ] = newBegin[0UL]+newCapacity;
4514 
4515  for( size_t k=0UL; k<j; ++k ) {
4516  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4517  newBegin[k+1UL] = newBegin[k] + capacity(k);
4518  }
4519  newEnd [j ] = castDown( transfer( begin_[j], end_[j], castUp( newBegin[j] ) ) );
4520  newBegin[j+1UL] = newBegin[j] + nonzeros;
4521  for( size_t k=j+1UL; k<n_; ++k ) {
4522  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4523  newBegin[k+1UL] = newBegin[k] + capacity(k);
4524  }
4525 
4526  BLAZE_INTERNAL_ASSERT( newBegin[n_] == newEnd[n_], "Invalid pointer calculations" );
4527 
4528  swap( newBegin, begin_ );
4529  deallocate( newBegin[0UL] );
4530  delete[] newBegin;
4531  end_ = newEnd;
4532  capacity_ = n_;
4533  }
4534  else
4535  {
4536  begin_[n_] += additional;
4537  for( size_t k=n_-1UL; k>j; --k ) {
4538  begin_[k] = castDown( std::move_backward( begin_[k], end_[k], castUp( end_[k]+additional ) ) );
4539  end_ [k] += additional;
4540  }
4541  }
4542 
4543  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4544  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4545 }
4547 //*************************************************************************************************
4548 
4549 
4550 //*************************************************************************************************
4560 template< typename Type > // Data type of the matrix
4562 {
4563  for( size_t j=0UL; j<n_; ++j )
4564  trim( j );
4565 }
4567 //*************************************************************************************************
4568 
4569 
4570 //*************************************************************************************************
4581 template< typename Type > // Data type of the matrix
4582 void CompressedMatrix<Type,true>::trim( size_t j )
4583 {
4584  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4585 
4586  if( j < ( n_ - 1UL ) )
4587  end_[j+1] = castDown( std::move( begin_[j+1], end_[j+1], castUp( end_[j] ) ) );
4588  begin_[j+1] = end_[j];
4589 }
4591 //*************************************************************************************************
4592 
4593 
4594 //*************************************************************************************************
4604 template< typename Type > // Data type of the matrix
4606 {
4607  if( nonZeros() < capacity() ) {
4608  CompressedMatrix( *this ).swap( *this );
4609  }
4610 }
4612 //*************************************************************************************************
4613 
4614 
4615 //*************************************************************************************************
4622 template< typename Type > // Data type of the matrix
4623 inline void CompressedMatrix<Type,true>::swap( CompressedMatrix& sm ) noexcept
4624 {
4625  using std::swap;
4626 
4627  swap( m_, sm.m_ );
4628  swap( n_, sm.n_ );
4629  swap( capacity_, sm.capacity_ );
4630  swap( begin_, sm.begin_ );
4631  swap( end_ , sm.end_ );
4632 }
4634 //*************************************************************************************************
4635 
4636 
4637 //*************************************************************************************************
4646 template< typename Type > // Data type of the matrix
4647 inline size_t CompressedMatrix<Type,true>::extendCapacity() const noexcept
4648 {
4649  size_t nonzeros( 2UL*capacity()+1UL );
4650  nonzeros = blaze::max( nonzeros, 7UL );
4651 
4652  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
4653 
4654  return nonzeros;
4655 }
4657 //*************************************************************************************************
4658 
4659 
4660 //*************************************************************************************************
4667 template< typename Type > // Data type of the matrix
4668 void CompressedMatrix<Type,true>::reserveElements( size_t nonzeros )
4669 {
4670  using std::swap;
4671 
4672  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
4673  Iterator* newEnd = newBegin+capacity_+1UL;
4674 
4675  newBegin[0UL] = allocate<Element>( nonzeros );
4676 
4677  for( size_t k=0UL; k<n_; ++k ) {
4678  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid column pointers" );
4679  newEnd [k] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4680  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
4681  }
4682 
4683  newEnd[n_] = newBegin[0UL]+nonzeros;
4684 
4685  swap( newBegin, begin_ );
4686  end_ = newEnd;
4687 
4688  if( newBegin != nullptr ) {
4689  deallocate( newBegin[0UL] );
4690  delete[] newBegin;
4691  }
4692 }
4694 //*************************************************************************************************
4695 
4696 
4697 //*************************************************************************************************
4705 template< typename Type > // Data type of the matrix
4707  CompressedMatrix<Type,true>::castDown( IteratorBase it ) const noexcept
4708 {
4709  return static_cast<Iterator>( it );
4710 }
4711 //*************************************************************************************************
4712 
4713 
4714 //*************************************************************************************************
4722 template< typename Type > // Data type of the matrix
4724  CompressedMatrix<Type,true>::castUp( Iterator it ) const noexcept
4725 {
4726  return static_cast<IteratorBase>( it );
4727 }
4728 //*************************************************************************************************
4729 
4730 
4731 
4732 
4733 //=================================================================================================
4734 //
4735 // INSERTION FUNCTIONS
4736 //
4737 //=================================================================================================
4738 
4739 //*************************************************************************************************
4752 template< typename Type > // Data type of the matrix
4754  CompressedMatrix<Type,true>::set( size_t i, size_t j, const Type& value )
4755 {
4756  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4757  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4758 
4759  const Iterator pos( lowerBound( i, j ) );
4760 
4761  if( pos != end_[j] && pos->index_ == i ) {
4762  pos->value() = value;
4763  return pos;
4764  }
4765  else return insert( pos, i, j, value );
4766 }
4768 //*************************************************************************************************
4769 
4770 
4771 //*************************************************************************************************
4785 template< typename Type > // Data type of the matrix
4787  CompressedMatrix<Type,true>::insert( size_t i, size_t j, const Type& value )
4788 {
4789  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4790  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4791 
4792  const Iterator pos( lowerBound( i, j ) );
4793 
4794  if( pos != end_[j] && pos->index_ == i ) {
4795  BLAZE_THROW_INVALID_ARGUMENT( "Bad access index" );
4796  }
4797 
4798  return insert( pos, i, j, value );
4799 }
4801 //*************************************************************************************************
4802 
4803 
4804 //*************************************************************************************************
4815 template< typename Type > // Data type of the matrix
4817  CompressedMatrix<Type,true>::insert( Iterator pos, size_t i, size_t j, const Type& value )
4818 {
4819  using std::swap;
4820 
4821  if( begin_[j+1UL] - end_[j] != 0 ) {
4822  std::move_backward( pos, end_[j], castUp( end_[j]+1UL ) );
4823  pos->value_ = value;
4824  pos->index_ = i;
4825  ++end_[j];
4826 
4827  return pos;
4828  }
4829  else if( end_[n_] - begin_[n_] != 0 ) {
4830  std::move_backward( pos, end_[n_-1UL], castUp( end_[n_-1]+1UL ) );
4831 
4832  pos->value_ = value;
4833  pos->index_ = i;
4834 
4835  for( size_t k=j+1UL; k<n_+1UL; ++k ) {
4836  ++begin_[k];
4837  ++end_[k-1UL];
4838  }
4839 
4840  return pos;
4841  }
4842  else {
4843  size_t newCapacity( extendCapacity() );
4844 
4845  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
4846  Iterator* newEnd = newBegin+capacity_+1UL;
4847 
4848  newBegin[0UL] = allocate<Element>( newCapacity );
4849 
4850  for( size_t k=0UL; k<j; ++k ) {
4851  const size_t nonzeros( end_[k] - begin_[k] );
4852  const size_t total( begin_[k+1UL] - begin_[k] );
4853  newEnd [k] = newBegin[k] + nonzeros;
4854  newBegin[k+1UL] = newBegin[k] + total;
4855  }
4856  newEnd [j] = newBegin[j] + ( end_[j] - begin_[j] ) + 1;
4857  newBegin[j+1UL] = newBegin[j] + ( begin_[j+1UL] - begin_[j] ) + 1;
4858  for( size_t k=j+1UL; k<n_; ++k ) {
4859  const size_t nonzeros( end_[k] - begin_[k] );
4860  const size_t total( begin_[k+1UL] - begin_[k] );
4861  newEnd [k] = newBegin[k] + nonzeros;
4862  newBegin[k+1UL] = newBegin[k] + total;
4863  }
4864 
4865  newEnd[n_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
4866 
4867  Iterator tmp = castDown( std::move( begin_[0UL], pos, castUp( newBegin[0UL] ) ) );
4868  tmp->value_ = value;
4869  tmp->index_ = i;
4870  std::move( pos, end_[n_-1UL], castUp( tmp+1UL ) );
4871 
4872  swap( newBegin, begin_ );
4873  end_ = newEnd;
4874  deallocate( newBegin[0UL] );
4875  delete[] newBegin;
4876 
4877  return tmp;
4878  }
4879 }
4881 //*************************************************************************************************
4882 
4883 
4884 //*************************************************************************************************
4937 template< typename Type > // Data type of the matrix
4938 inline void CompressedMatrix<Type,true>::append( size_t i, size_t j, const Type& value, bool check )
4939 {
4940  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
4941  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
4942  BLAZE_USER_ASSERT( end_[j] < end_[n_], "Not enough reserved capacity left" );
4943  BLAZE_USER_ASSERT( begin_[j] == end_[j] || i > ( end_[j]-1UL )->index_, "Index is not strictly increasing" );
4944 
4945  end_[j]->value_ = value;
4946 
4947  if( !check || !isDefault<strict>( end_[j]->value_ ) ) {
4948  end_[j]->index_ = i;
4949  ++end_[j];
4950  }
4951 }
4953 //*************************************************************************************************
4954 
4955 
4956 //*************************************************************************************************
4970 template< typename Type > // Data type of the matrix
4971 inline void CompressedMatrix<Type,true>::finalize( size_t j )
4972 {
4973  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
4974 
4975  begin_[j+1UL] = end_[j];
4976  if( j != n_-1UL )
4977  end_[j+1UL] = end_[j];
4978 }
4980 //*************************************************************************************************
4981 
4982 
4983 
4984 
4985 //=================================================================================================
4986 //
4987 // ERASE FUNCTIONS
4988 //
4989 //=================================================================================================
4990 
4991 //*************************************************************************************************
5001 template< typename Type > // Data type of the matrix
5002 inline void CompressedMatrix<Type,true>::erase( size_t i, size_t j )
5003 {
5004  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
5005  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5006 
5007  const Iterator pos( find( i, j ) );
5008  if( pos != end_[j] )
5009  end_[j] = castDown( std::move( pos+1, end_[j], castUp( pos ) ) );
5010 }
5012 //*************************************************************************************************
5013 
5014 
5015 //*************************************************************************************************
5025 template< typename Type > // Data type of the matrix
5028 {
5029  BLAZE_USER_ASSERT( j < columns() , "Invalid column access index" );
5030  BLAZE_USER_ASSERT( pos >= begin_[j] && pos <= end_[j], "Invalid compressed matrix iterator" );
5031 
5032  if( pos != end_[j] )
5033  end_[j] = castDown( std::move( pos+1, end_[j], castUp( pos ) ) );
5034 
5035  return pos;
5036 }
5038 //*************************************************************************************************
5039 
5040 
5041 //*************************************************************************************************
5052 template< typename Type > // Data type of the matrix
5054  CompressedMatrix<Type,true>::erase( size_t j, Iterator first, Iterator last )
5055 {
5056  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5057  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
5058  BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j], "Invalid compressed matrix iterator" );
5059  BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j], "Invalid compressed matrix iterator" );
5060 
5061  if( first != last )
5062  end_[j] = castDown( std::move( last, end_[j], castUp( first ) ) );
5063 
5064  return first;
5065 }
5067 //*************************************************************************************************
5068 
5069 
5070 //*************************************************************************************************
5092 template< typename Type > // Data type of the matrix
5093 template< typename Pred > // Type of the unary predicate
5094 inline void CompressedMatrix<Type,true>::erase( Pred predicate )
5095 {
5096  for( size_t j=0UL; j<n_; ++j ) {
5097  end_[j] = castDown( std::remove_if( castUp( begin_[j] ), castUp( end_[j] ),
5098  [predicate=predicate]( const ElementBase& element ) {
5099  return predicate( element.value() );
5100  } ) );
5101  }
5102 }
5104 //*************************************************************************************************
5105 
5106 
5107 //*************************************************************************************************
5132 template< typename Type > // Data type of the matrix
5133 template< typename Pred > // Type of the unary predicate
5134 inline void CompressedMatrix<Type,true>::erase( size_t j, Iterator first, Iterator last, Pred predicate )
5135 {
5136  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5137  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
5138  BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j], "Invalid compressed matrix iterator" );
5139  BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j], "Invalid compressed matrix iterator" );
5140 
5141  const auto pos = std::remove_if( castUp( first ), castUp( last ),
5142  [predicate=predicate]( const ElementBase& element ) {
5143  return predicate( element.value() );
5144  } );
5145 
5146  end_[j] = castDown( std::move( last, end_[j], pos ) );
5147 }
5149 //*************************************************************************************************
5150 
5151 
5152 
5153 
5154 //=================================================================================================
5155 //
5156 // LOOKUP FUNCTIONS
5157 //
5158 //=================================================================================================
5159 
5160 //*************************************************************************************************
5175 template< typename Type > // Data type of the matrix
5177  CompressedMatrix<Type,true>::find( size_t i, size_t j )
5178 {
5179  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
5180 }
5182 //*************************************************************************************************
5183 
5184 
5185 //*************************************************************************************************
5200 template< typename Type > // Data type of the matrix
5202  CompressedMatrix<Type,true>::find( size_t i, size_t j ) const
5203 {
5204  const ConstIterator pos( lowerBound( i, j ) );
5205  if( pos != end_[j] && pos->index_ == i )
5206  return pos;
5207  else return end_[j];
5208 }
5210 //*************************************************************************************************
5211 
5212 
5213 //*************************************************************************************************
5227 template< typename Type > // Data type of the matrix
5229  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j )
5230 {
5231  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
5232 }
5234 //*************************************************************************************************
5235 
5236 
5237 //*************************************************************************************************
5251 template< typename Type > // Data type of the matrix
5253  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j ) const
5254 {
5255  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5256  return std::lower_bound( begin_[j], end_[j], i,
5257  []( const Element& element, size_t index )
5258  {
5259  return element.index() < index;
5260  } );
5261 }
5263 //*************************************************************************************************
5264 
5265 
5266 //*************************************************************************************************
5280 template< typename Type > // Data type of the matrix
5282  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j )
5283 {
5284  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
5285 }
5287 //*************************************************************************************************
5288 
5289 
5290 //*************************************************************************************************
5304 template< typename Type > // Data type of the matrix
5306  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j ) const
5307 {
5308  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5309  return std::upper_bound( begin_[j], end_[j], i,
5310  []( size_t index, const Element& element )
5311  {
5312  return index < element.index();
5313  } );
5314 }
5316 //*************************************************************************************************
5317 
5318 
5319 
5320 
5321 //=================================================================================================
5322 //
5323 // NUMERIC FUNCTIONS
5324 //
5325 //=================================================================================================
5326 
5327 //*************************************************************************************************
5333 template< typename Type > // Data type of the matrix
5335 {
5336  CompressedMatrix tmp( trans( *this ) );
5337  swap( tmp );
5338  return *this;
5339 }
5341 //*************************************************************************************************
5342 
5343 
5344 //*************************************************************************************************
5350 template< typename Type > // Data type of the matrix
5352 {
5353  CompressedMatrix tmp( ctrans( *this ) );
5354  swap( tmp );
5355  return *this;
5356 }
5358 //*************************************************************************************************
5359 
5360 
5361 //*************************************************************************************************
5379 template< typename Type > // Data type of the matrix
5380 template< typename Other > // Data type of the scalar value
5382 {
5383  for( size_t j=0UL; j<n_; ++j )
5384  for( Iterator element=begin_[j]; element!=end_[j]; ++element )
5385  element->value_ *= scalar;
5386 
5387  return *this;
5388 }
5390 //*************************************************************************************************
5391 
5392 
5393 
5394 
5395 //=================================================================================================
5396 //
5397 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5398 //
5399 //=================================================================================================
5400 
5401 //*************************************************************************************************
5412 template< typename Type > // Data type of the matrix
5413 template< typename Other > // Data type of the foreign expression
5414 inline bool CompressedMatrix<Type,true>::canAlias( const Other* alias ) const noexcept
5415 {
5416  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5417 }
5419 //*************************************************************************************************
5420 
5421 
5422 //*************************************************************************************************
5433 template< typename Type > // Data type of the matrix
5434 template< typename Other > // Data type of the foreign expression
5435 inline bool CompressedMatrix<Type,true>::isAliased( const Other* alias ) const noexcept
5436 {
5437  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5438 }
5440 //*************************************************************************************************
5441 
5442 
5443 //*************************************************************************************************
5454 template< typename Type > // Data type of the matrix
5455 inline bool CompressedMatrix<Type,true>::canSMPAssign() const noexcept
5456 {
5457  return false;
5458 }
5460 //*************************************************************************************************
5461 
5462 
5463 //*************************************************************************************************
5475 template< typename Type > // Data type of the matrix
5476 template< typename MT // Type of the right-hand side dense matrix
5477  , bool SO > // Storage order of the right-hand side dense matrix
5478 inline void CompressedMatrix<Type,true>::assign( const DenseMatrix<MT,SO>& rhs )
5479 {
5480  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5481  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5482 
5483  if( m_ == 0UL || n_ == 0UL )
5484  return;
5485 
5486  size_t nonzeros( 0UL );
5487 
5488  for( size_t j=1UL; j<=n_; ++j )
5489  begin_[j] = end_[j] = end_[n_];
5490 
5491  for( size_t j=0UL; j<n_; ++j )
5492  {
5493  begin_[j] = end_[j] = begin_[0UL]+nonzeros;
5494 
5495  const size_t ibegin( ( IsLower<MT>::value )
5496  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5497  :( 0UL ) );
5498  const size_t iend ( ( IsUpper<MT>::value )
5499  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5500  :( m_ ) );
5501 
5502  for( size_t i=ibegin; i<iend; ++i )
5503  {
5504  if( nonzeros == capacity() ) {
5505  reserveElements( extendCapacity() );
5506  for( size_t k=j+1UL; k<=n_; ++k )
5507  begin_[k] = end_[k] = end_[n_];
5508  }
5509 
5510  end_[j]->value_ = (~rhs)(i,j);
5511 
5512  if( !isDefault<strict>( end_[j]->value_ ) ) {
5513  end_[j]->index_ = i;
5514  ++end_[j];
5515  ++nonzeros;
5516  }
5517  }
5518  }
5519 
5520  begin_[n_] = begin_[0UL]+nonzeros;
5521 }
5523 //*************************************************************************************************
5524 
5525 
5526 //*************************************************************************************************
5538 template< typename Type > // Data type of the matrix
5539 template< typename MT > // Type of the right-hand side compressed matrix
5540 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,true>& rhs )
5541 {
5542  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5543  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5544  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
5545  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
5546 
5547  if( n_ == 0UL || begin_[0] == nullptr )
5548  return;
5549 
5550  for( size_t j=0UL; j<n_; ++j ) {
5551  end_[j] = castDown( std::copy( (~rhs).begin(j), (~rhs).end(j), castUp( begin_[j] ) ) );
5552  begin_[j+1UL] = end_[j];
5553  }
5554 }
5556 //*************************************************************************************************
5557 
5558 
5559 //*************************************************************************************************
5571 template< typename Type > // Data type of the matrix
5572 template< typename MT > // Type of the right-hand side compressed matrix
5573 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,false>& rhs )
5574 {
5576 
5577  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5578  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5579  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
5580  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
5581 
5582  using RhsIterator = ConstIterator_<MT>;
5583 
5584  // Counting the number of elements per column
5585  std::vector<size_t> columnLengths( n_, 0UL );
5586  for( size_t i=0UL; i<m_; ++i ) {
5587  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5588  ++columnLengths[element->index()];
5589  }
5590 
5591  // Resizing the compressed matrix
5592  for( size_t j=0UL; j<n_; ++j ) {
5593  begin_[j+1UL] = end_[j+1UL] = begin_[j] + columnLengths[j];
5594  }
5595 
5596  // Appending the elements to the columns of the compressed matrix
5597  for( size_t i=0UL; i<m_; ++i ) {
5598  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5599  append( i, element->index(), element->value() );
5600  }
5601 }
5603 //*************************************************************************************************
5604 
5605 
5606 //*************************************************************************************************
5618 template< typename Type > // Data type of the matrix
5619 template< typename MT // Type of the right-hand side dense matrix
5620  , bool SO > // Storage order of the right-hand side dense matrix
5621 inline void CompressedMatrix<Type,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
5622 {
5623  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5624  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5625 
5626  CompressedMatrix tmp( serial( *this + (~rhs) ) );
5627  swap( tmp );
5628 }
5630 //*************************************************************************************************
5631 
5632 
5633 //*************************************************************************************************
5645 template< typename Type > // Data type of the matrix
5646 template< typename MT // Type of the right-hand side compressed matrix
5647  , bool SO > // Storage order of the right-hand side compressed matrix
5648 inline void CompressedMatrix<Type,true>::addAssign( const SparseMatrix<MT,SO>& rhs )
5649 {
5650  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5651  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5652 
5653  CompressedMatrix tmp( serial( *this + (~rhs) ) );
5654  swap( tmp );
5655 }
5657 //*************************************************************************************************
5658 
5659 
5660 //*************************************************************************************************
5672 template< typename Type > // Data type of the matrix
5673 template< typename MT // Type of the right-hand side dense matrix
5674  , bool SO > // Storage order of the right-hand side dense matrix
5675 inline void CompressedMatrix<Type,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
5676 {
5677  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5678  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5679 
5680  CompressedMatrix tmp( serial( *this - (~rhs) ) );
5681  swap( tmp );
5682 }
5684 //*************************************************************************************************
5685 
5686 
5687 //*************************************************************************************************
5699 template< typename Type > // Data type of the matrix
5700 template< typename MT // Type of the right-hand side compressed matrix
5701  , bool SO > // Storage order of the right-hand side compressed matrix
5702 inline void CompressedMatrix<Type,true>::subAssign( const SparseMatrix<MT,SO>& rhs )
5703 {
5704  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5705  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5706 
5707  CompressedMatrix tmp( serial( *this - (~rhs) ) );
5708  swap( tmp );
5709 }
5711 //*************************************************************************************************
5712 
5713 
5714 //*************************************************************************************************
5726 template< typename Type > // Data type of the matrix
5727 template< typename MT // Type of the right-hand side dense matrix
5728  , bool SO > // Storage order of the right-hand side dense matrix
5729 inline void CompressedMatrix<Type,true>::schurAssign( const DenseMatrix<MT,SO>& rhs )
5730 {
5731  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5732  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5733 
5735 
5736  for( size_t j=0UL; j<n_; ++j ) {
5737  const Iterator last( end(j) );
5738  for( Iterator element=begin(j); element!=last; ++element )
5739  element->value_ *= (~rhs)(element->index_,j);
5740  }
5741 }
5743 //*************************************************************************************************
5744 
5745 
5746 
5747 
5748 
5749 
5750 
5751 
5752 //=================================================================================================
5753 //
5754 // COMPRESSEDMATRIX OPERATORS
5755 //
5756 //=================================================================================================
5757 
5758 //*************************************************************************************************
5761 template< typename Type, bool SO >
5762 inline void reset( CompressedMatrix<Type,SO>& m );
5763 
5764 template< typename Type, bool SO >
5765 inline void reset( CompressedMatrix<Type,SO>& m, size_t i );
5766 
5767 template< typename Type, bool SO >
5768 inline void clear( CompressedMatrix<Type,SO>& m );
5769 
5770 template< bool RF, typename Type, bool SO >
5771 inline bool isDefault( const CompressedMatrix<Type,SO>& m );
5772 
5773 template< typename Type, bool SO >
5774 inline bool isIntact( const CompressedMatrix<Type,SO>& m );
5775 
5776 template< typename Type, bool SO >
5777 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) noexcept;
5779 //*************************************************************************************************
5780 
5781 
5782 //*************************************************************************************************
5789 template< typename Type // Data type of the matrix
5790  , bool SO > // Storage order
5791 inline void reset( CompressedMatrix<Type,SO>& m )
5792 {
5793  m.reset();
5794 }
5795 //*************************************************************************************************
5796 
5797 
5798 //*************************************************************************************************
5811 template< typename Type // Data type of the matrix
5812  , bool SO > // Storage order
5813 inline void reset( CompressedMatrix<Type,SO>& m, size_t i )
5814 {
5815  m.reset( i );
5816 }
5817 //*************************************************************************************************
5818 
5819 
5820 //*************************************************************************************************
5827 template< typename Type // Data type of the matrix
5828  , bool SO > // Storage order
5829 inline void clear( CompressedMatrix<Type,SO>& m )
5830 {
5831  m.clear();
5832 }
5833 //*************************************************************************************************
5834 
5835 
5836 //*************************************************************************************************
5861 template< bool RF // Relaxation flag
5862  , typename Type // Data type of the matrix
5863  , bool SO > // Storage order
5864 inline bool isDefault( const CompressedMatrix<Type,SO>& m )
5865 {
5866  return ( m.rows() == 0UL && m.columns() == 0UL );
5867 }
5868 //*************************************************************************************************
5869 
5870 
5871 //*************************************************************************************************
5889 template< typename Type // Data type of the matrix
5890  , bool SO > // Storage order
5891 inline bool isIntact( const CompressedMatrix<Type,SO>& m )
5892 {
5893  return ( m.nonZeros() <= m.capacity() );
5894 }
5895 //*************************************************************************************************
5896 
5897 
5898 //*************************************************************************************************
5906 template< typename Type // Data type of the matrix
5907  , bool SO > // Storage order
5908 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) noexcept
5909 {
5910  a.swap( b );
5911 }
5912 //*************************************************************************************************
5913 
5914 
5915 
5916 
5917 //=================================================================================================
5918 //
5919 // ISRESIZABLE SPECIALIZATIONS
5920 //
5921 //=================================================================================================
5922 
5923 //*************************************************************************************************
5925 template< typename T, bool SO >
5926 struct IsResizable< CompressedMatrix<T,SO> >
5927  : public TrueType
5928 {};
5930 //*************************************************************************************************
5931 
5932 
5933 
5934 
5935 //=================================================================================================
5936 //
5937 // ISSHRINKABLE SPECIALIZATIONS
5938 //
5939 //=================================================================================================
5940 
5941 //*************************************************************************************************
5943 template< typename T, bool SO >
5944 struct IsShrinkable< CompressedMatrix<T,SO> >
5945  : public TrueType
5946 {};
5948 //*************************************************************************************************
5949 
5950 
5951 
5952 
5953 //=================================================================================================
5954 //
5955 // ADDTRAIT SPECIALIZATIONS
5956 //
5957 //=================================================================================================
5958 
5959 //*************************************************************************************************
5961 template< typename T1, bool SO, typename T2, size_t M, size_t N >
5962 struct AddTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
5963 {
5964  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
5965 };
5966 
5967 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5968 struct AddTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
5969 {
5970  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO2 >;
5971 };
5972 
5973 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5974 struct AddTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
5975 {
5976  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
5977 };
5978 
5979 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5980 struct AddTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
5981 {
5982  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO1 >;
5983 };
5984 
5985 template< typename T1, bool SO, typename T2, size_t M, size_t N >
5986 struct AddTrait< CompressedMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
5987 {
5988  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO >;
5989 };
5990 
5991 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5992 struct AddTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
5993 {
5994  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO2 >;
5995 };
5996 
5997 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5998 struct AddTrait< HybridMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
5999 {
6000  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO >;
6001 };
6002 
6003 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6004 struct AddTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
6005 {
6006  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO1 >;
6007 };
6008 
6009 template< typename T1, bool SO, typename T2 >
6010 struct AddTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
6011 {
6012  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6013 };
6014 
6015 template< typename T1, bool SO1, typename T2, bool SO2 >
6016 struct AddTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
6017 {
6018  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO2 >;
6019 };
6020 
6021 template< typename T1, bool SO, typename T2 >
6022 struct AddTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6023 {
6024  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6025 };
6026 
6027 template< typename T1, bool SO1, typename T2, bool SO2 >
6028 struct AddTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
6029 {
6030  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO1 >;
6031 };
6032 
6033 template< typename T1, bool SO, typename T2, bool AF, bool PF >
6034 struct AddTrait< CompressedMatrix<T1,SO>, CustomMatrix<T2,AF,PF,SO> >
6035 {
6036  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6037 };
6038 
6039 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6040 struct AddTrait< CompressedMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6041 {
6042  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO2 >;
6043 };
6044 
6045 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6046 struct AddTrait< CustomMatrix<T1,AF,PF,SO>, CompressedMatrix<T2,SO> >
6047 {
6048  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6049 };
6050 
6051 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6052 struct AddTrait< CustomMatrix<T1,AF,PF,SO1>, CompressedMatrix<T2,SO2> >
6053 {
6054  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO1 >;
6055 };
6056 
6057 template< typename T1, bool SO, typename T2 >
6058 struct AddTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6059 {
6060  using Type = CompressedMatrix< AddTrait_<T1,T2>, SO >;
6061 };
6062 
6063 template< typename T1, bool SO1, typename T2, bool SO2 >
6064 struct AddTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
6065 {
6066  using Type = CompressedMatrix< AddTrait_<T1,T2>, false >;
6067 };
6069 //*************************************************************************************************
6070 
6071 
6072 
6073 
6074 //=================================================================================================
6075 //
6076 // SUBTRAIT SPECIALIZATIONS
6077 //
6078 //=================================================================================================
6079 
6080 //*************************************************************************************************
6082 template< typename T1, bool SO, typename T2, size_t M, size_t N >
6083 struct SubTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
6084 {
6085  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
6086 };
6087 
6088 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6089 struct SubTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
6090 {
6091  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO2 >;
6092 };
6093 
6094 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6095 struct SubTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
6096 {
6097  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
6098 };
6099 
6100 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6101 struct SubTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
6102 {
6103  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO1 >;
6104 };
6105 
6106 template< typename T1, bool SO, typename T2, size_t M, size_t N >
6107 struct SubTrait< CompressedMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
6108 {
6109  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO >;
6110 };
6111 
6112 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6113 struct SubTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
6114 {
6115  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO2 >;
6116 };
6117 
6118 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6119 struct SubTrait< HybridMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
6120 {
6121  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO >;
6122 };
6123 
6124 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6125 struct SubTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
6126 {
6127  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO1 >;
6128 };
6129 
6130 template< typename T1, bool SO, typename T2 >
6131 struct SubTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
6132 {
6133  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6134 };
6135 
6136 template< typename T1, bool SO1, typename T2, bool SO2 >
6137 struct SubTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
6138 {
6139  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO2 >;
6140 };
6141 
6142 template< typename T1, bool SO, typename T2 >
6143 struct SubTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6144 {
6145  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6146 };
6147 
6148 template< typename T1, bool SO1, typename T2, bool SO2 >
6149 struct SubTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
6150 {
6151  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO1 >;
6152 };
6153 
6154 template< typename T1, bool SO, typename T2, bool AF, bool PF >
6155 struct SubTrait< CompressedMatrix<T1,SO>, CustomMatrix<T2,AF,PF,SO> >
6156 {
6157  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6158 };
6159 
6160 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6161 struct SubTrait< CompressedMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6162 {
6163  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO2 >;
6164 };
6165 
6166 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6167 struct SubTrait< CustomMatrix<T1,AF,PF,SO>, CompressedMatrix<T2,SO> >
6168 {
6169  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6170 };
6171 
6172 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6173 struct SubTrait< CustomMatrix<T1,AF,PF,SO1>, CompressedMatrix<T2,SO2> >
6174 {
6175  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO1 >;
6176 };
6177 
6178 template< typename T1, bool SO, typename T2 >
6179 struct SubTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6180 {
6181  using Type = CompressedMatrix< SubTrait_<T1,T2>, SO >;
6182 };
6183 
6184 template< typename T1, bool SO1, typename T2, bool SO2 >
6185 struct SubTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
6186 {
6187  using Type = CompressedMatrix< SubTrait_<T1,T2>, false >;
6188 };
6190 //*************************************************************************************************
6191 
6192 
6193 
6194 
6195 //=================================================================================================
6196 //
6197 // SCHURTRAIT SPECIALIZATIONS
6198 //
6199 //=================================================================================================
6200 
6201 //*************************************************************************************************
6203 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6204 struct SchurTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
6205 {
6206  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO1 >;
6207 };
6208 
6209 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6210 struct SchurTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
6211 {
6212  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO2 >;
6213 };
6214 
6215 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6216 struct SchurTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
6217 {
6218  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO1 >;
6219 };
6220 
6221 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6222 struct SchurTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
6223 {
6224  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO2 >;
6225 };
6226 
6227 template< typename T1, bool SO1, typename T2, bool SO2 >
6228 struct SchurTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
6229 {
6230  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO1 >;
6231 };
6232 
6233 template< typename T1, bool SO1, typename T2, bool SO2 >
6234 struct SchurTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
6235 {
6236  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO2 >;
6237 };
6238 
6239 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6240 struct SchurTrait< CompressedMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6241 {
6242  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO1 >;
6243 };
6244 
6245 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6246 struct SchurTrait< CustomMatrix<T1,AF,PF,SO1>, CompressedMatrix<T2,SO2> >
6247 {
6248  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO2 >;
6249 };
6250 
6251 template< typename T1, bool SO, typename T2 >
6252 struct SchurTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6253 {
6254  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO >;
6255 };
6256 
6257 template< typename T1, bool SO1, typename T2, bool SO2 >
6258 struct SchurTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
6259 {
6260  using Type = CompressedMatrix< MultTrait_<T1,T2>, false >;
6261 };
6263 //*************************************************************************************************
6264 
6265 
6266 
6267 
6268 //=================================================================================================
6269 //
6270 // MULTTRAIT SPECIALIZATIONS
6271 //
6272 //=================================================================================================
6273 
6274 //*************************************************************************************************
6276 template< typename T1, bool SO, typename T2 >
6277 struct MultTrait< CompressedMatrix<T1,SO>, T2, EnableIf_< IsNumeric<T2> > >
6278 {
6279  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO >;
6280 };
6281 
6282 template< typename T1, typename T2, bool SO >
6283 struct MultTrait< T1, CompressedMatrix<T2,SO>, EnableIf_< IsNumeric<T1> > >
6284 {
6285  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO >;
6286 };
6287 
6288 template< typename T1, bool SO, typename T2, size_t N >
6289 struct MultTrait< CompressedMatrix<T1,SO>, StaticVector<T2,N,false> >
6290 {
6291  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6292 };
6293 
6294 template< typename T1, size_t N, typename T2, bool SO >
6295 struct MultTrait< StaticVector<T1,N,true>, CompressedMatrix<T2,SO> >
6296 {
6297  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6298 };
6299 
6300 template< typename T1, bool SO, typename T2, size_t N >
6301 struct MultTrait< CompressedMatrix<T1,SO>, HybridVector<T2,N,false> >
6302 {
6303  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6304 };
6305 
6306 template< typename T1, size_t N, typename T2, bool SO >
6307 struct MultTrait< HybridVector<T1,N,true>, CompressedMatrix<T2,SO> >
6308 {
6309  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6310 };
6311 
6312 template< typename T1, bool SO, typename T2 >
6313 struct MultTrait< CompressedMatrix<T1,SO>, DynamicVector<T2,false> >
6314 {
6315  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6316 };
6317 
6318 template< typename T1, typename T2, bool SO >
6319 struct MultTrait< DynamicVector<T1,true>, CompressedMatrix<T2,SO> >
6320 {
6321  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6322 };
6323 
6324 template< typename T1, bool SO, typename T2, bool AF, bool PF >
6325 struct MultTrait< CompressedMatrix<T1,SO>, CustomVector<T2,AF,PF,false> >
6326 {
6327  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6328 };
6329 
6330 template< typename T1, bool AF, bool PF, typename T2, bool SO >
6331 struct MultTrait< CustomVector<T1,AF,PF,true>, CompressedMatrix<T2,SO> >
6332 {
6333  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6334 };
6335 
6336 template< typename T1, bool SO, typename T2 >
6337 struct MultTrait< CompressedMatrix<T1,SO>, CompressedVector<T2,false> >
6338 {
6339  using Type = CompressedVector< MultTrait_<T1,T2>, false >;
6340 };
6341 
6342 template< typename T1, typename T2, bool SO >
6343 struct MultTrait< CompressedVector<T1,true>, CompressedMatrix<T2,SO> >
6344 {
6345  using Type = CompressedVector< MultTrait_<T1,T2>, true >;
6346 };
6347 
6348 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6349 struct MultTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
6350 {
6351  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6352 };
6353 
6354 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6355 struct MultTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
6356 {
6357  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6358 };
6359 
6360 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6361 struct MultTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
6362 {
6363  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6364 };
6365 
6366 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6367 struct MultTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
6368 {
6369  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6370 };
6371 
6372 template< typename T1, bool SO1, typename T2, bool SO2 >
6373 struct MultTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
6374 {
6375  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6376 };
6377 
6378 template< typename T1, bool SO1, typename T2, bool SO2 >
6379 struct MultTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
6380 {
6381  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6382 };
6383 
6384 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6385 struct MultTrait< CompressedMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6386 {
6387  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6388 };
6389 
6390 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6391 struct MultTrait< CustomMatrix<T1,AF,PF,SO1>, CompressedMatrix<T2,SO2> >
6392 {
6393  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6394 };
6395 
6396 template< typename T1, bool SO1, typename T2, bool SO2 >
6397 struct MultTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
6398 {
6399  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO1 >;
6400 };
6402 //*************************************************************************************************
6403 
6404 
6405 
6406 
6407 //=================================================================================================
6408 //
6409 // DIVTRAIT SPECIALIZATIONS
6410 //
6411 //=================================================================================================
6412 
6413 //*************************************************************************************************
6415 template< typename T1, bool SO, typename T2 >
6416 struct DivTrait< CompressedMatrix<T1,SO>, T2, EnableIf_< IsNumeric<T2> > >
6417 {
6418  using Type = CompressedMatrix< DivTrait_<T1,T2>, SO >;
6419 };
6421 //*************************************************************************************************
6422 
6423 
6424 
6425 
6426 //=================================================================================================
6427 //
6428 // UNARYMAPTRAIT SPECIALIZATIONS
6429 //
6430 //=================================================================================================
6431 
6432 //*************************************************************************************************
6434 template< typename T, bool SO, typename OP >
6435 struct UnaryMapTrait< CompressedMatrix<T,SO>, OP >
6436 {
6437  using Type = CompressedMatrix< UnaryMapTrait_<T,OP>, SO >;
6438 };
6440 //*************************************************************************************************
6441 
6442 
6443 
6444 
6445 //=================================================================================================
6446 //
6447 // HIGHTYPE SPECIALIZATIONS
6448 //
6449 //=================================================================================================
6450 
6451 //*************************************************************************************************
6453 template< typename T1, bool SO, typename T2 >
6454 struct HighType< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6455 {
6456  using Type = CompressedMatrix< typename HighType<T1,T2>::Type, SO >;
6457 };
6459 //*************************************************************************************************
6460 
6461 
6462 
6463 
6464 //=================================================================================================
6465 //
6466 // LOWTYPE SPECIALIZATIONS
6467 //
6468 //=================================================================================================
6469 
6470 //*************************************************************************************************
6472 template< typename T1, bool SO, typename T2 >
6473 struct LowType< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6474 {
6475  using Type = CompressedMatrix< typename LowType<T1,T2>::Type, SO >;
6476 };
6478 //*************************************************************************************************
6479 
6480 
6481 
6482 
6483 //=================================================================================================
6484 //
6485 // SUBMATRIXTRAIT SPECIALIZATIONS
6486 //
6487 //=================================================================================================
6488 
6489 //*************************************************************************************************
6491 template< typename T, bool SO, size_t... CSAs >
6492 struct SubmatrixTrait< CompressedMatrix<T,SO>, CSAs... >
6493 {
6494  using Type = CompressedMatrix<T,SO>;
6495 };
6497 //*************************************************************************************************
6498 
6499 
6500 
6501 
6502 //=================================================================================================
6503 //
6504 // ROWTRAIT SPECIALIZATIONS
6505 //
6506 //=================================================================================================
6507 
6508 //*************************************************************************************************
6510 template< typename T, bool SO, size_t... CRAs >
6511 struct RowTrait< CompressedMatrix<T,SO>, CRAs... >
6512 {
6513  using Type = CompressedVector<T,true>;
6514 };
6516 //*************************************************************************************************
6517 
6518 
6519 
6520 
6521 //=================================================================================================
6522 //
6523 // ROWSTRAIT SPECIALIZATIONS
6524 //
6525 //=================================================================================================
6526 
6527 //*************************************************************************************************
6529 template< typename T, bool SO, size_t... CRAs >
6530 struct RowsTrait< CompressedMatrix<T,SO>, CRAs... >
6531 {
6532  using Type = CompressedMatrix<T,false>;
6533 };
6535 //*************************************************************************************************
6536 
6537 
6538 
6539 
6540 //=================================================================================================
6541 //
6542 // COLUMNTRAIT SPECIALIZATIONS
6543 //
6544 //=================================================================================================
6545 
6546 //*************************************************************************************************
6548 template< typename T, bool SO, size_t... CCAs >
6549 struct ColumnTrait< CompressedMatrix<T,SO>, CCAs... >
6550 {
6551  using Type = CompressedVector<T,false>;
6552 };
6554 //*************************************************************************************************
6555 
6556 
6557 
6558 
6559 //=================================================================================================
6560 //
6561 // COLUMNSTRAIT SPECIALIZATIONS
6562 //
6563 //=================================================================================================
6564 
6565 //*************************************************************************************************
6567 template< typename T, bool SO, size_t... CCAs >
6568 struct ColumnsTrait< CompressedMatrix<T,SO>, CCAs... >
6569 {
6570  using Type = CompressedMatrix<T,true>;
6571 };
6573 //*************************************************************************************************
6574 
6575 
6576 
6577 
6578 //=================================================================================================
6579 //
6580 // BANDTRAIT SPECIALIZATIONS
6581 //
6582 //=================================================================================================
6583 
6584 //*************************************************************************************************
6586 template< typename T, bool SO, ptrdiff_t... CBAs >
6587 struct BandTrait< CompressedMatrix<T,SO>, CBAs... >
6588 {
6589  using Type = CompressedVector<T,defaultTransposeFlag>;
6590 };
6592 //*************************************************************************************************
6593 
6594 } // namespace blaze
6595 
6596 #endif
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
Definition: Const.h:79
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Pointer difference type of the Blaze library.
void reserveElements(size_t nonzeros)
Reserving the specified number of compressed matrix elements.
Definition: CompressedMatrix.h:1896
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:529
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:2947
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
void shrinkToFit()
Requesting the removal of unused capacity.
Definition: CompressedMatrix.h:1836
Header file for the subtraction trait.
bool canSMPAssign() const noexcept
Returns whether the matrix can be used in SMP assignments.
Definition: CompressedMatrix.h:2681
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:522
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:2662
Header file for the row trait.
CompressedMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: CompressedMatrix.h:2581
CompressedMatrix()
The default constructor for CompressedMatrix.
Definition: CompressedMatrix.h:573
Header file for the serial shim.
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:221
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:265
Iterator end(size_t i) noexcept
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:1022
Reference operator()(size_t i, size_t j) noexcept
2D-access to the compressed matrix elements.
Definition: CompressedMatrix.h:848
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:364
MatrixAccessProxy< This > Reference
Reference to a compressed matrix value.
Definition: CompressedMatrix.h:319
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:588
size_t m_
The current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:3288
void clear()
Clearing the compressed matrix.
Definition: CompressedMatrix.h:1573
Header file for the And class template.
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:87
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3083
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.In case the given data type is a volatile-qualified type, a compilation error is created.
Definition: Volatile.h:79
~CompressedMatrix()
The destructor for CompressedMatrix.
Definition: CompressedMatrix.h:814
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:560
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:1444
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:87
BoolConstant< true > TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3084
Header file for memory allocation and deallocation functionality.
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:1000
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1950
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:531
Resize mechanism to obtain a CompressedMatrix with different fixed dimensions.
Definition: CompressedMatrix.h:3102
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:129
void swap(CompressedMatrix &sm) noexcept
Swapping the contents of two sparse matrices.
Definition: CompressedMatrix.h:1853
Header file for the band trait.
Constraint on the data type.
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:3290
Header file for the SparseMatrix base class.
ElementBase * IteratorBase
Iterator over non-constant base elements.
Definition: CompressedMatrix.h:227
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:527
void reserve(size_t nonzeros)
Setting the minimum capacity of the compressed matrix.
Definition: CompressedMatrix.h:1697
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
void reset()
Reset to the default initial values.
Definition: CompressedMatrix.h:1535
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.
Header file for the unary map trait.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3082
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:1359
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5908
Header file for the If class template.
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:1983
Header file for the MatrixAccessProxy class.
Header file for all forward declarations of the math module.
#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.
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3079
void erase(size_t i, size_t j)
Erasing an element from the compressed matrix.
Definition: CompressedMatrix.h:2227
Iterator * end_
Pointers one past the last non-zero element of each column.
Definition: CompressedMatrix.h:3292
size_t rows() const noexcept
Returns the current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:1430
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
#define BLAZE_CONSTRAINT_MUST_HAVE_SAME_SIZE(T1, T2)
Constraint on the size of two data types.In case the types T1 and T2 don&#39;t have the same size...
Definition: SameSize.h:60
Header file for the Not class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3085
size_t capacity() const noexcept
Returns the maximum capacity of the compressed matrix.
Definition: CompressedMatrix.h:1458
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:1066
Constraint on the data type.
CompressedMatrix< Type, SO > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:311
Header file for the IsLower type trait.
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:506
Header file for the default storage order for all vectors of the Blaze library.
IteratorBase castUp(Iterator it) const noexcept
Performs an up-cast of the given iterator.
Definition: CompressedMatrix.h:1953
Iterator insert(size_t i, size_t j, const Type &value)
Inserting an element into the compressed matrix.
Definition: CompressedMatrix.h:2015
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:317
Header file for the exception macros of the math module.
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
Compile time check for data types.This type trait tests whether or not the given template parameter i...
Definition: IsSMPAssignable.h:123
BLAZE_ALWAYS_INLINE void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:714
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:430
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:2895
size_t nonZeros() const
Returns the number of non-zero elements in the compressed matrix.
Definition: CompressedMatrix.h:1495
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:608
CompressedMatrix & operator=(initializer_list< initializer_list< Type > > list)
List assignment to all matrix elements.
Definition: CompressedMatrix.h:1106
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the compressed matrix.
Definition: CompressedMatrix.h:1600
Header file for the IsNumeric 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, a compilation error is created.
Definition: Symmetric.h:79
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: CompressedMatrix.h:2642
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
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:107
Header file for run time assertion macros.
Header file for the relaxation flag types.
Header file for the addition trait.
Resize mechanism to obtain a CompressedMatrix with different fixed dimensions.
Definition: CompressedMatrix.h:339
CompressedMatrix & transpose()
In-place transpose of the matrix.
Definition: CompressedMatrix.h:2565
Header file for the division trait.
void trim()
Removing all excessive capacity from all rows/columns.
Definition: CompressedMatrix.h:1793
Header file for the submatrix trait.
Constraint on the data type.
Header file for the columns trait.
Headerfile for the generic transfer algorithm.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:79
Header file for the column trait.
Header file for the isDefault shim.
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b) noexcept
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:272
const Type & ConstReference
Reference to a constant compressed matrix value.
Definition: CompressedMatrix.h:320
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:101
Constraint on the data type.
Constraint on the data type.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:322
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:816
Iterator * begin_
Pointers to the first non-zero element of each column.
Definition: CompressedMatrix.h:3291
#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:2703
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:2165
EnableIf_< IsBuiltin< T > > deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:230
void finalize(size_t i)
Finalizing the element insertion of a row/column.
Definition: CompressedMatrix.h:2197
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
Iterator find(size_t i, size_t j)
Searches for a specific matrix element.
Definition: CompressedMatrix.h:2405
Header file for the rows trait.
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
Iterator * begin_
Pointers to the first non-zero element of each row.
Definition: CompressedMatrix.h:528
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:490
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3080
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:789
size_t n_
The current number of columns of the compressed matrix.
Definition: CompressedMatrix.h:3289
Index-value-pair for sparse vectors and matrices.The ValueIndexPair class represents a single index-v...
Definition: ValueIndexPair.h:73
Constraint on the size of two data types.
Iterator castDown(IteratorBase it) const noexcept
Performs a down-cast of the given iterator.
Definition: CompressedMatrix.h:1935
void addAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the addition assignment of a dense matrix.
Definition: CompressedMatrix.h:2843
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:2458
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:3294
Compile time type check.This class tests whether the given template parameter T is an rvalue referenc...
Definition: IsRValueReference.h:77
Iterator upperBound(size_t i, size_t j)
Returns an iterator to the first index greater than the given index.
Definition: CompressedMatrix.h:2513
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:321
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:254
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:628
size_t extendCapacity() const noexcept
Calculating a new matrix capacity.
Definition: CompressedMatrix.h:1876
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:329
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:3092
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
Header file for the IsUpper type trait.
size_t n_
The current number of columns of the compressed matrix.
Definition: CompressedMatrix.h:526
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:226
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: CompressedMatrix.h:902
Header file for the IsResizable type trait.
size_t m_
The current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:525
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:316
Reference value()
Access to the current value of the value-index-pair.
Definition: ValueIndexPair.h:362
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:956