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>
90 #include <blaze/util/Assert.h>
96 #include <blaze/util/EnableIf.h>
97 #include <blaze/util/Memory.h>
98 #include <blaze/util/Types.h>
102 
103 
104 namespace blaze {
105 
106 //=================================================================================================
107 //
108 // CLASS DEFINITION
109 //
110 //=================================================================================================
111 
112 //*************************************************************************************************
222 template< typename Type // Data type of the matrix
223  , bool SO = defaultStorageOrder > // Storage order
225  : public SparseMatrix< CompressedMatrix<Type,SO>, SO >
226 {
227  private:
228  //**Type definitions****************************************************************************
231  //**********************************************************************************************
232 
233  //**Private class Element***********************************************************************
240  struct Element
241  : public ElementBase
242  {
243  //**Constructors*****************************************************************************
244  explicit Element() = default;
245  Element( const Element& rhs ) = default;
246  Element( Element&& rhs ) = default;
247  //*******************************************************************************************
248 
249  //**Assignment operators*********************************************************************
250  inline Element& operator=( const Element& rhs )
251  {
252  this->value_ = rhs.value_;
253  return *this;
254  }
255 
256  inline Element& operator=( Element&& rhs )
257  {
258  this->value_ = std::move( rhs.value_ );
259  return *this;
260  }
261 
262  template< typename Other >
263  inline auto operator=( const Other& rhs )
265  {
266  this->value_ = rhs.value();
267  return *this;
268  }
269 
270  template< typename Other >
271  inline auto operator=( Other&& rhs )
273  IsRValueReference_v<Other&&>, Element& >
274  {
275  this->value_ = std::move( rhs.value() );
276  return *this;
277  }
278 
279  template< typename Other >
280  inline auto operator=( const Other& v )
282  {
283  this->value_ = v;
284  return *this;
285  }
286 
287  template< typename Other >
288  inline auto operator=( Other&& v )
290  IsRValueReference_v<Other&&>, Element& >
291  {
292  this->value_ = std::move( v );
293  return *this;
294  }
295  //*******************************************************************************************
296 
297  //**Friend declarations**********************************************************************
298  friend class CompressedMatrix;
299  //*******************************************************************************************
300  };
302  //**********************************************************************************************
303 
304  //**Private class Uninitialized*****************************************************************
308  struct Uninitialized {};
310  //**********************************************************************************************
311 
312  public:
313  //**Type definitions****************************************************************************
316  using ResultType = This;
319  using ElementType = Type;
320  using ReturnType = const Type&;
321  using CompositeType = const This&;
323  using ConstReference = const Type&;
324  using Iterator = Element*;
325  using ConstIterator = const Element*;
326  //**********************************************************************************************
327 
328  //**Rebind struct definition********************************************************************
331  template< typename NewType > // Data type of the other matrix
332  struct Rebind {
334  };
335  //**********************************************************************************************
336 
337  //**Resize struct definition********************************************************************
340  template< size_t NewM // Number of rows of the other matrix
341  , size_t NewN > // Number of columns of the other matrix
342  struct Resize {
344  };
345  //**********************************************************************************************
346 
347  //**Compilation flags***************************************************************************
349 
352  static constexpr bool smpAssignable = !IsSMPAssignable_v<Type>;
353  //**********************************************************************************************
354 
355  //**Constructors********************************************************************************
358  explicit inline CompressedMatrix();
359  explicit inline CompressedMatrix( size_t m, size_t n );
360  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
361  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
362  explicit inline CompressedMatrix( initializer_list< initializer_list<Type> > list );
363 
364  inline CompressedMatrix( const CompressedMatrix& sm );
365  inline CompressedMatrix( CompressedMatrix&& sm ) noexcept;
366 
367  template< typename MT, bool SO2 > inline CompressedMatrix( const DenseMatrix<MT,SO2>& dm );
368  template< typename MT, bool SO2 > inline CompressedMatrix( const SparseMatrix<MT,SO2>& sm );
370  //**********************************************************************************************
371 
372  //**Destructor**********************************************************************************
375  inline ~CompressedMatrix();
377  //**********************************************************************************************
378 
379  //**Data access functions***********************************************************************
382  inline Reference operator()( size_t i, size_t j ) noexcept;
383  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
384  inline Reference at( size_t i, size_t j );
385  inline ConstReference at( size_t i, size_t j ) const;
386  inline Iterator begin ( size_t i ) noexcept;
387  inline ConstIterator begin ( size_t i ) const noexcept;
388  inline ConstIterator cbegin( size_t i ) const noexcept;
389  inline Iterator end ( size_t i ) noexcept;
390  inline ConstIterator end ( size_t i ) const noexcept;
391  inline ConstIterator cend ( size_t i ) const noexcept;
393  //**********************************************************************************************
394 
395  //**Assignment operators************************************************************************
399  inline CompressedMatrix& operator=( const CompressedMatrix& rhs );
400  inline CompressedMatrix& operator=( CompressedMatrix&& rhs ) noexcept;
401 
402  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO2>& rhs );
403  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO2>& rhs );
404  template< typename MT, bool SO2 > inline CompressedMatrix& operator+=( const Matrix<MT,SO2>& rhs );
405  template< typename MT, bool SO2 > inline CompressedMatrix& operator-=( const Matrix<MT,SO2>& rhs );
406  template< typename MT, bool SO2 > inline CompressedMatrix& operator%=( const DenseMatrix<MT,SO2>& rhs );
407  template< typename MT, bool SO2 > inline CompressedMatrix& operator%=( const SparseMatrix<MT,SO2>& rhs );
409  //**********************************************************************************************
410 
411  //**Utility functions***************************************************************************
414  inline size_t rows() const noexcept;
415  inline size_t columns() const noexcept;
416  inline size_t capacity() const noexcept;
417  inline size_t capacity( size_t i ) const noexcept;
418  inline size_t nonZeros() const;
419  inline size_t nonZeros( size_t i ) const;
420  inline void reset();
421  inline void reset( size_t i );
422  inline void clear();
423  void resize ( size_t m, size_t n, bool preserve=true );
424  inline void reserve( size_t nonzeros );
425  void reserve( size_t i, size_t nonzeros );
426  inline void trim ();
427  inline void trim ( size_t i );
428  inline void shrinkToFit();
429  inline void swap( CompressedMatrix& sm ) noexcept;
431  //**********************************************************************************************
432 
433  //**Insertion functions*************************************************************************
436  inline Iterator set ( size_t i, size_t j, const Type& value );
437  inline Iterator insert ( size_t i, size_t j, const Type& value );
438  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
439  inline void finalize( size_t i );
441  //**********************************************************************************************
442 
443  //**Erase functions*****************************************************************************
446  inline void erase( size_t i, size_t j );
447  inline Iterator erase( size_t i, Iterator pos );
448  inline Iterator erase( size_t i, Iterator first, Iterator last );
449 
450  template< typename Pred >
451  inline void erase( Pred predicate );
452 
453  template< typename Pred >
454  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
456  //**********************************************************************************************
457 
458  //**Lookup functions****************************************************************************
461  inline Iterator find ( size_t i, size_t j );
462  inline ConstIterator find ( size_t i, size_t j ) const;
463  inline Iterator lowerBound( size_t i, size_t j );
464  inline ConstIterator lowerBound( size_t i, size_t j ) const;
465  inline Iterator upperBound( size_t i, size_t j );
466  inline ConstIterator upperBound( size_t i, size_t j ) const;
468  //**********************************************************************************************
469 
470  //**Numeric functions***************************************************************************
473  inline CompressedMatrix& transpose();
474  inline CompressedMatrix& ctranspose();
475 
476  template< typename Other > inline CompressedMatrix& scale( const Other& scalar );
478  //**********************************************************************************************
479 
480  //**Expression template evaluation functions****************************************************
483  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
484  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
485 
486  inline bool canSMPAssign() const noexcept;
487 
488  template< typename MT, bool SO2 > inline void assign ( const DenseMatrix<MT,SO2>& rhs );
489  template< typename MT > inline void assign ( const SparseMatrix<MT,SO>& rhs );
490  template< typename MT > inline void assign ( const SparseMatrix<MT,!SO>& rhs );
491  template< typename MT, bool SO2 > inline void addAssign ( const DenseMatrix<MT,SO2>& rhs );
492  template< typename MT, bool SO2 > inline void addAssign ( const SparseMatrix<MT,SO2>& rhs );
493  template< typename MT, bool SO2 > inline void subAssign ( const DenseMatrix<MT,SO2>& rhs );
494  template< typename MT, bool SO2 > inline void subAssign ( const SparseMatrix<MT,SO2>& rhs );
495  template< typename MT, bool SO2 > inline void schurAssign( const DenseMatrix<MT,SO2>& rhs );
497  //**********************************************************************************************
498 
499  private:
500  //**Constructors********************************************************************************
503  explicit inline CompressedMatrix( size_t m, size_t n, Uninitialized );
505  //**********************************************************************************************
506 
507  //**Utility functions***************************************************************************
510  inline size_t extendCapacity() const noexcept;
511  void reserveElements( size_t nonzeros );
512 
513  inline Iterator castDown( IteratorBase it ) const noexcept;
514  inline IteratorBase castUp ( Iterator it ) const noexcept;
516  //**********************************************************************************************
517 
518  //**Insertion functions*************************************************************************
521  Iterator insert( Iterator pos, size_t i, size_t j, const Type& value );
523  //**********************************************************************************************
524 
525  //**Member variables****************************************************************************
528  size_t m_;
529  size_t n_;
530  size_t capacity_;
533 
534  static const Type zero_;
535 
536  //**********************************************************************************************
537 
538  //**Compile time checks*************************************************************************
546  //**********************************************************************************************
547 };
548 //*************************************************************************************************
549 
550 
551 
552 
553 //=================================================================================================
554 //
555 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
556 //
557 //=================================================================================================
558 
559 template< typename Type, bool SO >
560 const Type CompressedMatrix<Type,SO>::zero_{};
561 
562 
563 
564 
565 //=================================================================================================
566 //
567 // CONSTRUCTORS
568 //
569 //=================================================================================================
570 
571 //*************************************************************************************************
574 template< typename Type // Data type of the matrix
575  , bool SO > // Storage order
577  : m_ ( 0UL ) // The current number of rows of the compressed matrix
578  , n_ ( 0UL ) // The current number of columns of the compressed matrix
579  , capacity_( 0UL ) // The current capacity of the pointer array
580  , begin_ ( nullptr ) // Pointers to the first non-zero element of each row
581  , end_ ( nullptr ) // Pointers one past the last non-zero element of each row
582 {}
583 //*************************************************************************************************
584 
585 
586 //*************************************************************************************************
594 template< typename Type // Data type of the matrix
595  , bool SO > // Storage order
597  : CompressedMatrix( m, n, Uninitialized() )
598 {
599  for( size_t i=1UL; i<2UL*m_+2UL; ++i )
600  begin_[i] = nullptr;
601 }
602 //*************************************************************************************************
603 
604 
605 //*************************************************************************************************
614 template< typename Type // Data type of the matrix
615  , bool SO > // Storage order
616 inline CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
617  : CompressedMatrix( m, n, Uninitialized() )
618 {
619  begin_[0UL] = allocate<Element>( nonzeros );
620  for( size_t i=1UL; i<(2UL*m_+1UL); ++i )
621  begin_[i] = begin_[0UL];
622  end_[m_] = begin_[0UL]+nonzeros;
623 }
624 //*************************************************************************************************
625 
626 
627 //*************************************************************************************************
638 template< typename Type // Data type of the matrix
639  , bool SO > // Storage order
640 CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
641  : CompressedMatrix( m, n, Uninitialized() )
642 {
643  BLAZE_USER_ASSERT( nonzeros.size() == m, "Size of capacity vector and number of rows don't match" );
644 
645  size_t newCapacity( 0UL );
646  for( auto it=nonzeros.begin(); it!=nonzeros.end(); ++it )
647  newCapacity += *it;
648 
649  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
650  for( size_t i=0UL; i<m_; ++i ) {
651  begin_[i+1UL] = end_[i+1UL] = begin_[i] + nonzeros[i];
652  }
653 }
654 //*************************************************************************************************
655 
656 
657 //*************************************************************************************************
677 template< typename Type // Data type of the matrix
678  , bool SO > // Storage order
680  : CompressedMatrix( list.size(), determineColumns( list ), blaze::nonZeros( list ) )
681 {
682  size_t i( 0UL );
683 
684  for( const auto& rowList : list )
685  {
686  size_t j( 0UL );
687 
688  for( const Type& element : rowList ) {
689  if( !isDefault<strict>( element ) )
690  append( i, j, element );
691  ++j;
692  }
693 
694  finalize( i );
695  ++i;
696  }
697 }
698 //*************************************************************************************************
699 
700 
701 //*************************************************************************************************
706 template< typename Type // Data type of the matrix
707  , bool SO > // Storage order
709  : CompressedMatrix( sm.m_, sm.n_, Uninitialized() )
710 {
711  const size_t nonzeros( sm.nonZeros() );
712 
713  begin_[0UL] = allocate<Element>( nonzeros );
714  for( size_t i=0UL; i<m_; ++i ) {
715  end_[i] = castDown( std::copy( sm.begin(i), sm.end(i), castUp( begin_[i] ) ) );
716  begin_[i+1UL] = end_[i];
717  }
718  end_[m_] = begin_[0UL]+nonzeros;
719 }
720 //*************************************************************************************************
721 
722 
723 //*************************************************************************************************
728 template< typename Type // Data type of the matrix
729  , bool SO > // Storage order
731  : m_ ( sm.m_ ) // The current number of rows of the compressed matrix
732  , n_ ( sm.n_ ) // The current number of columns of the compressed matrix
733  , capacity_( sm.capacity_ ) // The current capacity of the pointer array
734  , begin_ ( sm.begin_ ) // Pointers to the first non-zero element of each row
735  , end_ ( sm.end_ ) // Pointers one past the last non-zero element of each row
736 {
737  sm.m_ = 0UL;
738  sm.n_ = 0UL;
739  sm.capacity_ = 0UL;
740  sm.begin_ = nullptr;
741  sm.end_ = nullptr;
742 }
743 //*************************************************************************************************
744 
745 
746 //*************************************************************************************************
751 template< typename Type // Data type of the matrix
752  , bool SO > // Storage order
753 template< typename MT // Type of the foreign dense matrix
754  , bool SO2 > // Storage order of the foreign dense matrix
756  : CompressedMatrix( (~dm).rows(), (~dm).columns() )
757 {
758  using blaze::assign;
759 
760  assign( *this, ~dm );
761 }
762 //*************************************************************************************************
763 
764 
765 //*************************************************************************************************
770 template< typename Type // Data type of the matrix
771  , bool SO > // Storage order
772 template< typename MT // Type of the foreign compressed matrix
773  , bool SO2 > // Storage order of the foreign compressed matrix
775  : CompressedMatrix( (~sm).rows(), (~sm).columns(), (~sm).nonZeros() )
776 {
777  using blaze::assign;
778 
779  assign( *this, ~sm );
780 }
781 //*************************************************************************************************
782 
783 
784 //*************************************************************************************************
790 template< typename Type // Data type of the matrix
791  , bool SO > // Storage order
792 inline CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, Uninitialized )
793  : m_ ( m ) // The current number of rows of the compressed matrix
794  , n_ ( n ) // The current number of columns of the compressed matrix
795  , capacity_( m ) // The current capacity of the pointer array
796  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
797  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
798 {
799  begin_[0] = nullptr;
800 }
801 //*************************************************************************************************
802 
803 
804 
805 
806 //=================================================================================================
807 //
808 // DESTRUCTOR
809 //
810 //=================================================================================================
811 
812 //*************************************************************************************************
815 template< typename Type // Data type of the matrix
816  , bool SO > // Storage order
818 {
819  if( begin_ != nullptr ) {
820  deallocate( begin_[0UL] );
821  delete[] begin_;
822  }
823 }
824 //*************************************************************************************************
825 
826 
827 
828 
829 //=================================================================================================
830 //
831 // DATA ACCESS FUNCTIONS
832 //
833 //=================================================================================================
834 
835 //*************************************************************************************************
848 template< typename Type // Data type of the matrix
849  , bool SO > // Storage order
851  CompressedMatrix<Type,SO>::operator()( size_t i, size_t j ) noexcept
852 {
853  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
854  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
855 
856  return Reference( *this, i, j );
857 }
858 //*************************************************************************************************
859 
860 
861 //*************************************************************************************************
871 template< typename Type // Data type of the matrix
872  , bool SO > // Storage order
874  CompressedMatrix<Type,SO>::operator()( size_t i, size_t j ) const noexcept
875 {
876  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
877  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
878 
879  const ConstIterator pos( lowerBound( i, j ) );
880 
881  if( pos == end_[i] || pos->index_ != j )
882  return zero_;
883  else
884  return pos->value_;
885 }
886 //*************************************************************************************************
887 
888 
889 //*************************************************************************************************
902 template< typename Type // Data type of the matrix
903  , bool SO > // Storage order
905  CompressedMatrix<Type,SO>::at( size_t i, size_t j )
906 {
907  if( i >= m_ ) {
908  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
909  }
910  if( j >= n_ ) {
911  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
912  }
913  return (*this)(i,j);
914 }
915 //*************************************************************************************************
916 
917 
918 //*************************************************************************************************
929 template< typename Type // Data type of the matrix
930  , bool SO > // Storage order
932  CompressedMatrix<Type,SO>::at( size_t i, size_t j ) const
933 {
934  if( i >= m_ ) {
935  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
936  }
937  if( j >= n_ ) {
938  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
939  }
940  return (*this)(i,j);
941 }
942 //*************************************************************************************************
943 
944 
945 //*************************************************************************************************
956 template< typename Type // Data type of the matrix
957  , bool SO > // Storage order
959  CompressedMatrix<Type,SO>::begin( size_t i ) noexcept
960 {
961  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
962  return begin_[i];
963 }
964 //*************************************************************************************************
965 
966 
967 //*************************************************************************************************
978 template< typename Type // Data type of the matrix
979  , bool SO > // Storage order
981  CompressedMatrix<Type,SO>::begin( size_t i ) const noexcept
982 {
983  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
984  return begin_[i];
985 }
986 //*************************************************************************************************
987 
988 
989 //*************************************************************************************************
1000 template< typename Type // Data type of the matrix
1001  , bool SO > // Storage order
1003  CompressedMatrix<Type,SO>::cbegin( size_t i ) const noexcept
1004 {
1005  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1006  return begin_[i];
1007 }
1008 //*************************************************************************************************
1009 
1010 
1011 //*************************************************************************************************
1022 template< typename Type // Data type of the matrix
1023  , bool SO > // Storage order
1025  CompressedMatrix<Type,SO>::end( size_t i ) noexcept
1026 {
1027  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1028  return end_[i];
1029 }
1030 //*************************************************************************************************
1031 
1032 
1033 //*************************************************************************************************
1044 template< typename Type // Data type of the matrix
1045  , bool SO > // Storage order
1047  CompressedMatrix<Type,SO>::end( size_t i ) const noexcept
1048 {
1049  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1050  return end_[i];
1051 }
1052 //*************************************************************************************************
1053 
1054 
1055 //*************************************************************************************************
1066 template< typename Type // Data type of the matrix
1067  , bool SO > // Storage order
1069  CompressedMatrix<Type,SO>::cend( size_t i ) const noexcept
1070 {
1071  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1072  return end_[i];
1073 }
1074 //*************************************************************************************************
1075 
1076 
1077 
1078 
1079 //=================================================================================================
1080 //
1081 // ASSIGNMENT OPERATORS
1082 //
1083 //=================================================================================================
1084 
1085 //*************************************************************************************************
1106 template< typename Type // Data type of the matrix
1107  , bool SO > // Storage order
1110 {
1111  using blaze::nonZeros;
1112 
1113  resize( list.size(), determineColumns( list ), false );
1114  reserve( nonZeros( list ) );
1115 
1116  size_t i( 0UL );
1117 
1118  for( const auto& rowList : list )
1119  {
1120  size_t j( 0UL );
1121 
1122  for( const Type& element : rowList ) {
1123  if( !isDefault<strict>( element ) )
1124  append( i, j, element );
1125  ++j;
1126  }
1127 
1128  finalize( i );
1129  ++i;
1130  }
1131 
1132  return *this;
1133 }
1134 //*************************************************************************************************
1135 
1136 
1137 //*************************************************************************************************
1146 template< typename Type // Data type of the matrix
1147  , bool SO > // Storage order
1150 {
1151  using std::swap;
1152 
1153  if( &rhs == this ) return *this;
1154 
1155  const size_t nonzeros( rhs.nonZeros() );
1156 
1157  if( rhs.m_ > capacity_ || nonzeros > capacity() )
1158  {
1159  Iterator* newBegin( new Iterator[2UL*rhs.m_+2UL] );
1160  Iterator* newEnd ( newBegin+(rhs.m_+1UL) );
1161 
1162  newBegin[0UL] = allocate<Element>( nonzeros );
1163  for( size_t i=0UL; i<rhs.m_; ++i ) {
1164  newEnd[i] = castDown( std::copy( rhs.begin_[i], rhs.end_[i], castUp( newBegin[i] ) ) );
1165  newBegin[i+1UL] = newEnd[i];
1166  }
1167  newEnd[rhs.m_] = newBegin[0UL]+nonzeros;
1168 
1169  swap( begin_, newBegin );
1170  end_ = newEnd;
1171  capacity_ = rhs.m_;
1172 
1173  if( newBegin != nullptr ) {
1174  deallocate( newBegin[0UL] );
1175  delete[] newBegin;
1176  }
1177  }
1178  else {
1179  for( size_t i=0UL; i<rhs.m_; ++i ) {
1180  end_[i] = castDown( std::copy( rhs.begin_[i], rhs.end_[i], castUp( begin_[i] ) ) );
1181  begin_[i+1UL] = end_[i];
1182  }
1183  }
1184 
1185  m_ = rhs.m_;
1186  n_ = rhs.n_;
1187 
1188  return *this;
1189 }
1190 //*************************************************************************************************
1191 
1192 
1193 //*************************************************************************************************
1199 template< typename Type // Data type of the matrix
1200  , bool SO > // Storage order
1203 {
1204  if( begin_ != nullptr ) {
1205  deallocate( begin_[0UL] );
1206  delete[] begin_;
1207  }
1208 
1209  m_ = rhs.m_;
1210  n_ = rhs.n_;
1211  capacity_ = rhs.capacity_;
1212  begin_ = rhs.begin_;
1213  end_ = rhs.end_;
1214 
1215  rhs.m_ = 0UL;
1216  rhs.n_ = 0UL;
1217  rhs.capacity_ = 0UL;
1218  rhs.begin_ = nullptr;
1219  rhs.end_ = nullptr;
1220 
1221  return *this;
1222 }
1223 //*************************************************************************************************
1224 
1225 
1226 //*************************************************************************************************
1235 template< typename Type // Data type of the matrix
1236  , bool SO > // Storage order
1237 template< typename MT // Type of the right-hand side dense matrix
1238  , bool SO2 > // Storage order of the right-hand side dense matrix
1241 {
1242  using blaze::assign;
1243 
1244  if( (~rhs).canAlias( this ) ) {
1245  CompressedMatrix tmp( ~rhs );
1246  swap( tmp );
1247  }
1248  else {
1249  resize( (~rhs).rows(), (~rhs).columns(), false );
1250  assign( *this, ~rhs );
1251  }
1252 
1253  return *this;
1254 }
1255 //*************************************************************************************************
1256 
1257 
1258 //*************************************************************************************************
1267 template< typename Type // Data type of the matrix
1268  , bool SO > // Storage order
1269 template< typename MT // Type of the right-hand side compressed matrix
1270  , bool SO2 > // Storage order of the right-hand side compressed matrix
1273 {
1274  using blaze::assign;
1275 
1276  if( (~rhs).canAlias( this ) ||
1277  (~rhs).rows() > capacity_ ||
1278  (~rhs).nonZeros() > capacity() ) {
1279  CompressedMatrix tmp( ~rhs );
1280  swap( tmp );
1281  }
1282  else {
1283  resize( (~rhs).rows(), (~rhs).columns(), false );
1284  reset();
1285  assign( *this, ~rhs );
1286  }
1287 
1288  return *this;
1289 }
1290 //*************************************************************************************************
1291 
1292 
1293 //*************************************************************************************************
1303 template< typename Type // Data type of the matrix
1304  , bool SO > // Storage order
1305 template< typename MT // Type of the right-hand side matrix
1306  , bool SO2 > // Storage order of the right-hand side matrix
1309 {
1310  using blaze::addAssign;
1311 
1312  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1313  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1314  }
1315 
1316  addAssign( *this, ~rhs );
1317  return *this;
1318 }
1319 //*************************************************************************************************
1320 
1321 
1322 //*************************************************************************************************
1332 template< typename Type // Data type of the matrix
1333  , bool SO > // Storage order
1334 template< typename MT // Type of the right-hand side matrix
1335  , bool SO2 > // Storage order of the right-hand side matrix
1337 {
1338  using blaze::subAssign;
1339 
1340  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1341  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1342  }
1343 
1344  subAssign( *this, ~rhs );
1345  return *this;
1346 }
1347 //*************************************************************************************************
1348 
1349 
1350 //*************************************************************************************************
1361 template< typename Type // Data type of the matrix
1362  , bool SO > // Storage order
1363 template< typename MT // Type of the right-hand side dense matrix
1364  , bool SO2 > // Storage order of the right-hand side dense matrix
1367 {
1368  using blaze::schurAssign;
1369 
1370  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1371  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1372  }
1373 
1374  if( (~rhs).canAlias( this ) ) {
1375  CompressedMatrix tmp( *this % (~rhs) );
1376  swap( tmp );
1377  }
1378  else {
1379  CompositeType_t<MT> tmp( ~rhs );
1380  schurAssign( *this, tmp );
1381  }
1382 
1383  return *this;
1384 }
1385 //*************************************************************************************************
1386 
1387 
1388 //*************************************************************************************************
1399 template< typename Type // Data type of the matrix
1400  , bool SO > // Storage order
1401 template< typename MT // Type of the right-hand side sparse matrix
1402  , bool SO2 > // Storage order of the right-hand side sparse matrix
1405 {
1406  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1407  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1408  }
1409 
1410  CompressedMatrix tmp( *this % (~rhs) );
1411  swap( tmp );
1412 
1413  return *this;
1414 }
1415 //*************************************************************************************************
1416 
1417 
1418 
1419 
1420 //=================================================================================================
1421 //
1422 // UTILITY FUNCTIONS
1423 //
1424 //=================================================================================================
1425 
1426 //*************************************************************************************************
1431 template< typename Type // Data type of the matrix
1432  , bool SO > // Storage order
1433 inline size_t CompressedMatrix<Type,SO>::rows() const noexcept
1434 {
1435  return m_;
1436 }
1437 //*************************************************************************************************
1438 
1439 
1440 //*************************************************************************************************
1445 template< typename Type // Data type of the matrix
1446  , bool SO > // Storage order
1447 inline size_t CompressedMatrix<Type,SO>::columns() const noexcept
1448 {
1449  return n_;
1450 }
1451 //*************************************************************************************************
1452 
1453 
1454 //*************************************************************************************************
1459 template< typename Type // Data type of the matrix
1460  , bool SO > // Storage order
1461 inline size_t CompressedMatrix<Type,SO>::capacity() const noexcept
1462 {
1463  if( begin_ != nullptr )
1464  return end_[m_] - begin_[0UL];
1465  else return 0UL;
1466 }
1467 //*************************************************************************************************
1468 
1469 
1470 //*************************************************************************************************
1481 template< typename Type // Data type of the matrix
1482  , bool SO > // Storage order
1483 inline size_t CompressedMatrix<Type,SO>::capacity( size_t i ) const noexcept
1484 {
1485  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1486  return begin_[i+1UL] - begin_[i];
1487 }
1488 //*************************************************************************************************
1489 
1490 
1491 //*************************************************************************************************
1496 template< typename Type // Data type of the matrix
1497  , bool SO > // Storage order
1499 {
1500  size_t nonzeros( 0UL );
1501 
1502  for( size_t i=0UL; i<m_; ++i )
1503  nonzeros += nonZeros( i );
1504 
1505  return nonzeros;
1506 }
1507 //*************************************************************************************************
1508 
1509 
1510 //*************************************************************************************************
1521 template< typename Type // Data type of the matrix
1522  , bool SO > // Storage order
1523 inline size_t CompressedMatrix<Type,SO>::nonZeros( size_t i ) const
1524 {
1525  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1526  return end_[i] - begin_[i];
1527 }
1528 //*************************************************************************************************
1529 
1530 
1531 //*************************************************************************************************
1536 template< typename Type // Data type of the matrix
1537  , bool SO > // Storage order
1539 {
1540  for( size_t i=0UL; i<m_; ++i )
1541  end_[i] = begin_[i];
1542 }
1543 //*************************************************************************************************
1544 
1545 
1546 //*************************************************************************************************
1557 template< typename Type // Data type of the matrix
1558  , bool SO > // Storage order
1559 inline void CompressedMatrix<Type,SO>::reset( size_t i )
1560 {
1561  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1562  end_[i] = begin_[i];
1563 }
1564 //*************************************************************************************************
1565 
1566 
1567 //*************************************************************************************************
1574 template< typename Type // Data type of the matrix
1575  , bool SO > // Storage order
1577 {
1578  if( end_ != nullptr )
1579  end_[0UL] = end_[m_];
1580  m_ = 0UL;
1581  n_ = 0UL;
1582 }
1583 //*************************************************************************************************
1584 
1585 
1586 //*************************************************************************************************
1601 template< typename Type // Data type of the matrix
1602  , bool SO > // Storage order
1603 void CompressedMatrix<Type,SO>::resize( size_t m, size_t n, bool preserve )
1604 {
1605  using std::swap;
1606 
1607  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1608  BLAZE_INTERNAL_ASSERT( begin_ == nullptr || size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1609 
1610  if( m == m_ && n == n_ ) return;
1611 
1612  if( begin_ == nullptr )
1613  {
1614  begin_ = new Iterator[2UL*m+2UL];
1615  end_ = begin_+m+1UL;
1616 
1617  for( size_t i=0UL; i<2UL*m+2UL; ++i ) {
1618  begin_[i] = nullptr;
1619  }
1620 
1621  capacity_ = m;
1622  }
1623  else if( m > capacity_ )
1624  {
1625  Iterator* newBegin( new Iterator[2UL*m+2UL] );
1626  Iterator* newEnd ( newBegin+m+1UL );
1627 
1628  newBegin[0UL] = begin_[0UL];
1629 
1630  if( preserve ) {
1631  for( size_t i=0UL; i<m_; ++i ) {
1632  newEnd [i] = end_ [i];
1633  newBegin[i+1UL] = begin_[i+1UL];
1634  }
1635  for( size_t i=m_; i<m; ++i ) {
1636  newBegin[i+1UL] = newEnd[i] = begin_[m_];
1637  }
1638  }
1639  else {
1640  for( size_t i=0UL; i<m; ++i ) {
1641  newBegin[i+1UL] = newEnd[i] = begin_[0UL];
1642  }
1643  }
1644 
1645  newEnd[m] = end_[m_];
1646 
1647  swap( newBegin, begin_ );
1648  delete[] newBegin;
1649  end_ = newEnd;
1650  capacity_ = m;
1651  }
1652  else if( m > m_ )
1653  {
1654  end_[m] = end_[m_];
1655 
1656  if( !preserve ) {
1657  for( size_t i=0UL; i<m_; ++i )
1658  end_[i] = begin_[i];
1659  }
1660 
1661  for( size_t i=m_; i<m; ++i ) {
1662  begin_[i+1UL] = end_[i] = begin_[m_];
1663  }
1664  }
1665  else
1666  {
1667  if( preserve ) {
1668  for( size_t i=0UL; i<m; ++i )
1669  end_[i] = lowerBound( i, n );
1670  }
1671  else {
1672  for( size_t i=0UL; i<m; ++i )
1673  end_[i] = begin_[i];
1674  }
1675 
1676  end_[m] = end_[m_];
1677  }
1678 
1679  m_ = m;
1680  n_ = n;
1681 
1682  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1683  BLAZE_INTERNAL_ASSERT( size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1684 }
1685 //*************************************************************************************************
1686 
1687 
1688 //*************************************************************************************************
1698 template< typename Type // Data type of the matrix
1699  , bool SO > // Storage order
1700 inline void CompressedMatrix<Type,SO>::reserve( size_t nonzeros )
1701 {
1702  if( nonzeros > capacity() )
1703  reserveElements( nonzeros );
1704 }
1705 //*************************************************************************************************
1706 
1707 
1708 //*************************************************************************************************
1722 template< typename Type // Data type of the matrix
1723  , bool SO > // Storage order
1724 void CompressedMatrix<Type,SO>::reserve( size_t i, size_t nonzeros )
1725 {
1726  using std::swap;
1727 
1728  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1729 
1730  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1731  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1732 
1733  const size_t current( capacity(i) );
1734 
1735  if( current >= nonzeros ) return;
1736 
1737  const ptrdiff_t additional( nonzeros - current );
1738 
1739  if( end_[m_] - begin_[m_] < additional )
1740  {
1741  const size_t newCapacity( begin_[m_] - begin_[0UL] + additional );
1742  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
1743 
1744  Iterator* newBegin( new Iterator[2UL*m_+2UL] );
1745  Iterator* newEnd ( newBegin+m_+1UL );
1746 
1747  newBegin[0UL] = allocate<Element>( newCapacity );
1748  newEnd [m_ ] = newBegin[0UL]+newCapacity;
1749 
1750  for( size_t k=0UL; k<i; ++k ) {
1751  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
1752  newBegin[k+1UL] = newBegin[k] + capacity(k);
1753  }
1754  newEnd [i ] = castDown( transfer( begin_[i], end_[i], castUp( newBegin[i] ) ) );
1755  newBegin[i+1UL] = newBegin[i] + nonzeros;
1756  for( size_t k=i+1UL; k<m_; ++k ) {
1757  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
1758  newBegin[k+1UL] = newBegin[k] + capacity(k);
1759  }
1760 
1761  BLAZE_INTERNAL_ASSERT( newBegin[m_] == newEnd[m_], "Invalid pointer calculations" );
1762 
1763  swap( newBegin, begin_ );
1764  deallocate( newBegin[0UL] );
1765  delete[] newBegin;
1766  end_ = newEnd;
1767  capacity_ = m_;
1768  }
1769  else
1770  {
1771  begin_[m_] += additional;
1772  for( size_t j=m_-1UL; j>i; --j ) {
1773  begin_[j] = castDown( std::move_backward( begin_[j], end_[j], castUp( end_[j]+additional ) ) );
1774  end_ [j] += additional;
1775  }
1776  }
1777 
1778  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1779  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1780 }
1781 //*************************************************************************************************
1782 
1783 
1784 //*************************************************************************************************
1794 template< typename Type // Data type of the matrix
1795  , bool SO > // Storage order
1797 {
1798  for( size_t i=0UL; i<m_; ++i )
1799  trim( i );
1800 }
1801 //*************************************************************************************************
1802 
1803 
1804 //*************************************************************************************************
1815 template< typename Type // Data type of the matrix
1816  , bool SO > // Storage order
1817 inline void CompressedMatrix<Type,SO>::trim( size_t i )
1818 {
1819  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1820 
1821  if( i < ( m_ - 1UL ) )
1822  end_[i+1] = castDown( std::move( begin_[i+1], end_[i+1], castUp( end_[i] ) ) );
1823  begin_[i+1] = end_[i];
1824 }
1825 //*************************************************************************************************
1826 
1827 
1828 //*************************************************************************************************
1837 template< typename Type // Data type of the matrix
1838  , bool SO > // Storage order
1840 {
1841  if( nonZeros() < capacity() ) {
1842  CompressedMatrix( *this ).swap( *this );
1843  }
1844 }
1845 //*************************************************************************************************
1846 
1847 
1848 //*************************************************************************************************
1854 template< typename Type // Data type of the matrix
1855  , bool SO > // Storage order
1857 {
1858  using std::swap;
1859 
1860  swap( m_, sm.m_ );
1861  swap( n_, sm.n_ );
1862  swap( capacity_, sm.capacity_ );
1863  swap( begin_, sm.begin_ );
1864  swap( end_ , sm.end_ );
1865 }
1866 //*************************************************************************************************
1867 
1868 
1869 //*************************************************************************************************
1877 template< typename Type // Data type of the matrix
1878  , bool SO > // Storage order
1879 inline size_t CompressedMatrix<Type,SO>::extendCapacity() const noexcept
1880 {
1881  size_t nonzeros( 2UL*capacity()+1UL );
1882  nonzeros = blaze::max( nonzeros, 7UL );
1883 
1884  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
1885 
1886  return nonzeros;
1887 }
1888 //*************************************************************************************************
1889 
1890 
1891 //*************************************************************************************************
1897 template< typename Type // Data type of the matrix
1898  , bool SO > // Storage order
1900 {
1901  using std::swap;
1902 
1903  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1904  Iterator* newEnd = newBegin+capacity_+1UL;
1905 
1906  newBegin[0UL] = allocate<Element>( nonzeros );
1907 
1908  for( size_t k=0UL; k<m_; ++k ) {
1909  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid row pointers" );
1910  newEnd [k] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
1911  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
1912  }
1913 
1914  newEnd[m_] = newBegin[0UL]+nonzeros;
1915 
1916  swap( newBegin, begin_ );
1917  end_ = newEnd;
1918 
1919  if( newBegin != nullptr ) {
1920  deallocate( newBegin[0UL] );
1921  delete[] newBegin;
1922  }
1923 }
1924 //*************************************************************************************************
1925 
1926 
1927 //*************************************************************************************************
1935 template< typename Type // Data type of the matrix
1936  , bool SO > // Storage order
1939 {
1940  return static_cast<Iterator>( it );
1941 }
1942 //*************************************************************************************************
1943 
1944 
1945 //*************************************************************************************************
1953 template< typename Type // Data type of the matrix
1954  , bool SO > // Storage order
1957 {
1958  return static_cast<IteratorBase>( it );
1959 }
1960 //*************************************************************************************************
1961 
1962 
1963 
1964 
1965 //=================================================================================================
1966 //
1967 // INSERTION FUNCTIONS
1968 //
1969 //=================================================================================================
1970 
1971 //*************************************************************************************************
1983 template< typename Type // Data type of the matrix
1984  , bool SO > // Storage order
1986  CompressedMatrix<Type,SO>::set( size_t i, size_t j, const Type& value )
1987 {
1988  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1989  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1990 
1991  const Iterator pos( lowerBound( i, j ) );
1992 
1993  if( pos != end_[i] && pos->index_ == j ) {
1994  pos->value() = value;
1995  return pos;
1996  }
1997  else return insert( pos, i, j, value );
1998 }
1999 //*************************************************************************************************
2000 
2001 
2002 //*************************************************************************************************
2015 template< typename Type // Data type of the matrix
2016  , bool SO > // Storage order
2018  CompressedMatrix<Type,SO>::insert( size_t i, size_t j, const Type& value )
2019 {
2020  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2021  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2022 
2023  const Iterator pos( lowerBound( i, j ) );
2024 
2025  if( pos != end_[i] && pos->index_ == j ) {
2026  BLAZE_THROW_INVALID_ARGUMENT( "Bad access index" );
2027  }
2028 
2029  return insert( pos, i, j, value );
2030 }
2031 //*************************************************************************************************
2032 
2033 
2034 //*************************************************************************************************
2044 template< typename Type // Data type of the matrix
2045  , bool SO > // Storage order
2047  CompressedMatrix<Type,SO>::insert( Iterator pos, size_t i, size_t j, const Type& value )
2048 {
2049  using std::swap;
2050 
2051  if( begin_[i+1UL] - end_[i] != 0 ) {
2052  std::move_backward( pos, end_[i], castUp( end_[i]+1UL ) );
2053  pos->value_ = value;
2054  pos->index_ = j;
2055  ++end_[i];
2056 
2057  return pos;
2058  }
2059  else if( end_[m_] - begin_[m_] != 0 ) {
2060  std::move_backward( pos, end_[m_-1UL], castUp( end_[m_-1UL]+1UL ) );
2061 
2062  pos->value_ = value;
2063  pos->index_ = j;
2064 
2065  for( size_t k=i+1UL; k<m_+1UL; ++k ) {
2066  ++begin_[k];
2067  ++end_[k-1UL];
2068  }
2069 
2070  return pos;
2071  }
2072  else {
2073  size_t newCapacity( extendCapacity() );
2074 
2075  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
2076  Iterator* newEnd = newBegin+capacity_+1UL;
2077 
2078  newBegin[0UL] = allocate<Element>( newCapacity );
2079 
2080  for( size_t k=0UL; k<i; ++k ) {
2081  const size_t nonzeros( end_[k] - begin_[k] );
2082  const size_t total( begin_[k+1UL] - begin_[k] );
2083  newEnd [k] = newBegin[k] + nonzeros;
2084  newBegin[k+1UL] = newBegin[k] + total;
2085  }
2086  newEnd [i] = newBegin[i] + ( end_[i] - begin_[i] ) + 1;
2087  newBegin[i+1UL] = newBegin[i] + ( begin_[i+1] - begin_[i] ) + 1;
2088  for( size_t k=i+1UL; k<m_; ++k ) {
2089  const size_t nonzeros( end_[k] - begin_[k] );
2090  const size_t total( begin_[k+1UL] - begin_[k] );
2091  newEnd [k] = newBegin[k] + nonzeros;
2092  newBegin[k+1UL] = newBegin[k] + total;
2093  }
2094 
2095  newEnd[m_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
2096 
2097  Iterator tmp = castDown( std::move( begin_[0UL], pos, castUp( newBegin[0UL] ) ) );
2098  tmp->value_ = value;
2099  tmp->index_ = j;
2100  std::move( pos, end_[m_-1UL], castUp( tmp+1UL ) );
2101 
2102  swap( newBegin, begin_ );
2103  end_ = newEnd;
2104  deallocate( newBegin[0UL] );
2105  delete[] newBegin;
2106 
2107  return tmp;
2108  }
2109 }
2110 //*************************************************************************************************
2111 
2112 
2113 //*************************************************************************************************
2166 template< typename Type // Data type of the matrix
2167  , bool SO > // Storage order
2168 inline void CompressedMatrix<Type,SO>::append( size_t i, size_t j, const Type& value, bool check )
2169 {
2170  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2171  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
2172  BLAZE_USER_ASSERT( end_[i] < end_[m_], "Not enough reserved capacity left" );
2173  BLAZE_USER_ASSERT( begin_[i] == end_[i] || j > ( end_[i]-1UL )->index_, "Index is not strictly increasing" );
2174 
2175  end_[i]->value_ = value;
2176 
2177  if( !check || !isDefault<strict>( end_[i]->value_ ) ) {
2178  end_[i]->index_ = j;
2179  ++end_[i];
2180  }
2181 }
2182 //*************************************************************************************************
2183 
2184 
2185 //*************************************************************************************************
2198 template< typename Type // Data type of the matrix
2199  , bool SO > // Storage order
2201 {
2202  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2203 
2204  begin_[i+1UL] = end_[i];
2205  if( i != m_-1UL )
2206  end_[i+1UL] = end_[i];
2207 }
2208 //*************************************************************************************************
2209 
2210 
2211 
2212 
2213 //=================================================================================================
2214 //
2215 // ERASE FUNCTIONS
2216 //
2217 //=================================================================================================
2218 
2219 //*************************************************************************************************
2228 template< typename Type // Data type of the matrix
2229  , bool SO > // Storage order
2230 inline void CompressedMatrix<Type,SO>::erase( size_t i, size_t j )
2231 {
2232  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2233  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2234 
2235  const Iterator pos( find( i, j ) );
2236  if( pos != end_[i] )
2237  end_[i] = castDown( std::move( pos+1, end_[i], castUp( pos ) ) );
2238 }
2239 //*************************************************************************************************
2240 
2241 
2242 //*************************************************************************************************
2253 template< typename Type // Data type of the matrix
2254  , bool SO > // Storage order
2257 {
2258  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2259  BLAZE_USER_ASSERT( pos >= begin_[i] && pos <= end_[i], "Invalid compressed matrix iterator" );
2260 
2261  if( pos != end_[i] )
2262  end_[i] = castDown( std::move( pos+1, end_[i], castUp( pos ) ) );
2263 
2264  return pos;
2265 }
2266 //*************************************************************************************************
2267 
2268 
2269 //*************************************************************************************************
2281 template< typename Type // Data type of the matrix
2282  , bool SO > // Storage order
2285 {
2286  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2287  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
2288  BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i], "Invalid compressed matrix iterator" );
2289  BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i], "Invalid compressed matrix iterator" );
2290 
2291  if( first != last )
2292  end_[i] = castDown( std::move( last, end_[i], castUp( first ) ) );
2293 
2294  return first;
2295 }
2296 //*************************************************************************************************
2297 
2298 
2299 //*************************************************************************************************
2320 template< typename Type // Data type of the matrix
2321  , bool SO > // Storage order
2322 template< typename Pred > // Type of the unary predicate
2323 inline void CompressedMatrix<Type,SO>::erase( Pred predicate )
2324 {
2325  for( size_t i=0UL; i<m_; ++i ) {
2326  end_[i] = castDown( std::remove_if( castUp( begin_[i] ), castUp( end_[i] ),
2327  [predicate=predicate]( const ElementBase& element) {
2328  return predicate( element.value() );
2329  } ) );
2330  }
2331 }
2332 //*************************************************************************************************
2333 
2334 
2335 //*************************************************************************************************
2362 template< typename Type // Data type of the matrix
2363  , bool SO > // Storage order
2364 template< typename Pred > // Type of the unary predicate
2365 inline void CompressedMatrix<Type,SO>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
2366 {
2367  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2368  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
2369  BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i], "Invalid compressed matrix iterator" );
2370  BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i], "Invalid compressed matrix iterator" );
2371 
2372  const auto pos = std::remove_if( castUp( first ), castUp( last ),
2373  [predicate=predicate]( const ElementBase& element ) {
2374  return predicate( element.value() );
2375  } );
2376 
2377  end_[i] = castDown( std::move( last, end_[i], pos ) );
2378 }
2379 //*************************************************************************************************
2380 
2381 
2382 
2383 
2384 //=================================================================================================
2385 //
2386 // LOOKUP FUNCTIONS
2387 //
2388 //=================================================================================================
2389 
2390 //*************************************************************************************************
2405 template< typename Type // Data type of the matrix
2406  , bool SO > // Storage order
2408  CompressedMatrix<Type,SO>::find( size_t i, size_t j )
2409 {
2410  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
2411 }
2412 //*************************************************************************************************
2413 
2414 
2415 //*************************************************************************************************
2430 template< typename Type // Data type of the matrix
2431  , bool SO > // Storage order
2433  CompressedMatrix<Type,SO>::find( size_t i, size_t j ) const
2434 {
2435  const ConstIterator pos( lowerBound( i, j ) );
2436  if( pos != end_[i] && pos->index_ == j )
2437  return pos;
2438  else return end_[i];
2439 }
2440 //*************************************************************************************************
2441 
2442 
2443 //*************************************************************************************************
2458 template< typename Type // Data type of the matrix
2459  , bool SO > // Storage order
2462 {
2463  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
2464 }
2465 //*************************************************************************************************
2466 
2467 
2468 //*************************************************************************************************
2483 template< typename Type // Data type of the matrix
2484  , bool SO > // Storage order
2486  CompressedMatrix<Type,SO>::lowerBound( size_t i, size_t j ) const
2487 {
2488  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2489  return std::lower_bound( begin_[i], end_[i], j,
2490  []( const Element& element, size_t index )
2491  {
2492  return element.index() < index;
2493  } );
2494 }
2495 //*************************************************************************************************
2496 
2497 
2498 //*************************************************************************************************
2513 template< typename Type // Data type of the matrix
2514  , bool SO > // Storage order
2517 {
2518  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
2519 }
2520 //*************************************************************************************************
2521 
2522 
2523 //*************************************************************************************************
2538 template< typename Type // Data type of the matrix
2539  , bool SO > // Storage order
2541  CompressedMatrix<Type,SO>::upperBound( size_t i, size_t j ) const
2542 {
2543  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2544  return std::upper_bound( begin_[i], end_[i], j,
2545  []( size_t index, const Element& element )
2546  {
2547  return index < element.index();
2548  } );
2549 }
2550 //*************************************************************************************************
2551 
2552 
2553 
2554 
2555 //=================================================================================================
2556 //
2557 // NUMERIC FUNCTIONS
2558 //
2559 //=================================================================================================
2560 
2561 //*************************************************************************************************
2566 template< typename Type // Data type of the matrix
2567  , bool SO > // Storage order
2569 {
2570  CompressedMatrix tmp( trans( *this ) );
2571  swap( tmp );
2572  return *this;
2573 }
2574 //*************************************************************************************************
2575 
2576 
2577 //*************************************************************************************************
2582 template< typename Type // Data type of the matrix
2583  , bool SO > // Storage order
2585 {
2586  CompressedMatrix tmp( ctrans( *this ) );
2587  swap( tmp );
2588  return *this;
2589 }
2590 //*************************************************************************************************
2591 
2592 
2593 //*************************************************************************************************
2610 template< typename Type // Data type of the matrix
2611  , bool SO > // Storage order
2612 template< typename Other > // Data type of the scalar value
2614 {
2615  for( size_t i=0UL; i<m_; ++i )
2616  for( auto element=begin_[i]; element!=end_[i]; ++element )
2617  element->value_ *= scalar;
2618 
2619  return *this;
2620 }
2621 //*************************************************************************************************
2622 
2623 
2624 
2625 
2626 //=================================================================================================
2627 //
2628 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2629 //
2630 //=================================================================================================
2631 
2632 //*************************************************************************************************
2642 template< typename Type // Data type of the matrix
2643  , bool SO > // Storage order
2644 template< typename Other > // Data type of the foreign expression
2645 inline bool CompressedMatrix<Type,SO>::canAlias( const Other* alias ) const noexcept
2646 {
2647  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2648 }
2649 //*************************************************************************************************
2650 
2651 
2652 //*************************************************************************************************
2662 template< typename Type // Data type of the matrix
2663  , bool SO > // Storage order
2664 template< typename Other > // Data type of the foreign expression
2665 inline bool CompressedMatrix<Type,SO>::isAliased( const Other* alias ) const noexcept
2666 {
2667  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2668 }
2669 //*************************************************************************************************
2670 
2671 
2672 //*************************************************************************************************
2682 template< typename Type // Data type of the matrix
2683  , bool SO > // Storage order
2684 inline bool CompressedMatrix<Type,SO>::canSMPAssign() const noexcept
2685 {
2686  return false;
2687 }
2688 //*************************************************************************************************
2689 
2690 
2691 //*************************************************************************************************
2702 template< typename Type // Data type of the matrix
2703  , bool SO > // Storage order
2704 template< typename MT // Type of the right-hand side dense matrix
2705  , bool SO2 > // Storage order of the right-hand side dense matrix
2707 {
2708  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2709  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2710 
2711  if( m_ == 0UL || n_ == 0UL )
2712  return;
2713 
2714  size_t nonzeros( 0UL );
2715 
2716  for( size_t i=1UL; i<=m_; ++i )
2717  begin_[i] = end_[i] = end_[m_];
2718 
2719  for( size_t i=0UL; i<m_; ++i )
2720  {
2721  begin_[i] = end_[i] = begin_[0UL]+nonzeros;
2722 
2723  const size_t jbegin( ( IsUpper_v<MT> )
2724  ?( IsStrictlyUpper_v<MT> ? i+1UL : i )
2725  :( 0UL ) );
2726  const size_t jend ( ( IsLower_v<MT> )
2727  ?( IsStrictlyLower_v<MT> ? i : i+1UL )
2728  :( n_ ) );
2729 
2730  for( size_t j=jbegin; j<jend; ++j )
2731  {
2732  if( nonzeros == capacity() ) {
2733  reserveElements( extendCapacity() );
2734  for( size_t k=i+1UL; k<=m_; ++k )
2735  begin_[k] = end_[k] = end_[m_];
2736  }
2737 
2738  end_[i]->value_ = (~rhs)(i,j);
2739 
2740  if( !isDefault<strict>( end_[i]->value_ ) ) {
2741  end_[i]->index_ = j;
2742  ++end_[i];
2743  ++nonzeros;
2744  }
2745  }
2746  }
2747 
2748  begin_[m_] = begin_[0UL]+nonzeros;
2749 }
2750 //*************************************************************************************************
2751 
2752 
2753 //*************************************************************************************************
2764 template< typename Type // Data type of the matrix
2765  , bool SO > // Storage order
2766 template< typename MT > // Type of the right-hand side compressed matrix
2768 {
2769  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2770  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2771  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2772  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
2773 
2774  if( m_ == 0UL || begin_[0] == nullptr )
2775  return;
2776 
2777  for( size_t i=0UL; i<m_; ++i ) {
2778  end_[i] = castDown( std::copy( (~rhs).begin(i), (~rhs).end(i), castUp( begin_[i] ) ) );
2779  begin_[i+1UL] = end_[i];
2780  }
2781 }
2782 //*************************************************************************************************
2783 
2784 
2785 //*************************************************************************************************
2796 template< typename Type // Data type of the matrix
2797  , bool SO > // Storage order
2798 template< typename MT > // Type of the right-hand side compressed matrix
2800 {
2802 
2803  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2804  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2805  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2806  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
2807 
2808  // Counting the number of elements per row
2809  std::vector<size_t> rowLengths( m_, 0UL );
2810  for( size_t j=0UL; j<n_; ++j ) {
2811  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2812  ++rowLengths[element->index()];
2813  }
2814 
2815  // Resizing the compressed matrix
2816  for( size_t i=0UL; i<m_; ++i ) {
2817  begin_[i+1UL] = end_[i+1UL] = begin_[i] + rowLengths[i];
2818  }
2819 
2820  // Appending the elements to the rows of the compressed matrix
2821  for( size_t j=0UL; j<n_; ++j ) {
2822  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2823  append( element->index(), j, element->value() );
2824  }
2825 }
2826 //*************************************************************************************************
2827 
2828 
2829 //*************************************************************************************************
2840 template< typename Type // Data type of the matrix
2841  , bool SO > // Storage order
2842 template< typename MT // Type of the right-hand side dense matrix
2843  , bool SO2 > // Storage order of the right-hand side dense matrix
2845 {
2846  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2847  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2848 
2849  CompressedMatrix tmp( serial( *this + (~rhs) ) );
2850  swap( tmp );
2851 }
2852 //*************************************************************************************************
2853 
2854 
2855 //*************************************************************************************************
2866 template< typename Type // Data type of the matrix
2867  , bool SO > // Storage order
2868 template< typename MT // Type of the right-hand side compressed matrix
2869  , bool SO2 > // Storage order of the right-hand side compressed matrix
2871 {
2872  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2873  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2874 
2875  CompressedMatrix tmp( serial( *this + (~rhs) ) );
2876  swap( tmp );
2877 }
2878 //*************************************************************************************************
2879 
2880 
2881 //*************************************************************************************************
2892 template< typename Type // Data type of the matrix
2893  , bool SO > // Storage order
2894 template< typename MT // Type of the right-hand side dense matrix
2895  , bool SO2 > // Storage order of the right-hand side dense matrix
2897 {
2898  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2899  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2900 
2901  CompressedMatrix tmp( serial( *this - (~rhs) ) );
2902  swap( tmp );
2903 }
2904 //*************************************************************************************************
2905 
2906 
2907 //*************************************************************************************************
2918 template< typename Type // Data type of the matrix
2919  , bool SO > // Storage order
2920 template< typename MT // Type of the right-hand side compressed matrix
2921  , bool SO2 > // Storage order of the right-hand compressed matrix
2923 {
2924  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2925  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2926 
2927  CompressedMatrix tmp( serial( *this - (~rhs) ) );
2928  swap( tmp );
2929 }
2930 //*************************************************************************************************
2931 
2932 
2933 //*************************************************************************************************
2944 template< typename Type // Data type of the matrix
2945  , bool SO > // Storage order
2946 template< typename MT // Type of the right-hand side dense matrix
2947  , bool SO2 > // Storage order of the right-hand side dense matrix
2949 {
2950  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2951  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2952 
2954 
2955  for( size_t i=0UL; i<m_; ++i ) {
2956  const Iterator last( end(i) );
2957  for( auto element=begin(i); element!=last; ++element )
2958  element->value_ *= (~rhs)(i,element->index_);
2959  }
2960 }
2961 //*************************************************************************************************
2962 
2963 
2964 
2965 
2966 
2967 
2968 
2969 
2970 //=================================================================================================
2971 //
2972 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2973 //
2974 //=================================================================================================
2975 
2976 //*************************************************************************************************
2984 template< typename Type > // Data type of the matrix
2985 class CompressedMatrix<Type,true>
2986  : public SparseMatrix< CompressedMatrix<Type,true>, true >
2987 {
2988  private:
2989  //**Type definitions****************************************************************************
2991  using IteratorBase = ElementBase*;
2992  //**********************************************************************************************
2993 
2994  //**Private class Element***********************************************************************
3001  struct Element
3002  : public ElementBase
3003  {
3004  //**Constructors*****************************************************************************
3005  explicit Element() = default;
3006  Element( const Element& rhs ) = default;
3007  Element( Element&& rhs ) = default;
3008  //*******************************************************************************************
3009 
3010  //**Assignment operators*********************************************************************
3011  inline Element& operator=( const Element& rhs )
3012  {
3013  this->value_ = rhs.value_;
3014  return *this;
3015  }
3016 
3017  inline Element& operator=( Element&& rhs )
3018  {
3019  this->value_ = std::move( rhs.value_ );
3020  return *this;
3021  }
3022 
3023  template< typename Other >
3024  inline auto operator=( const Other& rhs )
3025  -> EnableIf_t< IsSparseElement_v<Other>, Element& >
3026  {
3027  this->value_ = rhs.value();
3028  return *this;
3029  }
3030 
3031  template< typename Other >
3032  inline auto operator=( Other&& rhs )
3033  -> EnableIf_t< IsSparseElement_v< RemoveReference_t<Other> > &&
3034  IsRValueReference_v<Other&&>, Element& >
3035  {
3036  this->value_ = std::move( rhs.value() );
3037  return *this;
3038  }
3039 
3040  template< typename Other >
3041  inline auto operator=( const Other& v )
3042  -> EnableIf_t< !IsSparseElement_v<Other>, Element& >
3043  {
3044  this->value_ = v;
3045  return *this;
3046  }
3047 
3048  template< typename Other >
3049  inline auto operator=( Other&& v )
3050  -> EnableIf_t< !IsSparseElement_v< RemoveReference_t<Other> > &&
3051  IsRValueReference_v<Other&&>, Element& >
3052  {
3053  this->value_ = std::move( v );
3054  return *this;
3055  }
3056  //*******************************************************************************************
3057 
3058  //**Friend declarations**********************************************************************
3059  friend class CompressedMatrix;
3060  //*******************************************************************************************
3061  };
3063  //**********************************************************************************************
3064 
3065  //**Private class Uninitialized*****************************************************************
3069  struct Uninitialized {};
3071  //**********************************************************************************************
3072 
3073  public:
3074  //**Type definitions****************************************************************************
3077  using ResultType = This;
3080  using ElementType = Type;
3081  using ReturnType = const Type&;
3082  using CompositeType = const This&;
3084  using ConstReference = const Type&;
3085  using Iterator = Element*;
3086  using ConstIterator = const Element*;
3087  //**********************************************************************************************
3088 
3089  //**Rebind struct definition********************************************************************
3092  template< typename NewType > // Data type of the other matrix
3093  struct Rebind {
3095  };
3096  //**********************************************************************************************
3097 
3098  //**Resize struct definition********************************************************************
3101  template< size_t NewM // Number of rows of the other matrix
3102  , size_t NewN > // Number of columns of the other matrix
3103  struct Resize {
3105  };
3106  //**********************************************************************************************
3107 
3108  //**Compilation flags***************************************************************************
3110 
3113  static constexpr bool smpAssignable = !IsSMPAssignable_v<Type>;
3114  //**********************************************************************************************
3115 
3116  //**Constructors********************************************************************************
3119  explicit inline CompressedMatrix();
3120  explicit inline CompressedMatrix( size_t m, size_t n );
3121  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
3122  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
3123  explicit inline CompressedMatrix( initializer_list< initializer_list<Type> > list );
3124 
3125  inline CompressedMatrix( const CompressedMatrix& sm );
3126  inline CompressedMatrix( CompressedMatrix&& sm ) noexcept;
3127 
3128  template< typename MT, bool SO > inline CompressedMatrix( const DenseMatrix<MT,SO>& dm );
3129  template< typename MT, bool SO > inline CompressedMatrix( const SparseMatrix<MT,SO>& sm );
3131  //**********************************************************************************************
3132 
3133  //**Destructor**********************************************************************************
3136  inline ~CompressedMatrix();
3138  //**********************************************************************************************
3139 
3140  //**Data access functions***********************************************************************
3143  inline Reference operator()( size_t i, size_t j ) noexcept;
3144  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3145  inline Reference at( size_t i, size_t j );
3146  inline ConstReference at( size_t i, size_t j ) const;
3147  inline Iterator begin ( size_t j ) noexcept;
3148  inline ConstIterator begin ( size_t j ) const noexcept;
3149  inline ConstIterator cbegin( size_t j ) const noexcept;
3150  inline Iterator end ( size_t j ) noexcept;
3151  inline ConstIterator end ( size_t j ) const noexcept;
3152  inline ConstIterator cend ( size_t j ) const noexcept;
3154  //**********************************************************************************************
3155 
3156  //**Assignment operators************************************************************************
3160  inline CompressedMatrix& operator=( const CompressedMatrix& rhs );
3161  inline CompressedMatrix& operator=( CompressedMatrix&& rhs ) noexcept;
3162 
3163  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO>& rhs );
3164  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const SparseMatrix<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 Matrix<MT,SO>& rhs );
3167  template< typename MT, bool SO > inline CompressedMatrix& operator%=( const DenseMatrix<MT,SO>& rhs );
3168  template< typename MT, bool SO > inline CompressedMatrix& operator%=( const SparseMatrix<MT,SO>& rhs );
3170  //**********************************************************************************************
3171 
3172  //**Utility functions***************************************************************************
3175  inline size_t rows() const noexcept;
3176  inline size_t columns() const noexcept;
3177  inline size_t capacity() const noexcept;
3178  inline size_t capacity( size_t j ) const noexcept;
3179  inline size_t nonZeros() const;
3180  inline size_t nonZeros( size_t j ) const;
3181  inline void reset();
3182  inline void reset( size_t j );
3183  inline void clear();
3184  void resize ( size_t m, size_t n, bool preserve=true );
3185  inline void reserve( size_t nonzeros );
3186  void reserve( size_t j, size_t nonzeros );
3187  inline void trim ();
3188  inline void trim ( size_t j );
3189  inline void shrinkToFit();
3190  inline void swap( CompressedMatrix& sm ) noexcept;
3192  //**********************************************************************************************
3193 
3194  //**Insertion functions*************************************************************************
3197  inline Iterator set ( size_t i, size_t j, const Type& value );
3198  inline Iterator insert ( size_t i, size_t j, const Type& value );
3199  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
3200  inline void finalize( size_t j );
3202  //**********************************************************************************************
3203 
3204  //**Erase functions*****************************************************************************
3207  inline void erase( size_t i, size_t j );
3208  inline Iterator erase( size_t j, Iterator pos );
3209  inline Iterator erase( size_t j, Iterator first, Iterator last );
3210 
3211  template< typename Pred >
3212  inline void erase( Pred predicate );
3213 
3214  template< typename Pred >
3215  inline void erase( size_t j, Iterator first, Iterator last, Pred predicate );
3217  //**********************************************************************************************
3218 
3219  //**Lookup functions****************************************************************************
3222  inline Iterator find ( size_t i, size_t j );
3223  inline ConstIterator find ( size_t i, size_t j ) const;
3224  inline Iterator lowerBound( size_t i, size_t j );
3225  inline ConstIterator lowerBound( size_t i, size_t j ) const;
3226  inline Iterator upperBound( size_t i, size_t j );
3227  inline ConstIterator upperBound( size_t i, size_t j ) const;
3229  //**********************************************************************************************
3230 
3231  //**Numeric functions***************************************************************************
3234  inline CompressedMatrix& transpose();
3235  inline CompressedMatrix& ctranspose();
3236 
3237  template< typename Other > inline CompressedMatrix& scale( const Other& scalar );
3239  //**********************************************************************************************
3240 
3241  //**Expression template evaluation functions****************************************************
3244  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3245  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3246 
3247  inline bool canSMPAssign() const noexcept;
3248 
3249  template< typename MT, bool SO > inline void assign ( const DenseMatrix<MT,SO>& rhs );
3250  template< typename MT > inline void assign ( const SparseMatrix<MT,true>& rhs );
3251  template< typename MT > inline void assign ( const SparseMatrix<MT,false>& rhs );
3252  template< typename MT, bool SO > inline void addAssign ( const DenseMatrix<MT,SO>& rhs );
3253  template< typename MT, bool SO > inline void addAssign ( const SparseMatrix<MT,SO>& rhs );
3254  template< typename MT, bool SO > inline void subAssign ( const DenseMatrix<MT,SO>& rhs );
3255  template< typename MT, bool SO > inline void subAssign ( const SparseMatrix<MT,SO>& rhs );
3256  template< typename MT, bool SO > inline void schurAssign( const DenseMatrix<MT,SO>& rhs );
3258  //**********************************************************************************************
3259 
3260  private:
3261  //**Constructors********************************************************************************
3264  explicit inline CompressedMatrix( size_t m, size_t n, Uninitialized );
3266  //**********************************************************************************************
3267 
3268  //**Utility functions***************************************************************************
3271  inline size_t extendCapacity() const noexcept;
3272  void reserveElements( size_t nonzeros );
3273 
3274  inline Iterator castDown( IteratorBase it ) const noexcept;
3275  inline IteratorBase castUp ( Iterator it ) const noexcept;
3277  //**********************************************************************************************
3278 
3279  //**Insertion functions*************************************************************************
3282  Iterator insert( Iterator pos, size_t i, size_t j, const Type& value );
3284  //**********************************************************************************************
3285 
3286  //**Member variables****************************************************************************
3289  size_t m_;
3290  size_t n_;
3291  size_t capacity_;
3294 
3295  static const Type zero_;
3296 
3297  //**********************************************************************************************
3298 
3299  //**Compile time checks*************************************************************************
3307  //**********************************************************************************************
3308 };
3310 //*************************************************************************************************
3311 
3312 
3313 
3314 
3315 //=================================================================================================
3316 //
3317 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
3318 //
3319 //=================================================================================================
3320 
3321 template< typename Type >
3322 const Type CompressedMatrix<Type,true>::zero_{};
3323 
3324 
3325 
3326 
3327 //=================================================================================================
3328 //
3329 // CONSTRUCTORS
3330 //
3331 //=================================================================================================
3332 
3333 //*************************************************************************************************
3337 template< typename Type > // Data type of the matrix
3339  : m_ ( 0UL ) // The current number of rows of the compressed matrix
3340  , n_ ( 0UL ) // The current number of columns of the compressed matrix
3341  , capacity_( 0UL ) // The current capacity of the pointer array
3342  , begin_ ( nullptr ) // Pointers to the first non-zero element of each column
3343  , end_ ( nullptr ) // Pointers one past the last non-zero element of each column
3344 {}
3346 //*************************************************************************************************
3347 
3348 
3349 //*************************************************************************************************
3358 template< typename Type > // Data type of the matrix
3359 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n )
3360  : CompressedMatrix( m, n, Uninitialized() )
3361 {
3362  for( size_t j=1UL; j<2UL*n_+2UL; ++j )
3363  begin_[j] = nullptr;
3364 }
3366 //*************************************************************************************************
3367 
3368 
3369 //*************************************************************************************************
3379 template< typename Type > // Data type of the matrix
3380 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
3381  : CompressedMatrix( m, n, Uninitialized() )
3382 {
3383  begin_[0UL] = allocate<Element>( nonzeros );
3384  for( size_t j=1UL; j<(2UL*n_+1UL); ++j )
3385  begin_[j] = begin_[0UL];
3386  end_[n_] = begin_[0UL]+nonzeros;
3387 }
3389 //*************************************************************************************************
3390 
3391 
3392 //*************************************************************************************************
3403 template< typename Type > // Data type of the matrix
3404 CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
3405  : CompressedMatrix( m, n, Uninitialized() )
3406 {
3407  BLAZE_USER_ASSERT( nonzeros.size() == n, "Size of capacity vector and number of columns don't match" );
3408 
3409  size_t newCapacity( 0UL );
3410  for( auto it=nonzeros.begin(); it!=nonzeros.end(); ++it )
3411  newCapacity += *it;
3412 
3413  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
3414  for( size_t j=0UL; j<n_; ++j ) {
3415  begin_[j+1UL] = end_[j+1UL] = begin_[j] + nonzeros[j];
3416  }
3417 }
3419 //*************************************************************************************************
3420 
3421 
3422 //*************************************************************************************************
3443 template< typename Type > // Data type of the matrix
3444 inline CompressedMatrix<Type,true>::CompressedMatrix( initializer_list< initializer_list<Type> > list )
3445  : CompressedMatrix( list.size(), determineColumns( list ), blaze::nonZeros( list ) )
3446 {
3447  for( size_t j=0UL; j<n_; ++j )
3448  {
3449  size_t i( 0UL );
3450 
3451  for( const auto& rowList : list )
3452  {
3453  if( rowList.size() <= j ) {
3454  ++i;
3455  continue;
3456  }
3457 
3458  auto pos( rowList.begin() );
3459  std::advance( pos, j );
3460  if( !isDefault<strict>( *pos ) )
3461  append( i, j, *pos );
3462  ++i;
3463  }
3464 
3465  finalize( j );
3466  }
3467 }
3469 //*************************************************************************************************
3470 
3471 
3472 //*************************************************************************************************
3478 template< typename Type > // Data type of the matrix
3479 inline CompressedMatrix<Type,true>::CompressedMatrix( const CompressedMatrix& sm )
3480  : CompressedMatrix( sm.m_, sm.n_, Uninitialized() )
3481 {
3482  const size_t nonzeros( sm.nonZeros() );
3483 
3484  begin_[0UL] = allocate<Element>( nonzeros );
3485  for( size_t j=0UL; j<n_; ++j ) {
3486  end_[j] = castDown( std::copy( sm.begin(j), sm.end(j), castUp( begin_[j] ) ) );
3487  begin_[j+1UL] = end_[j];
3488  }
3489  end_[n_] = begin_[0UL]+nonzeros;
3490 }
3492 //*************************************************************************************************
3493 
3494 
3495 //*************************************************************************************************
3501 template< typename Type > // Data type of the matrix
3502 inline CompressedMatrix<Type,true>::CompressedMatrix( CompressedMatrix&& sm ) noexcept
3503  : m_ ( sm.m_ ) // The current number of rows of the compressed matrix
3504  , n_ ( sm.n_ ) // The current number of columns of the compressed matrix
3505  , capacity_( sm.capacity_ ) // The current capacity of the pointer array
3506  , begin_ ( sm.begin_ ) // Pointers to the first non-zero element of each column
3507  , end_ ( sm.end_ ) // Pointers one past the last non-zero element of each column
3508 {
3509  sm.m_ = 0UL;
3510  sm.n_ = 0UL;
3511  sm.capacity_ = 0UL;
3512  sm.begin_ = nullptr;
3513  sm.end_ = nullptr;
3514 }
3516 //*************************************************************************************************
3517 
3518 
3519 //*************************************************************************************************
3525 template< typename Type > // Data type of the matrix
3526 template< typename MT // Type of the foreign dense matrix
3527  , bool SO > // Storage order of the foreign dense matrix
3528 inline CompressedMatrix<Type,true>::CompressedMatrix( const DenseMatrix<MT,SO>& dm )
3529  : CompressedMatrix( (~dm).rows(), (~dm).columns() )
3530 {
3531  using blaze::assign;
3532 
3533  assign( *this, ~dm );
3534 }
3536 //*************************************************************************************************
3537 
3538 
3539 //*************************************************************************************************
3545 template< typename Type > // Data type of the matrix
3546 template< typename MT // Type of the foreign compressed matrix
3547  , bool SO > // Storage order of the foreign compressed matrix
3548 inline CompressedMatrix<Type,true>::CompressedMatrix( const SparseMatrix<MT,SO>& sm )
3549  : CompressedMatrix( (~sm).rows(), (~sm).columns(), (~sm).nonZeros() )
3550 {
3551  using blaze::assign;
3552 
3553  assign( *this, ~sm );
3554 }
3556 //*************************************************************************************************
3557 
3558 
3559 //*************************************************************************************************
3566 template< typename Type > // Data type of the matrix
3567 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, Uninitialized )
3568  : m_ ( m ) // The current number of rows of the compressed matrix
3569  , n_ ( n ) // The current number of columns of the compressed matrix
3570  , capacity_( n ) // The current capacity of the pointer array
3571  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
3572  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
3573 {
3574  begin_[0UL] = nullptr;
3575 }
3577 //*************************************************************************************************
3578 
3579 
3580 
3581 
3582 //=================================================================================================
3583 //
3584 // DESTRUCTOR
3585 //
3586 //=================================================================================================
3587 
3588 //*************************************************************************************************
3592 template< typename Type > // Data type of the matrix
3593 inline CompressedMatrix<Type,true>::~CompressedMatrix()
3594 {
3595  if( begin_ != nullptr ) {
3596  deallocate( begin_[0UL] );
3597  delete[] begin_;
3598  }
3599 }
3601 //*************************************************************************************************
3602 
3603 
3604 
3605 
3606 //=================================================================================================
3607 //
3608 // DATA ACCESS FUNCTIONS
3609 //
3610 //=================================================================================================
3611 
3612 //*************************************************************************************************
3626 template< typename Type > // Data type of the matrix
3628  CompressedMatrix<Type,true>::operator()( size_t i, size_t j ) noexcept
3629 {
3630  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3631  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3632 
3633  return Reference( *this, i, j );
3634 }
3636 //*************************************************************************************************
3637 
3638 
3639 //*************************************************************************************************
3650 template< typename Type > // Data type of the matrix
3652  CompressedMatrix<Type,true>::operator()( size_t i, size_t j ) const noexcept
3653 {
3654  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3655  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3656 
3657  const ConstIterator pos( lowerBound( i, j ) );
3658 
3659  if( pos == end_[j] || pos->index_ != i )
3660  return zero_;
3661  else
3662  return pos->value_;
3663 }
3665 //*************************************************************************************************
3666 
3667 
3668 //*************************************************************************************************
3682 template< typename Type > // Data type of the matrix
3684  CompressedMatrix<Type,true>::at( size_t i, size_t j )
3685 {
3686  if( i >= m_ ) {
3687  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3688  }
3689  if( j >= n_ ) {
3690  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3691  }
3692  return (*this)(i,j);
3693 }
3695 //*************************************************************************************************
3696 
3697 
3698 //*************************************************************************************************
3710 template< typename Type > // Data type of the matrix
3712  CompressedMatrix<Type,true>::at( size_t i, size_t j ) const
3713 {
3714  if( i >= m_ ) {
3715  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3716  }
3717  if( j >= n_ ) {
3718  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3719  }
3720  return (*this)(i,j);
3721 }
3723 //*************************************************************************************************
3724 
3725 
3726 //*************************************************************************************************
3733 template< typename Type > // Data type of the matrix
3735  CompressedMatrix<Type,true>::begin( size_t j ) noexcept
3736 {
3737  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3738  return begin_[j];
3739 }
3741 //*************************************************************************************************
3742 
3743 
3744 //*************************************************************************************************
3751 template< typename Type > // Data type of the matrix
3753  CompressedMatrix<Type,true>::begin( size_t j ) const noexcept
3754 {
3755  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3756  return begin_[j];
3757 }
3759 //*************************************************************************************************
3760 
3761 
3762 //*************************************************************************************************
3769 template< typename Type > // Data type of the matrix
3771  CompressedMatrix<Type,true>::cbegin( size_t j ) const noexcept
3772 {
3773  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3774  return begin_[j];
3775 }
3777 //*************************************************************************************************
3778 
3779 
3780 //*************************************************************************************************
3787 template< typename Type > // Data type of the matrix
3789  CompressedMatrix<Type,true>::end( size_t j ) noexcept
3790 {
3791  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3792  return end_[j];
3793 }
3795 //*************************************************************************************************
3796 
3797 
3798 //*************************************************************************************************
3805 template< typename Type > // Data type of the matrix
3807  CompressedMatrix<Type,true>::end( size_t j ) const noexcept
3808 {
3809  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3810  return end_[j];
3811 }
3813 //*************************************************************************************************
3814 
3815 
3816 //*************************************************************************************************
3823 template< typename Type > // Data type of the matrix
3825  CompressedMatrix<Type,true>::cend( size_t j ) const noexcept
3826 {
3827  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3828  return end_[j];
3829 }
3831 //*************************************************************************************************
3832 
3833 
3834 
3835 
3836 //=================================================================================================
3837 //
3838 // ASSIGNMENT OPERATORS
3839 //
3840 //=================================================================================================
3841 
3842 //*************************************************************************************************
3864 template< typename Type > // Data type of the matrix
3865 inline CompressedMatrix<Type,true>&
3866  CompressedMatrix<Type,true>::operator=( initializer_list< initializer_list<Type> > list )
3867 {
3868  using blaze::nonZeros;
3869 
3870  resize( list.size(), determineColumns( list ), false );
3871  reserve( nonZeros( list ) );
3872 
3873  for( size_t j=0UL; j<n_; ++j )
3874  {
3875  size_t i( 0UL );
3876 
3877  for( const auto& rowList : list )
3878  {
3879  if( rowList.size() <= j ) {
3880  ++i;
3881  continue;
3882  }
3883 
3884  auto pos( rowList.begin() );
3885  std::advance( pos, j );
3886  if( !isDefault<strict>( *pos ) )
3887  append( i, j, *pos );
3888  ++i;
3889  }
3890 
3891  finalize( j );
3892  }
3893 
3894  return *this;
3895 }
3897 //*************************************************************************************************
3898 
3899 
3900 //*************************************************************************************************
3910 template< typename Type > // Data type of the matrix
3911 inline CompressedMatrix<Type,true>&
3912  CompressedMatrix<Type,true>::operator=( const CompressedMatrix& rhs )
3913 {
3914  using std::swap;
3915 
3916  if( &rhs == this ) return *this;
3917 
3918  const size_t nonzeros( rhs.nonZeros() );
3919 
3920  if( rhs.n_ > capacity_ || nonzeros > capacity() )
3921  {
3922  Iterator* newBegin( new Iterator[2UL*rhs.n_+2UL] );
3923  Iterator* newEnd ( newBegin+(rhs.n_+1UL) );
3924 
3925  newBegin[0UL] = allocate<Element>( nonzeros );
3926  for( size_t j=0UL; j<rhs.n_; ++j ) {
3927  newEnd[j] = castDown( std::copy( rhs.begin_[j], rhs.end_[j], castUp( newBegin[j] ) ) );
3928  newBegin[j+1UL] = newEnd[j];
3929  }
3930  newEnd[rhs.n_] = newBegin[0UL]+nonzeros;
3931 
3932  swap( begin_, newBegin );
3933  end_ = newEnd;
3934  capacity_ = rhs.n_;
3935 
3936  if( newBegin != nullptr ) {
3937  deallocate( newBegin[0UL] );
3938  delete[] newBegin;
3939  }
3940  }
3941  else {
3942  for( size_t j=0UL; j<rhs.n_; ++j ) {
3943  end_[j] = castDown( std::copy( rhs.begin_[j], rhs.end_[j], castUp( begin_[j] ) ) );
3944  begin_[j+1UL] = end_[j];
3945  }
3946  }
3947 
3948  m_ = rhs.m_;
3949  n_ = rhs.n_;
3950 
3951  return *this;
3952 }
3954 //*************************************************************************************************
3955 
3956 
3957 //*************************************************************************************************
3964 template< typename Type > // Data type of the matrix
3965 inline CompressedMatrix<Type,true>&
3966  CompressedMatrix<Type,true>::operator=( CompressedMatrix&& rhs ) noexcept
3967 {
3968  if( begin_ != nullptr ) {
3969  deallocate( begin_[0UL] );
3970  delete[] begin_;
3971  }
3972 
3973  m_ = rhs.m_;
3974  n_ = rhs.n_;
3975  capacity_ = rhs.capacity_;
3976  begin_ = rhs.begin_;
3977  end_ = rhs.end_;
3978 
3979  rhs.m_ = 0UL;
3980  rhs.n_ = 0UL;
3981  rhs.capacity_ = 0UL;
3982  rhs.begin_ = nullptr;
3983  rhs.end_ = nullptr;
3984 
3985  return *this;
3986 }
3988 //*************************************************************************************************
3989 
3990 
3991 //*************************************************************************************************
4001 template< typename Type > // Data type of the matrix
4002 template< typename MT // Type of the right-hand side dense matrix
4003  , bool SO > // Storage order of the right-hand side dense matrix
4004 inline CompressedMatrix<Type,true>&
4005  CompressedMatrix<Type,true>::operator=( const DenseMatrix<MT,SO>& rhs )
4006 {
4007  using blaze::assign;
4008 
4009  if( (~rhs).canAlias( this ) ) {
4010  CompressedMatrix tmp( ~rhs );
4011  swap( tmp );
4012  }
4013  else {
4014  resize( (~rhs).rows(), (~rhs).columns(), false );
4015  assign( *this, ~rhs );
4016  }
4017 
4018  return *this;
4019 }
4021 //*************************************************************************************************
4022 
4023 
4024 //*************************************************************************************************
4034 template< typename Type > // Data type of the matrix
4035 template< typename MT // Type of the right-hand side compressed matrix
4036  , bool SO > // Storage order of the right-hand side compressed matrix
4037 inline CompressedMatrix<Type,true>&
4038  CompressedMatrix<Type,true>::operator=( const SparseMatrix<MT,SO>& rhs )
4039 {
4040  using blaze::assign;
4041 
4042  if( (~rhs).canAlias( this ) ||
4043  (~rhs).columns() > capacity_ ||
4044  (~rhs).nonZeros() > capacity() ) {
4045  CompressedMatrix tmp( ~rhs );
4046  swap( tmp );
4047  }
4048  else {
4049  resize( (~rhs).rows(), (~rhs).columns(), false );
4050  reset();
4051  assign( *this, ~rhs );
4052  }
4053 
4054  return *this;
4055 }
4057 //*************************************************************************************************
4058 
4059 
4060 //*************************************************************************************************
4071 template< typename Type > // Data type of the matrix
4072 template< typename MT // Type of the right-hand side matrix
4073  , bool SO > // Storage order of the right-hand side matrix
4074 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator+=( const Matrix<MT,SO>& rhs )
4075 {
4076  using blaze::addAssign;
4077 
4078  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4079  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4080  }
4081 
4082  addAssign( *this, ~rhs );
4083  return *this;
4084 }
4086 //*************************************************************************************************
4087 
4088 
4089 //*************************************************************************************************
4100 template< typename Type > // Data type of the matrix
4101 template< typename MT // Type of the right-hand side matrix
4102  , bool SO > // Storage order of the right-hand side matrix
4103 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::operator-=( const Matrix<MT,SO>& rhs )
4104 {
4105  using blaze::subAssign;
4106 
4107  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4108  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4109  }
4110 
4111  subAssign( *this, ~rhs );
4112  return *this;
4113 }
4115 //*************************************************************************************************
4116 
4117 
4118 //*************************************************************************************************
4130 template< typename Type > // Data type of the matrix
4131 template< typename MT // Type of the right-hand side dense matrix
4132  , bool SO > // Storage order of the right-hand side dense matrix
4133 inline CompressedMatrix<Type,true>&
4134  CompressedMatrix<Type,true>::operator%=( const DenseMatrix<MT,SO>& rhs )
4135 {
4136  using blaze::schurAssign;
4137 
4138  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4139  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4140  }
4141 
4142  if( (~rhs).canAlias( this ) ) {
4143  CompressedMatrix tmp( *this % (~rhs) );
4144  swap( tmp );
4145  }
4146  else {
4147  CompositeType_t<MT> tmp( ~rhs );
4148  schurAssign( *this, tmp );
4149  }
4150 
4151  return *this;
4152 }
4154 //*************************************************************************************************
4155 
4156 
4157 //*************************************************************************************************
4169 template< typename Type > // Data type of the matrix
4170 template< typename MT // Type of the right-hand side sparse matrix
4171  , bool SO > // Storage order of the right-hand side sparse matrix
4172 inline CompressedMatrix<Type,true>&
4173  CompressedMatrix<Type,true>::operator%=( const SparseMatrix<MT,SO>& rhs )
4174 {
4175  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4176  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4177  }
4178 
4179  CompressedMatrix tmp( *this % (~rhs) );
4180  swap( tmp );
4181 
4182  return *this;
4183 }
4185 //*************************************************************************************************
4186 
4187 
4188 
4189 
4190 //=================================================================================================
4191 //
4192 // UTILITY FUNCTIONS
4193 //
4194 //=================================================================================================
4195 
4196 //*************************************************************************************************
4202 template< typename Type > // Data type of the matrix
4203 inline size_t CompressedMatrix<Type,true>::rows() const noexcept
4204 {
4205  return m_;
4206 }
4208 //*************************************************************************************************
4209 
4210 
4211 //*************************************************************************************************
4217 template< typename Type > // Data type of the matrix
4218 inline size_t CompressedMatrix<Type,true>::columns() const noexcept
4219 {
4220  return n_;
4221 }
4223 //*************************************************************************************************
4224 
4225 
4226 //*************************************************************************************************
4232 template< typename Type > // Data type of the matrix
4233 inline size_t CompressedMatrix<Type,true>::capacity() const noexcept
4234 {
4235  if( begin_ != nullptr )
4236  return end_[n_] - begin_[0UL];
4237  else return 0UL;
4238 }
4240 //*************************************************************************************************
4241 
4242 
4243 //*************************************************************************************************
4250 template< typename Type > // Data type of the matrix
4251 inline size_t CompressedMatrix<Type,true>::capacity( size_t j ) const noexcept
4252 {
4253  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4254  return begin_[j+1UL] - begin_[j];
4255 }
4257 //*************************************************************************************************
4258 
4259 
4260 //*************************************************************************************************
4266 template< typename Type > // Data type of the matrix
4267 inline size_t CompressedMatrix<Type,true>::nonZeros() const
4268 {
4269  size_t nonzeros( 0UL );
4270 
4271  for( size_t j=0UL; j<n_; ++j )
4272  nonzeros += nonZeros( j );
4273 
4274  return nonzeros;
4275 }
4277 //*************************************************************************************************
4278 
4279 
4280 //*************************************************************************************************
4287 template< typename Type > // Data type of the matrix
4288 inline size_t CompressedMatrix<Type,true>::nonZeros( size_t j ) const
4289 {
4290  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4291  return end_[j] - begin_[j];
4292 }
4294 //*************************************************************************************************
4295 
4296 
4297 //*************************************************************************************************
4303 template< typename Type > // Data type of the matrix
4305 {
4306  for( size_t j=0UL; j<n_; ++j )
4307  end_[j] = begin_[j];
4308 }
4310 //*************************************************************************************************
4311 
4312 
4313 //*************************************************************************************************
4323 template< typename Type > // Data type of the matrix
4324 inline void CompressedMatrix<Type,true>::reset( size_t j )
4325 {
4326  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4327  end_[j] = begin_[j];
4328 }
4330 //*************************************************************************************************
4331 
4332 
4333 //*************************************************************************************************
4341 template< typename Type > // Data type of the matrix
4343 {
4344  if( end_ != nullptr )
4345  end_[0UL] = end_[n_];
4346  m_ = 0UL;
4347  n_ = 0UL;
4348 }
4350 //*************************************************************************************************
4351 
4352 
4353 //*************************************************************************************************
4369 template< typename Type > // Data type of the matrix
4370 void CompressedMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
4371 {
4372  using std::swap;
4373 
4374  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4375  BLAZE_INTERNAL_ASSERT( begin_ == nullptr || size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4376 
4377  if( m == m_ && n == n_ ) return;
4378 
4379  if( begin_ == nullptr )
4380  {
4381  begin_ = new Iterator[2UL*n+2UL];
4382  end_ = begin_+n+1UL;
4383 
4384  for( size_t j=0UL; j<2UL*n+2UL; ++j ) {
4385  begin_[j] = nullptr;
4386  }
4387 
4388  capacity_ = n;
4389  }
4390  else if( n > capacity_ )
4391  {
4392  Iterator* newBegin( new Iterator[2UL*n+2UL] );
4393  Iterator* newEnd ( newBegin+n+1UL );
4394 
4395  newBegin[0UL] = begin_[0UL];
4396 
4397  if( preserve ) {
4398  for( size_t j=0UL; j<n_; ++j ) {
4399  newEnd [j] = end_ [j];
4400  newBegin[j+1UL] = begin_[j+1UL];
4401  }
4402  for( size_t j=n_; j<n; ++j ) {
4403  newBegin[j+1UL] = newEnd[j] = begin_[n_];
4404  }
4405  }
4406  else {
4407  for( size_t j=0UL; j<n; ++j ) {
4408  newBegin[j+1UL] = newEnd[j] = begin_[0UL];
4409  }
4410  }
4411 
4412  newEnd[n] = end_[n_];
4413 
4414  swap( newBegin, begin_ );
4415  delete[] newBegin;
4416  end_ = newEnd;
4417  capacity_ = n;
4418  }
4419  else if( n > n_ )
4420  {
4421  end_[n] = end_[n_];
4422 
4423  if( !preserve ) {
4424  for( size_t j=0UL; j<n_; ++j )
4425  end_[j] = begin_[j];
4426  }
4427 
4428  for( size_t j=n_; j<n; ++j ) {
4429  begin_[j+1UL] = end_[j] = begin_[n_];
4430  }
4431  }
4432  else
4433  {
4434  if( preserve ) {
4435  for( size_t j=0UL; j<n; ++j )
4436  end_[j] = lowerBound( m, j );
4437  }
4438  else {
4439  for( size_t j=0UL; j<n; ++j )
4440  end_[j] = begin_[j];
4441  }
4442 
4443  end_[n] = end_[n_];
4444  }
4445 
4446  m_ = m;
4447  n_ = n;
4448 
4449  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4450  BLAZE_INTERNAL_ASSERT( size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4451 }
4453 //*************************************************************************************************
4454 
4455 
4456 //*************************************************************************************************
4467 template< typename Type > // Data type of the matrix
4468 inline void CompressedMatrix<Type,true>::reserve( size_t nonzeros )
4469 {
4470  if( nonzeros > capacity() )
4471  reserveElements( nonzeros );
4472 }
4474 //*************************************************************************************************
4475 
4476 
4477 //*************************************************************************************************
4489 template< typename Type > // Data type of the matrix
4490 void CompressedMatrix<Type,true>::reserve( size_t j, size_t nonzeros )
4491 {
4492  using std::swap;
4493 
4494  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4495 
4496  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4497  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4498 
4499  const size_t current( capacity(j) );
4500 
4501  if( current >= nonzeros ) return;
4502 
4503  const ptrdiff_t additional( nonzeros - current );
4504 
4505  if( end_[n_] - begin_[n_] < additional )
4506  {
4507  const size_t newCapacity( begin_[n_] - begin_[0UL] + additional );
4508  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
4509 
4510  Iterator* newBegin( new Iterator[2UL*n_+2UL] );
4511  Iterator* newEnd ( newBegin+n_+1UL );
4512 
4513  newBegin[0UL] = allocate<Element>( newCapacity );
4514  newEnd [n_ ] = newBegin[0UL]+newCapacity;
4515 
4516  for( size_t k=0UL; k<j; ++k ) {
4517  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4518  newBegin[k+1UL] = newBegin[k] + capacity(k);
4519  }
4520  newEnd [j ] = castDown( transfer( begin_[j], end_[j], castUp( newBegin[j] ) ) );
4521  newBegin[j+1UL] = newBegin[j] + nonzeros;
4522  for( size_t k=j+1UL; k<n_; ++k ) {
4523  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4524  newBegin[k+1UL] = newBegin[k] + capacity(k);
4525  }
4526 
4527  BLAZE_INTERNAL_ASSERT( newBegin[n_] == newEnd[n_], "Invalid pointer calculations" );
4528 
4529  swap( newBegin, begin_ );
4530  deallocate( newBegin[0UL] );
4531  delete[] newBegin;
4532  end_ = newEnd;
4533  capacity_ = n_;
4534  }
4535  else
4536  {
4537  begin_[n_] += additional;
4538  for( size_t k=n_-1UL; k>j; --k ) {
4539  begin_[k] = castDown( std::move_backward( begin_[k], end_[k], castUp( end_[k]+additional ) ) );
4540  end_ [k] += additional;
4541  }
4542  }
4543 
4544  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4545  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4546 }
4548 //*************************************************************************************************
4549 
4550 
4551 //*************************************************************************************************
4561 template< typename Type > // Data type of the matrix
4562 void CompressedMatrix<Type,true>::trim()
4563 {
4564  for( size_t j=0UL; j<n_; ++j )
4565  trim( j );
4566 }
4568 //*************************************************************************************************
4569 
4570 
4571 //*************************************************************************************************
4582 template< typename Type > // Data type of the matrix
4583 void CompressedMatrix<Type,true>::trim( size_t j )
4584 {
4585  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4586 
4587  if( j < ( n_ - 1UL ) )
4588  end_[j+1] = castDown( std::move( begin_[j+1], end_[j+1], castUp( end_[j] ) ) );
4589  begin_[j+1] = end_[j];
4590 }
4592 //*************************************************************************************************
4593 
4594 
4595 //*************************************************************************************************
4605 template< typename Type > // Data type of the matrix
4606 inline void CompressedMatrix<Type,true>::shrinkToFit()
4607 {
4608  if( nonZeros() < capacity() ) {
4609  CompressedMatrix( *this ).swap( *this );
4610  }
4611 }
4613 //*************************************************************************************************
4614 
4615 
4616 //*************************************************************************************************
4623 template< typename Type > // Data type of the matrix
4624 inline void CompressedMatrix<Type,true>::swap( CompressedMatrix& sm ) noexcept
4625 {
4626  using std::swap;
4627 
4628  swap( m_, sm.m_ );
4629  swap( n_, sm.n_ );
4630  swap( capacity_, sm.capacity_ );
4631  swap( begin_, sm.begin_ );
4632  swap( end_ , sm.end_ );
4633 }
4635 //*************************************************************************************************
4636 
4637 
4638 //*************************************************************************************************
4647 template< typename Type > // Data type of the matrix
4648 inline size_t CompressedMatrix<Type,true>::extendCapacity() const noexcept
4649 {
4650  size_t nonzeros( 2UL*capacity()+1UL );
4651  nonzeros = blaze::max( nonzeros, 7UL );
4652 
4653  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
4654 
4655  return nonzeros;
4656 }
4658 //*************************************************************************************************
4659 
4660 
4661 //*************************************************************************************************
4668 template< typename Type > // Data type of the matrix
4669 void CompressedMatrix<Type,true>::reserveElements( size_t nonzeros )
4670 {
4671  using std::swap;
4672 
4673  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
4674  Iterator* newEnd = newBegin+capacity_+1UL;
4675 
4676  newBegin[0UL] = allocate<Element>( nonzeros );
4677 
4678  for( size_t k=0UL; k<n_; ++k ) {
4679  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid column pointers" );
4680  newEnd [k] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4681  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
4682  }
4683 
4684  newEnd[n_] = newBegin[0UL]+nonzeros;
4685 
4686  swap( newBegin, begin_ );
4687  end_ = newEnd;
4688 
4689  if( newBegin != nullptr ) {
4690  deallocate( newBegin[0UL] );
4691  delete[] newBegin;
4692  }
4693 }
4695 //*************************************************************************************************
4696 
4697 
4698 //*************************************************************************************************
4706 template< typename Type > // Data type of the matrix
4708  CompressedMatrix<Type,true>::castDown( IteratorBase it ) const noexcept
4709 {
4710  return static_cast<Iterator>( it );
4711 }
4712 //*************************************************************************************************
4713 
4714 
4715 //*************************************************************************************************
4723 template< typename Type > // Data type of the matrix
4724 inline typename CompressedMatrix<Type,true>::IteratorBase
4725  CompressedMatrix<Type,true>::castUp( Iterator it ) const noexcept
4726 {
4727  return static_cast<IteratorBase>( it );
4728 }
4729 //*************************************************************************************************
4730 
4731 
4732 
4733 
4734 //=================================================================================================
4735 //
4736 // INSERTION FUNCTIONS
4737 //
4738 //=================================================================================================
4739 
4740 //*************************************************************************************************
4753 template< typename Type > // Data type of the matrix
4755  CompressedMatrix<Type,true>::set( size_t i, size_t j, const Type& value )
4756 {
4757  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4758  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4759 
4760  const Iterator pos( lowerBound( i, j ) );
4761 
4762  if( pos != end_[j] && pos->index_ == i ) {
4763  pos->value() = value;
4764  return pos;
4765  }
4766  else return insert( pos, i, j, value );
4767 }
4769 //*************************************************************************************************
4770 
4771 
4772 //*************************************************************************************************
4786 template< typename Type > // Data type of the matrix
4788  CompressedMatrix<Type,true>::insert( size_t i, size_t j, const Type& value )
4789 {
4790  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4791  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4792 
4793  const Iterator pos( lowerBound( i, j ) );
4794 
4795  if( pos != end_[j] && pos->index_ == i ) {
4796  BLAZE_THROW_INVALID_ARGUMENT( "Bad access index" );
4797  }
4798 
4799  return insert( pos, i, j, value );
4800 }
4802 //*************************************************************************************************
4803 
4804 
4805 //*************************************************************************************************
4816 template< typename Type > // Data type of the matrix
4818  CompressedMatrix<Type,true>::insert( Iterator pos, size_t i, size_t j, const Type& value )
4819 {
4820  using std::swap;
4821 
4822  if( begin_[j+1UL] - end_[j] != 0 ) {
4823  std::move_backward( pos, end_[j], castUp( end_[j]+1UL ) );
4824  pos->value_ = value;
4825  pos->index_ = i;
4826  ++end_[j];
4827 
4828  return pos;
4829  }
4830  else if( end_[n_] - begin_[n_] != 0 ) {
4831  std::move_backward( pos, end_[n_-1UL], castUp( end_[n_-1]+1UL ) );
4832 
4833  pos->value_ = value;
4834  pos->index_ = i;
4835 
4836  for( size_t k=j+1UL; k<n_+1UL; ++k ) {
4837  ++begin_[k];
4838  ++end_[k-1UL];
4839  }
4840 
4841  return pos;
4842  }
4843  else {
4844  size_t newCapacity( extendCapacity() );
4845 
4846  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
4847  Iterator* newEnd = newBegin+capacity_+1UL;
4848 
4849  newBegin[0UL] = allocate<Element>( newCapacity );
4850 
4851  for( size_t k=0UL; k<j; ++k ) {
4852  const size_t nonzeros( end_[k] - begin_[k] );
4853  const size_t total( begin_[k+1UL] - begin_[k] );
4854  newEnd [k] = newBegin[k] + nonzeros;
4855  newBegin[k+1UL] = newBegin[k] + total;
4856  }
4857  newEnd [j] = newBegin[j] + ( end_[j] - begin_[j] ) + 1;
4858  newBegin[j+1UL] = newBegin[j] + ( begin_[j+1UL] - begin_[j] ) + 1;
4859  for( size_t k=j+1UL; k<n_; ++k ) {
4860  const size_t nonzeros( end_[k] - begin_[k] );
4861  const size_t total( begin_[k+1UL] - begin_[k] );
4862  newEnd [k] = newBegin[k] + nonzeros;
4863  newBegin[k+1UL] = newBegin[k] + total;
4864  }
4865 
4866  newEnd[n_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
4867 
4868  Iterator tmp = castDown( std::move( begin_[0UL], pos, castUp( newBegin[0UL] ) ) );
4869  tmp->value_ = value;
4870  tmp->index_ = i;
4871  std::move( pos, end_[n_-1UL], castUp( tmp+1UL ) );
4872 
4873  swap( newBegin, begin_ );
4874  end_ = newEnd;
4875  deallocate( newBegin[0UL] );
4876  delete[] newBegin;
4877 
4878  return tmp;
4879  }
4880 }
4882 //*************************************************************************************************
4883 
4884 
4885 //*************************************************************************************************
4938 template< typename Type > // Data type of the matrix
4939 inline void CompressedMatrix<Type,true>::append( size_t i, size_t j, const Type& value, bool check )
4940 {
4941  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
4942  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
4943  BLAZE_USER_ASSERT( end_[j] < end_[n_], "Not enough reserved capacity left" );
4944  BLAZE_USER_ASSERT( begin_[j] == end_[j] || i > ( end_[j]-1UL )->index_, "Index is not strictly increasing" );
4945 
4946  end_[j]->value_ = value;
4947 
4948  if( !check || !isDefault<strict>( end_[j]->value_ ) ) {
4949  end_[j]->index_ = i;
4950  ++end_[j];
4951  }
4952 }
4954 //*************************************************************************************************
4955 
4956 
4957 //*************************************************************************************************
4971 template< typename Type > // Data type of the matrix
4972 inline void CompressedMatrix<Type,true>::finalize( size_t j )
4973 {
4974  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
4975 
4976  begin_[j+1UL] = end_[j];
4977  if( j != n_-1UL )
4978  end_[j+1UL] = end_[j];
4979 }
4981 //*************************************************************************************************
4982 
4983 
4984 
4985 
4986 //=================================================================================================
4987 //
4988 // ERASE FUNCTIONS
4989 //
4990 //=================================================================================================
4991 
4992 //*************************************************************************************************
5002 template< typename Type > // Data type of the matrix
5003 inline void CompressedMatrix<Type,true>::erase( size_t i, size_t j )
5004 {
5005  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
5006  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5007 
5008  const Iterator pos( find( i, j ) );
5009  if( pos != end_[j] )
5010  end_[j] = castDown( std::move( pos+1, end_[j], castUp( pos ) ) );
5011 }
5013 //*************************************************************************************************
5014 
5015 
5016 //*************************************************************************************************
5026 template< typename Type > // Data type of the matrix
5028  CompressedMatrix<Type,true>::erase( size_t j, Iterator pos )
5029 {
5030  BLAZE_USER_ASSERT( j < columns() , "Invalid column access index" );
5031  BLAZE_USER_ASSERT( pos >= begin_[j] && pos <= end_[j], "Invalid compressed matrix iterator" );
5032 
5033  if( pos != end_[j] )
5034  end_[j] = castDown( std::move( pos+1, end_[j], castUp( pos ) ) );
5035 
5036  return pos;
5037 }
5039 //*************************************************************************************************
5040 
5041 
5042 //*************************************************************************************************
5053 template< typename Type > // Data type of the matrix
5055  CompressedMatrix<Type,true>::erase( size_t j, Iterator first, Iterator last )
5056 {
5057  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5058  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
5059  BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j], "Invalid compressed matrix iterator" );
5060  BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j], "Invalid compressed matrix iterator" );
5061 
5062  if( first != last )
5063  end_[j] = castDown( std::move( last, end_[j], castUp( first ) ) );
5064 
5065  return first;
5066 }
5068 //*************************************************************************************************
5069 
5070 
5071 //*************************************************************************************************
5093 template< typename Type > // Data type of the matrix
5094 template< typename Pred > // Type of the unary predicate
5095 inline void CompressedMatrix<Type,true>::erase( Pred predicate )
5096 {
5097  for( size_t j=0UL; j<n_; ++j ) {
5098  end_[j] = castDown( std::remove_if( castUp( begin_[j] ), castUp( end_[j] ),
5099  [predicate=predicate]( const ElementBase& element ) {
5100  return predicate( element.value() );
5101  } ) );
5102  }
5103 }
5105 //*************************************************************************************************
5106 
5107 
5108 //*************************************************************************************************
5133 template< typename Type > // Data type of the matrix
5134 template< typename Pred > // Type of the unary predicate
5135 inline void CompressedMatrix<Type,true>::erase( size_t j, Iterator first, Iterator last, Pred predicate )
5136 {
5137  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5138  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
5139  BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j], "Invalid compressed matrix iterator" );
5140  BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j], "Invalid compressed matrix iterator" );
5141 
5142  const auto pos = std::remove_if( castUp( first ), castUp( last ),
5143  [predicate=predicate]( const ElementBase& element ) {
5144  return predicate( element.value() );
5145  } );
5146 
5147  end_[j] = castDown( std::move( last, end_[j], pos ) );
5148 }
5150 //*************************************************************************************************
5151 
5152 
5153 
5154 
5155 //=================================================================================================
5156 //
5157 // LOOKUP FUNCTIONS
5158 //
5159 //=================================================================================================
5160 
5161 //*************************************************************************************************
5176 template< typename Type > // Data type of the matrix
5178  CompressedMatrix<Type,true>::find( size_t i, size_t j )
5179 {
5180  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
5181 }
5183 //*************************************************************************************************
5184 
5185 
5186 //*************************************************************************************************
5201 template< typename Type > // Data type of the matrix
5203  CompressedMatrix<Type,true>::find( size_t i, size_t j ) const
5204 {
5205  const ConstIterator pos( lowerBound( i, j ) );
5206  if( pos != end_[j] && pos->index_ == i )
5207  return pos;
5208  else return end_[j];
5209 }
5211 //*************************************************************************************************
5212 
5213 
5214 //*************************************************************************************************
5228 template< typename Type > // Data type of the matrix
5230  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j )
5231 {
5232  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
5233 }
5235 //*************************************************************************************************
5236 
5237 
5238 //*************************************************************************************************
5252 template< typename Type > // Data type of the matrix
5254  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j ) const
5255 {
5256  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5257  return std::lower_bound( begin_[j], end_[j], i,
5258  []( const Element& element, size_t index )
5259  {
5260  return element.index() < index;
5261  } );
5262 }
5264 //*************************************************************************************************
5265 
5266 
5267 //*************************************************************************************************
5281 template< typename Type > // Data type of the matrix
5283  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j )
5284 {
5285  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
5286 }
5288 //*************************************************************************************************
5289 
5290 
5291 //*************************************************************************************************
5305 template< typename Type > // Data type of the matrix
5307  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j ) const
5308 {
5309  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5310  return std::upper_bound( begin_[j], end_[j], i,
5311  []( size_t index, const Element& element )
5312  {
5313  return index < element.index();
5314  } );
5315 }
5317 //*************************************************************************************************
5318 
5319 
5320 
5321 
5322 //=================================================================================================
5323 //
5324 // NUMERIC FUNCTIONS
5325 //
5326 //=================================================================================================
5327 
5328 //*************************************************************************************************
5334 template< typename Type > // Data type of the matrix
5335 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::transpose()
5336 {
5337  CompressedMatrix tmp( trans( *this ) );
5338  swap( tmp );
5339  return *this;
5340 }
5342 //*************************************************************************************************
5343 
5344 
5345 //*************************************************************************************************
5351 template< typename Type > // Data type of the matrix
5352 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::ctranspose()
5353 {
5354  CompressedMatrix tmp( ctrans( *this ) );
5355  swap( tmp );
5356  return *this;
5357 }
5359 //*************************************************************************************************
5360 
5361 
5362 //*************************************************************************************************
5380 template< typename Type > // Data type of the matrix
5381 template< typename Other > // Data type of the scalar value
5382 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scale( const Other& scalar )
5383 {
5384  for( size_t j=0UL; j<n_; ++j )
5385  for( auto element=begin_[j]; element!=end_[j]; ++element )
5386  element->value_ *= scalar;
5387 
5388  return *this;
5389 }
5391 //*************************************************************************************************
5392 
5393 
5394 
5395 
5396 //=================================================================================================
5397 //
5398 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5399 //
5400 //=================================================================================================
5401 
5402 //*************************************************************************************************
5413 template< typename Type > // Data type of the matrix
5414 template< typename Other > // Data type of the foreign expression
5415 inline bool CompressedMatrix<Type,true>::canAlias( const Other* alias ) const noexcept
5416 {
5417  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5418 }
5420 //*************************************************************************************************
5421 
5422 
5423 //*************************************************************************************************
5434 template< typename Type > // Data type of the matrix
5435 template< typename Other > // Data type of the foreign expression
5436 inline bool CompressedMatrix<Type,true>::isAliased( const Other* alias ) const noexcept
5437 {
5438  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5439 }
5441 //*************************************************************************************************
5442 
5443 
5444 //*************************************************************************************************
5455 template< typename Type > // Data type of the matrix
5456 inline bool CompressedMatrix<Type,true>::canSMPAssign() const noexcept
5457 {
5458  return false;
5459 }
5461 //*************************************************************************************************
5462 
5463 
5464 //*************************************************************************************************
5476 template< typename Type > // Data type of the matrix
5477 template< typename MT // Type of the right-hand side dense matrix
5478  , bool SO > // Storage order of the right-hand side dense matrix
5479 inline void CompressedMatrix<Type,true>::assign( const DenseMatrix<MT,SO>& rhs )
5480 {
5481  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5482  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5483 
5484  if( m_ == 0UL || n_ == 0UL )
5485  return;
5486 
5487  size_t nonzeros( 0UL );
5488 
5489  for( size_t j=1UL; j<=n_; ++j )
5490  begin_[j] = end_[j] = end_[n_];
5491 
5492  for( size_t j=0UL; j<n_; ++j )
5493  {
5494  begin_[j] = end_[j] = begin_[0UL]+nonzeros;
5495 
5496  const size_t ibegin( ( IsLower_v<MT> )
5497  ?( IsStrictlyLower_v<MT> ? j+1UL : j )
5498  :( 0UL ) );
5499  const size_t iend ( ( IsUpper_v<MT> )
5500  ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
5501  :( m_ ) );
5502 
5503  for( size_t i=ibegin; i<iend; ++i )
5504  {
5505  if( nonzeros == capacity() ) {
5506  reserveElements( extendCapacity() );
5507  for( size_t k=j+1UL; k<=n_; ++k )
5508  begin_[k] = end_[k] = end_[n_];
5509  }
5510 
5511  end_[j]->value_ = (~rhs)(i,j);
5512 
5513  if( !isDefault<strict>( end_[j]->value_ ) ) {
5514  end_[j]->index_ = i;
5515  ++end_[j];
5516  ++nonzeros;
5517  }
5518  }
5519  }
5520 
5521  begin_[n_] = begin_[0UL]+nonzeros;
5522 }
5524 //*************************************************************************************************
5525 
5526 
5527 //*************************************************************************************************
5539 template< typename Type > // Data type of the matrix
5540 template< typename MT > // Type of the right-hand side compressed matrix
5541 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,true>& rhs )
5542 {
5543  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5544  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5545  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
5546  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
5547 
5548  if( n_ == 0UL || begin_[0] == nullptr )
5549  return;
5550 
5551  for( size_t j=0UL; j<n_; ++j ) {
5552  end_[j] = castDown( std::copy( (~rhs).begin(j), (~rhs).end(j), castUp( begin_[j] ) ) );
5553  begin_[j+1UL] = end_[j];
5554  }
5555 }
5557 //*************************************************************************************************
5558 
5559 
5560 //*************************************************************************************************
5572 template< typename Type > // Data type of the matrix
5573 template< typename MT > // Type of the right-hand side compressed matrix
5574 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,false>& rhs )
5575 {
5577 
5578  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5579  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5580  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
5581  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
5582 
5583  // Counting the number of elements per column
5584  std::vector<size_t> columnLengths( n_, 0UL );
5585  for( size_t i=0UL; i<m_; ++i ) {
5586  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5587  ++columnLengths[element->index()];
5588  }
5589 
5590  // Resizing the compressed matrix
5591  for( size_t j=0UL; j<n_; ++j ) {
5592  begin_[j+1UL] = end_[j+1UL] = begin_[j] + columnLengths[j];
5593  }
5594 
5595  // Appending the elements to the columns of the compressed matrix
5596  for( size_t i=0UL; i<m_; ++i ) {
5597  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5598  append( i, element->index(), element->value() );
5599  }
5600 }
5602 //*************************************************************************************************
5603 
5604 
5605 //*************************************************************************************************
5617 template< typename Type > // Data type of the matrix
5618 template< typename MT // Type of the right-hand side dense matrix
5619  , bool SO > // Storage order of the right-hand side dense matrix
5620 inline void CompressedMatrix<Type,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
5621 {
5622  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5623  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5624 
5625  CompressedMatrix tmp( serial( *this + (~rhs) ) );
5626  swap( tmp );
5627 }
5629 //*************************************************************************************************
5630 
5631 
5632 //*************************************************************************************************
5644 template< typename Type > // Data type of the matrix
5645 template< typename MT // Type of the right-hand side compressed matrix
5646  , bool SO > // Storage order of the right-hand side compressed matrix
5647 inline void CompressedMatrix<Type,true>::addAssign( const SparseMatrix<MT,SO>& rhs )
5648 {
5649  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5650  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5651 
5652  CompressedMatrix tmp( serial( *this + (~rhs) ) );
5653  swap( tmp );
5654 }
5656 //*************************************************************************************************
5657 
5658 
5659 //*************************************************************************************************
5671 template< typename Type > // Data type of the matrix
5672 template< typename MT // Type of the right-hand side dense matrix
5673  , bool SO > // Storage order of the right-hand side dense matrix
5674 inline void CompressedMatrix<Type,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
5675 {
5676  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5677  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5678 
5679  CompressedMatrix tmp( serial( *this - (~rhs) ) );
5680  swap( tmp );
5681 }
5683 //*************************************************************************************************
5684 
5685 
5686 //*************************************************************************************************
5698 template< typename Type > // Data type of the matrix
5699 template< typename MT // Type of the right-hand side compressed matrix
5700  , bool SO > // Storage order of the right-hand side compressed matrix
5701 inline void CompressedMatrix<Type,true>::subAssign( const SparseMatrix<MT,SO>& rhs )
5702 {
5703  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5704  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5705 
5706  CompressedMatrix tmp( serial( *this - (~rhs) ) );
5707  swap( tmp );
5708 }
5710 //*************************************************************************************************
5711 
5712 
5713 //*************************************************************************************************
5725 template< typename Type > // Data type of the matrix
5726 template< typename MT // Type of the right-hand side dense matrix
5727  , bool SO > // Storage order of the right-hand side dense matrix
5728 inline void CompressedMatrix<Type,true>::schurAssign( const DenseMatrix<MT,SO>& rhs )
5729 {
5730  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5731  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5732 
5734 
5735  for( size_t j=0UL; j<n_; ++j ) {
5736  const Iterator last( end(j) );
5737  for( auto element=begin(j); element!=last; ++element )
5738  element->value_ *= (~rhs)(element->index_,j);
5739  }
5740 }
5742 //*************************************************************************************************
5743 
5744 
5745 
5746 
5747 
5748 
5749 
5750 
5751 //=================================================================================================
5752 //
5753 // COMPRESSEDMATRIX OPERATORS
5754 //
5755 //=================================================================================================
5756 
5757 //*************************************************************************************************
5760 template< typename Type, bool SO >
5761 void reset( CompressedMatrix<Type,SO>& m );
5762 
5763 template< typename Type, bool SO >
5764 void reset( CompressedMatrix<Type,SO>& m, size_t i );
5765 
5766 template< typename Type, bool SO >
5767 void clear( CompressedMatrix<Type,SO>& m );
5768 
5769 template< bool RF, typename Type, bool SO >
5770 bool isDefault( const CompressedMatrix<Type,SO>& m );
5771 
5772 template< typename Type, bool SO >
5773 bool isIntact( const CompressedMatrix<Type,SO>& m );
5774 
5775 template< typename Type, bool SO >
5776 void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) noexcept;
5778 //*************************************************************************************************
5779 
5780 
5781 //*************************************************************************************************
5788 template< typename Type // Data type of the matrix
5789  , bool SO > // Storage order
5790 inline void reset( CompressedMatrix<Type,SO>& m )
5791 {
5792  m.reset();
5793 }
5794 //*************************************************************************************************
5795 
5796 
5797 //*************************************************************************************************
5810 template< typename Type // Data type of the matrix
5811  , bool SO > // Storage order
5812 inline void reset( CompressedMatrix<Type,SO>& m, size_t i )
5813 {
5814  m.reset( i );
5815 }
5816 //*************************************************************************************************
5817 
5818 
5819 //*************************************************************************************************
5826 template< typename Type // Data type of the matrix
5827  , bool SO > // Storage order
5828 inline void clear( CompressedMatrix<Type,SO>& m )
5829 {
5830  m.clear();
5831 }
5832 //*************************************************************************************************
5833 
5834 
5835 //*************************************************************************************************
5860 template< bool RF // Relaxation flag
5861  , typename Type // Data type of the matrix
5862  , bool SO > // Storage order
5863 inline bool isDefault( const CompressedMatrix<Type,SO>& m )
5864 {
5865  return ( m.rows() == 0UL && m.columns() == 0UL );
5866 }
5867 //*************************************************************************************************
5868 
5869 
5870 //*************************************************************************************************
5888 template< typename Type // Data type of the matrix
5889  , bool SO > // Storage order
5890 inline bool isIntact( const CompressedMatrix<Type,SO>& m )
5891 {
5892  return ( m.nonZeros() <= m.capacity() );
5893 }
5894 //*************************************************************************************************
5895 
5896 
5897 //*************************************************************************************************
5905 template< typename Type // Data type of the matrix
5906  , bool SO > // Storage order
5907 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) noexcept
5908 {
5909  a.swap( b );
5910 }
5911 //*************************************************************************************************
5912 
5913 
5914 
5915 
5916 //=================================================================================================
5917 //
5918 // ISRESIZABLE SPECIALIZATIONS
5919 //
5920 //=================================================================================================
5921 
5922 //*************************************************************************************************
5924 template< typename T, bool SO >
5925 struct IsResizable< CompressedMatrix<T,SO> >
5926  : public TrueType
5927 {};
5929 //*************************************************************************************************
5930 
5931 
5932 
5933 
5934 //=================================================================================================
5935 //
5936 // ISSHRINKABLE SPECIALIZATIONS
5937 //
5938 //=================================================================================================
5939 
5940 //*************************************************************************************************
5942 template< typename T, bool SO >
5943 struct IsShrinkable< CompressedMatrix<T,SO> >
5944  : public TrueType
5945 {};
5947 //*************************************************************************************************
5948 
5949 
5950 
5951 
5952 //=================================================================================================
5953 //
5954 // ADDTRAIT SPECIALIZATIONS
5955 //
5956 //=================================================================================================
5957 
5958 //*************************************************************************************************
5960 template< typename T1, typename T2 >
5961 struct AddTraitEval2< T1, T2
5962  , EnableIf_t< IsSparseMatrix_v<T1> && IsSparseMatrix_v<T2> > >
5963 {
5964  using ET1 = ElementType_t<T1>;
5965  using ET2 = ElementType_t<T2>;
5966 
5967  static constexpr bool SO = ( StorageOrder_v<T1> && StorageOrder_v<T2> );
5968 
5969  using Type = CompressedMatrix< AddTrait_t<ET1,ET2>, SO >;
5970 };
5972 //*************************************************************************************************
5973 
5974 
5975 
5976 
5977 //=================================================================================================
5978 //
5979 // SUBTRAIT SPECIALIZATIONS
5980 //
5981 //=================================================================================================
5982 
5983 //*************************************************************************************************
5985 template< typename T1, typename T2 >
5986 struct SubTraitEval2< T1, T2
5987  , EnableIf_t< IsSparseMatrix_v<T1> && IsSparseMatrix_v<T2> > >
5988 {
5989  using ET1 = ElementType_t<T1>;
5990  using ET2 = ElementType_t<T2>;
5991 
5992  static constexpr bool SO = ( StorageOrder_v<T1> && StorageOrder_v<T2> );
5993 
5994  using Type = CompressedMatrix< SubTrait_t<ET1,ET2>, SO >;
5995 };
5997 //*************************************************************************************************
5998 
5999 
6000 
6001 
6002 //=================================================================================================
6003 //
6004 // SCHURTRAIT SPECIALIZATIONS
6005 //
6006 //=================================================================================================
6007 
6008 //*************************************************************************************************
6010 template< typename T1 // Type of the left-hand side operand
6011  , typename T2 > // Type of the right-hand side operand
6012 struct SchurTraitEval2< T1, T2
6013  , EnableIf_t< IsMatrix_v<T1> &&
6014  IsMatrix_v<T2> &&
6015  ( IsSparseMatrix_v<T1> || IsSparseMatrix_v<T2> ) > >
6016 {
6017  using ET1 = ElementType_t<T1>;
6018  using ET2 = ElementType_t<T2>;
6019 
6020  static constexpr bool SO = ( IsSparseMatrix_v<T1> && IsSparseMatrix_v<T2>
6021  ? ( StorageOrder_v<T1> && StorageOrder_v<T2> )
6022  : ( IsSparseMatrix_v<T1>
6023  ? StorageOrder_v<T1>
6024  : StorageOrder_v<T2> ) );
6025 
6026  using Type = CompressedMatrix< MultTrait_t<ET1,ET2>, SO >;
6027 };
6029 //*************************************************************************************************
6030 
6031 
6032 
6033 
6034 //=================================================================================================
6035 //
6036 // MULTTRAIT SPECIALIZATIONS
6037 //
6038 //=================================================================================================
6039 
6040 //*************************************************************************************************
6042 template< typename T1, typename T2 >
6043 struct MultTraitEval2< T1, T2
6044  , EnableIf_t< IsSparseMatrix_v<T1> && IsNumeric_v<T2> > >
6045 {
6046  using ET1 = ElementType_t<T1>;
6047 
6048  using Type = CompressedMatrix< MultTrait_t<ET1,T2>, StorageOrder_v<T1> >;
6049 };
6050 
6051 template< typename T1, typename T2 >
6052 struct MultTraitEval2< T1, T2
6053  , EnableIf_t< IsNumeric_v<T1> && IsSparseMatrix_v<T2> > >
6054 {
6055  using ET2 = ElementType_t<T2>;
6056 
6057  using Type = CompressedMatrix< MultTrait_t<T1,ET2>, StorageOrder_v<T2> >;
6058 };
6059 
6060 template< typename T1, typename T2 >
6061 struct MultTraitEval2< T1, T2
6062  , EnableIf_t< ( IsSparseVector_v<T1> ||
6063  IsSparseVector_v<T2> ) &&
6064  IsColumnVector_v<T1> &&
6065  IsRowVector_v<T2> > >
6066 {
6067  using ET1 = ElementType_t<T1>;
6068  using ET2 = ElementType_t<T2>;
6069 
6070  static constexpr bool SO = ( IsSparseVector_v<T2> ? rowMajor : columnMajor );
6071 
6072  using Type = CompressedMatrix< MultTrait_t<ET1,ET2>, SO >;
6073 };
6074 
6075 template< typename T1, typename T2 >
6076 struct MultTraitEval2< T1, T2
6077  , EnableIf_t< IsSparseMatrix_v<T1> &&
6078  IsSparseMatrix_v<T2> &&
6079  !( IsIdentity_v<T1> && IsIdentity_v<T2> ) > >
6080 {
6081  using ET1 = ElementType_t<T1>;
6082  using ET2 = ElementType_t<T2>;
6083 
6084  using Type = CompressedMatrix< MultTrait_t<ET1,ET2>, StorageOrder_v<T1> >;
6085 };
6087 //*************************************************************************************************
6088 
6089 
6090 
6091 
6092 //=================================================================================================
6093 //
6094 // DIVTRAIT SPECIALIZATIONS
6095 //
6096 //=================================================================================================
6097 
6098 //*************************************************************************************************
6100 template< typename T1, typename T2 >
6101 struct DivTraitEval2< T1, T2
6102  , EnableIf_t< IsSparseMatrix_v<T1> && IsNumeric_v<T2> > >
6103 {
6104  using ET1 = ElementType_t<T1>;
6105 
6106  using Type = CompressedMatrix< DivTrait_t<ET1,T2>, StorageOrder_v<T1> >;
6107 };
6109 //*************************************************************************************************
6110 
6111 
6112 
6113 
6114 //=================================================================================================
6115 //
6116 // MAPTRAIT SPECIALIZATIONS
6117 //
6118 //=================================================================================================
6119 
6120 //*************************************************************************************************
6122 template< typename T, typename OP >
6123 struct UnaryMapTraitEval2< T, OP
6124  , EnableIf_t< IsSparseMatrix_v<T> > >
6125 {
6126  using ET = ElementType_t<T>;
6127 
6128  using Type = CompressedMatrix< MapTrait_t<ET,OP>, StorageOrder_v<T> >;
6129 };
6131 //*************************************************************************************************
6132 
6133 
6134 
6135 
6136 //=================================================================================================
6137 //
6138 // EXPANDTRAIT SPECIALIZATIONS
6139 //
6140 //=================================================================================================
6141 
6142 //*************************************************************************************************
6144 template< typename T // Type to be expanded
6145  , size_t E > // Compile time expansion
6146 struct ExpandTraitEval2< T, E
6147  , EnableIf_t< IsSparseVector_v<T> > >
6148 {
6149  static constexpr bool TF = ( IsColumnVector_v<T> ? columnMajor : rowMajor );
6150 
6151  using Type = CompressedMatrix< ElementType_t<T>, TF >;
6152 };
6154 //*************************************************************************************************
6155 
6156 
6157 
6158 
6159 //=================================================================================================
6160 //
6161 // HIGHTYPE SPECIALIZATIONS
6162 //
6163 //=================================================================================================
6164 
6165 //*************************************************************************************************
6167 template< typename T1, bool SO, typename T2 >
6168 struct HighType< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6169 {
6170  using Type = CompressedMatrix< typename HighType<T1,T2>::Type, SO >;
6171 };
6173 //*************************************************************************************************
6174 
6175 
6176 
6177 
6178 //=================================================================================================
6179 //
6180 // LOWTYPE SPECIALIZATIONS
6181 //
6182 //=================================================================================================
6183 
6184 //*************************************************************************************************
6186 template< typename T1, bool SO, typename T2 >
6187 struct LowType< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6188 {
6189  using Type = CompressedMatrix< typename LowType<T1,T2>::Type, SO >;
6190 };
6192 //*************************************************************************************************
6193 
6194 
6195 
6196 
6197 //=================================================================================================
6198 //
6199 // SUBMATRIXTRAIT SPECIALIZATIONS
6200 //
6201 //=================================================================================================
6202 
6203 //*************************************************************************************************
6205 template< typename MT, size_t I, size_t J, size_t M, size_t N >
6206 struct SubmatrixTraitEval2< MT, I, J, M, N
6207  , EnableIf_t< IsSparseMatrix_v<MT> > >
6208 {
6209  using Type = CompressedMatrix< RemoveConst_t< ElementType_t<MT> >, StorageOrder_v<MT> >;
6210 };
6212 //*************************************************************************************************
6213 
6214 
6215 
6216 
6217 //=================================================================================================
6218 //
6219 // ROWSTRAIT SPECIALIZATIONS
6220 //
6221 //=================================================================================================
6222 
6223 //*************************************************************************************************
6225 template< typename MT, size_t M >
6226 struct RowsTraitEval2< MT, M
6227  , EnableIf_t< IsSparseMatrix_v<MT> > >
6228 {
6229  using Type = CompressedMatrix< RemoveConst_t< ElementType_t<MT> >, false >;
6230 };
6232 //*************************************************************************************************
6233 
6234 
6235 
6236 
6237 //=================================================================================================
6238 //
6239 // COLUMNSTRAIT SPECIALIZATIONS
6240 //
6241 //=================================================================================================
6242 
6243 //*************************************************************************************************
6245 template< typename MT, size_t N >
6246 struct ColumnsTraitEval2< MT, N
6247  , EnableIf_t< IsSparseMatrix_v<MT> > >
6248 {
6249  using Type = CompressedMatrix< RemoveConst_t< ElementType_t<MT> >, true >;
6250 };
6252 //*************************************************************************************************
6253 
6254 } // namespace blaze
6255 
6256 #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:1899
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:532
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:2948
#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
constexpr bool IsSparseMatrix_v
Auxiliary variable template for the IsSparseMatrix type trait.The IsSparseMatrix_v variable template ...
Definition: IsSparseMatrix.h:139
void shrinkToFit()
Requesting the removal of unused capacity.
Definition: CompressedMatrix.h:1839
Header file for the subtraction trait.
bool canSMPAssign() const noexcept
Returns whether the matrix can be used in SMP assignments.
Definition: CompressedMatrix.h:2684
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:546
Header file for basic type definitions.
constexpr bool IsMatrix_v
Auxiliary variable template for the IsMatrix type trait.The IsMatrix_v variable template provides a c...
Definition: IsMatrix.h:139
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: CompressedMatrix.h:2665
CompressedMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: CompressedMatrix.h:2584
Header file for the IsSparseMatrix type trait.
CompressedMatrix()
The default constructor for CompressedMatrix.
Definition: CompressedMatrix.h:576
Header file for the serial shim.
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:224
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: CompressedMatrix.h:352
Iterator end(size_t i) noexcept
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:1025
Reference operator()(size_t i, size_t j) noexcept
2D-access to the compressed matrix elements.
Definition: CompressedMatrix.h:851
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3075
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:591
size_t m_
The current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:3289
void clear()
Clearing the compressed matrix.
Definition: CompressedMatrix.h:1576
Header file for the IsRowVector type trait.
void clear(CompressedMatrix< Type, SO > &m)
Clearing the given compressed matrix.
Definition: CompressedMatrix.h:5828
Header file for the IsIdentity type trait.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3084
#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:817
void reset(CompressedMatrix< Type, SO > &m)
Resetting the given compressed matrix.
Definition: CompressedMatrix.h:5790
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:584
Access proxy for sparse, matrices.The MatrixAccessProxy provides safe access to the elements of a no...
Definition: MatrixAccessProxy.h:101
size_t columns() const noexcept
Returns the current number of columns of the compressed matrix.
Definition: CompressedMatrix.h:1447
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:3085
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:1003
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:534
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
constexpr bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
Resize mechanism to obtain a CompressedMatrix with different fixed dimensions.
Definition: CompressedMatrix.h:3103
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:137
void swap(CompressedMatrix &sm) noexcept
Swapping the contents of two sparse matrices.
Definition: CompressedMatrix.h:1856
Constraint on the data type.
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:3291
Header file for the IsMatrix type trait.
Header file for the SparseMatrix base class.
ElementBase * IteratorBase
Iterator over non-constant base elements.
Definition: CompressedMatrix.h:230
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:530
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.The EnableIf_t alias declaration provides a convenient...
Definition: EnableIf.h:138
void reserve(size_t nonzeros)
Setting the minimum capacity of the compressed matrix.
Definition: CompressedMatrix.h:1700
void reset()
Reset to the default initial values.
Definition: CompressedMatrix.h:1538
constexpr bool columnMajor
Storage order flag for column-major matrices.
Definition: StorageOrder.h:99
Headerfile for the generic max algorithm.
Header file for the ValueIndexPair class.
Header file for the LowType type trait.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3083
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:1364
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5907
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:1986
bool isIntact(const CompressedMatrix< Type, SO > &m)
Returns whether the invariants of the given compressed matrix are intact.
Definition: CompressedMatrix.h:5890
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:3080
Header file for the expand trait.
void erase(size_t i, size_t j)
Erasing an element from the compressed matrix.
Definition: CompressedMatrix.h:2230
Iterator * end_
Pointers one past the last non-zero element of each column.
Definition: CompressedMatrix.h:3293
size_t rows() const noexcept
Returns the current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:1433
#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
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3086
constexpr bool IsNumeric_v
Auxiliary variable template for the IsNumeric type trait.The IsNumeric_v variable template provides a...
Definition: IsNumeric.h:143
size_t capacity() const noexcept
Returns the maximum capacity of the compressed matrix.
Definition: CompressedMatrix.h:1461
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:1069
Constraint on the data type.
CompressedMatrix< Type, SO > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:314
Header file for the IsLower type trait.
constexpr bool IsSparseVector_v
Auxiliary variable template for the IsSparseVector type trait.The IsSparseVector_v variable template ...
Definition: IsSparseVector.h:139
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:1956
Iterator insert(size_t i, size_t j, const Type &value)
Inserting an element into the compressed matrix.
Definition: CompressedMatrix.h:2018
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:320
Header file for the exception macros of the math module.
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1179
void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:738
MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:438
Constraint on the data type.
void subAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the subtraction assignment of a dense matrix.
Definition: CompressedMatrix.h:2896
size_t nonZeros() const
Returns the number of non-zero elements in the compressed matrix.
Definition: CompressedMatrix.h:1498
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
CompressedMatrix & operator=(initializer_list< initializer_list< Type > > list)
List assignment to all matrix elements.
Definition: CompressedMatrix.h:1109
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the compressed matrix.
Definition: CompressedMatrix.h:1603
Header file for the IsNumeric type trait.
Header file for the RemoveConst type trait.
Header file for the IsSparseVector type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, 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:2645
Header file for run time assertion macros.
Header file for the relaxation flag types.
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.The CompositeType_t alias declaration pro...
Definition: Aliases.h:90
Header file for the addition trait.
Resize mechanism to obtain a CompressedMatrix with different fixed dimensions.
Definition: CompressedMatrix.h:342
CompressedMatrix & transpose()
In-place transpose of the matrix.
Definition: CompressedMatrix.h:2568
Header file for the division trait.
void trim()
Removing all excessive capacity from all rows/columns.
Definition: CompressedMatrix.h:1796
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 isDefault shim.
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b) noexcept
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:281
const Type & ConstReference
Reference to a constant compressed matrix value.
Definition: CompressedMatrix.h:323
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:109
constexpr Reference value() noexcept
Access to the current value of the value-index-pair.
Definition: ValueIndexPair.h:370
Constraint on the data type.
Constraint on the data type.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:325
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:808
Iterator * begin_
Pointers to the first non-zero element of each column.
Definition: CompressedMatrix.h:3292
#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:2706
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
void append(size_t i, size_t j, const Type &value, bool check=false)
Appending an element to the specified row/column of the compressed matrix.
Definition: CompressedMatrix.h:2168
void finalize(size_t i)
Finalizing the element insertion of a row/column.
Definition: CompressedMatrix.h:2200
Iterator find(size_t i, size_t j)
Searches for a specific matrix element.
Definition: CompressedMatrix.h:2408
Header file for the rows trait.
Iterator * begin_
Pointers to the first non-zero element of each row.
Definition: CompressedMatrix.h:531
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3081
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
size_t n_
The current number of columns of the compressed matrix.
Definition: CompressedMatrix.h:3290
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:1938
void addAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the addition assignment of a dense matrix.
Definition: CompressedMatrix.h:2844
EnableIf_t< IsBuiltin_v< T > > deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:224
Header file for the default transpose flag for all vectors of the Blaze library.
Initializer list type of the Blaze library.
Iterator lowerBound(size_t i, size_t j)
Returns an iterator to the first index not less than the given index.
Definition: CompressedMatrix.h:2461
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:3295
Iterator upperBound(size_t i, size_t j)
Returns an iterator to the first index greater than the given index.
Definition: CompressedMatrix.h:2516
Header file for the StorageOrder type trait.
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:324
Header file for the map trait.
size_t extendCapacity() const noexcept
Calculating a new matrix capacity.
Definition: CompressedMatrix.h:1879
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:332
bool isDefault(const CompressedMatrix< Type, SO > &m)
Returns whether the given compressed matrix is in default state.
Definition: CompressedMatrix.h:5863
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:3093
Header file for the IsUpper type trait.
size_t n_
The current number of columns of the compressed matrix.
Definition: CompressedMatrix.h:529
Header file for the IsColumnVector type trait.
OutputIterator transfer(InputIterator first, InputIterator last, OutputIterator dest)
Transfers the elements from the given source range to the destination range.
Definition: Transfer.h:70
ValueIndexPair< Type > ElementBase
Base class for the compressed matrix element.
Definition: CompressedMatrix.h:229
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: CompressedMatrix.h:905
Header file for the IsResizable type trait.
size_t m_
The current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:528
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:319
constexpr size_t determineColumns(initializer_list< initializer_list< Type > > list) noexcept
Determines the maximum number of columns specified by the given initializer list. ...
Definition: InitializerList.h:108
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:959