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>
80 #include <blaze/util/Assert.h>
86 #include <blaze/util/EnableIf.h>
87 #include <blaze/util/Memory.h>
88 #include <blaze/util/mpl/And.h>
89 #include <blaze/util/mpl/If.h>
90 #include <blaze/util/mpl/Not.h>
91 #include <blaze/util/Types.h>
94 
95 
96 namespace blaze {
97 
98 //=================================================================================================
99 //
100 // CLASS DEFINITION
101 //
102 //=================================================================================================
103 
104 //*************************************************************************************************
214 template< typename Type // Data type of the matrix
215  , bool SO = defaultStorageOrder > // Storage order
217  : public SparseMatrix< CompressedMatrix<Type,SO>, SO >
218 {
219  private:
220  //**Type definitions****************************************************************************
223  //**********************************************************************************************
224 
225  //**Private class Element***********************************************************************
232  struct Element
233  : public ElementBase
234  {
235  //**Constructors*****************************************************************************
236  explicit Element() = default;
237  Element( const Element& rhs ) = default;
238  Element( Element&& rhs ) = default;
239  //*******************************************************************************************
240 
241  //**Assignment operators*********************************************************************
242  inline Element& operator=( const Element& rhs )
243  {
244  this->value_ = rhs.value_;
245  return *this;
246  }
247 
248  inline Element& operator=( Element&& rhs )
249  {
250  this->value_ = std::move( rhs.value_ );
251  return *this;
252  }
253 
254  template< typename Other >
255  inline EnableIf_< IsSparseElement<Other>, Element& >
256  operator=( const Other& rhs )
257  {
258  this->value_ = rhs.value();
259  return *this;
260  }
261 
262  template< typename Other >
264  , IsRValueReference<Other&&> >, Element& >
265  operator=( Other&& rhs )
266  {
267  this->value_ = std::move( rhs.value() );
268  return *this;
269  }
270 
271  template< typename Other >
272  inline EnableIf_< Not< IsSparseElement<Other> >, Element& >
273  operator=( const Other& v )
274  {
275  this->value_ = v;
276  return *this;
277  }
278 
279  template< typename Other >
281  , IsRValueReference<Other&&> >, Element& >
282  operator=( Other&& v )
283  {
284  this->value_ = std::move( v );
285  return *this;
286  }
287  //*******************************************************************************************
288 
289  //**Friend declarations**********************************************************************
290  friend class CompressedMatrix;
291  //*******************************************************************************************
292  };
294  //**********************************************************************************************
295 
296  public:
297  //**Type definitions****************************************************************************
300  using ResultType = This;
303  using ElementType = Type;
304  using ReturnType = const Type&;
305  using CompositeType = const This&;
307  using ConstReference = const Type&;
308  using Iterator = Element*;
309  using ConstIterator = const Element*;
310  //**********************************************************************************************
311 
312  //**Rebind struct definition********************************************************************
315  template< typename NewType > // Data type of the other matrix
316  struct Rebind {
318  };
319  //**********************************************************************************************
320 
321  //**Resize struct definition********************************************************************
324  template< size_t NewM // Number of rows of the other matrix
325  , size_t NewN > // Number of columns of the other matrix
326  struct Resize {
328  };
329  //**********************************************************************************************
330 
331  //**Compilation flags***************************************************************************
333 
336  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
337  //**********************************************************************************************
338 
339  //**Constructors********************************************************************************
342  explicit inline CompressedMatrix();
343  explicit inline CompressedMatrix( size_t m, size_t n );
344  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
345  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
346  inline CompressedMatrix( const CompressedMatrix& sm );
347  inline CompressedMatrix( CompressedMatrix&& sm ) noexcept;
348  template< typename MT, bool SO2 > inline CompressedMatrix( const DenseMatrix<MT,SO2>& dm );
349  template< typename MT, bool SO2 > inline CompressedMatrix( const SparseMatrix<MT,SO2>& sm );
351  //**********************************************************************************************
352 
353  //**Destructor**********************************************************************************
356  inline ~CompressedMatrix();
358  //**********************************************************************************************
359 
360  //**Data access functions***********************************************************************
363  inline Reference operator()( size_t i, size_t j ) noexcept;
364  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
365  inline Reference at( size_t i, size_t j );
366  inline ConstReference at( size_t i, size_t j ) const;
367  inline Iterator begin ( size_t i ) noexcept;
368  inline ConstIterator begin ( size_t i ) const noexcept;
369  inline ConstIterator cbegin( size_t i ) const noexcept;
370  inline Iterator end ( size_t i ) noexcept;
371  inline ConstIterator end ( size_t i ) const noexcept;
372  inline ConstIterator cend ( size_t i ) const noexcept;
374  //**********************************************************************************************
375 
376  //**Assignment operators************************************************************************
379  inline CompressedMatrix& operator=( const CompressedMatrix& rhs );
380  inline CompressedMatrix& operator=( CompressedMatrix&& rhs ) noexcept;
381 
382  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO2>& rhs );
383  template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO2>& rhs );
384  template< typename MT, bool SO2 > inline CompressedMatrix& operator+=( const Matrix<MT,SO2>& rhs );
385  template< typename MT, bool SO2 > inline CompressedMatrix& operator-=( const Matrix<MT,SO2>& rhs );
386  template< typename MT, bool SO2 > inline CompressedMatrix& operator%=( const DenseMatrix<MT,SO2>& rhs );
387  template< typename MT, bool SO2 > inline CompressedMatrix& operator%=( const SparseMatrix<MT,SO2>& rhs );
388  template< typename MT, bool SO2 > inline CompressedMatrix& operator*=( const Matrix<MT,SO2>& rhs );
389 
390  template< typename Other >
391  inline EnableIf_< IsNumeric<Other>, CompressedMatrix >& operator*=( Other rhs );
392 
393  template< typename Other >
394  inline EnableIf_< IsNumeric<Other>, CompressedMatrix >& operator/=( Other rhs );
396  //**********************************************************************************************
397 
398  //**Utility functions***************************************************************************
401  inline size_t rows() const noexcept;
402  inline size_t columns() const noexcept;
403  inline size_t capacity() const noexcept;
404  inline size_t capacity( size_t i ) const noexcept;
405  inline size_t nonZeros() const;
406  inline size_t nonZeros( size_t i ) const;
407  inline void reset();
408  inline void reset( size_t i );
409  inline void clear();
410  void resize ( size_t m, size_t n, bool preserve=true );
411  inline void reserve( size_t nonzeros );
412  void reserve( size_t i, size_t nonzeros );
413  inline void trim ();
414  inline void trim ( size_t i );
415  inline void shrinkToFit();
416  inline void swap( CompressedMatrix& sm ) noexcept;
418  //**********************************************************************************************
419 
420  //**Insertion functions*************************************************************************
423  inline Iterator set ( size_t i, size_t j, const Type& value );
424  inline Iterator insert ( size_t i, size_t j, const Type& value );
425  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
426  inline void finalize( size_t i );
428  //**********************************************************************************************
429 
430  //**Erase functions*****************************************************************************
433  inline void erase( size_t i, size_t j );
434  inline Iterator erase( size_t i, Iterator pos );
435  inline Iterator erase( size_t i, Iterator first, Iterator last );
436 
437  template< typename Pred >
438  inline void erase( Pred predicate );
439 
440  template< typename Pred >
441  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
443  //**********************************************************************************************
444 
445  //**Lookup functions****************************************************************************
448  inline Iterator find ( size_t i, size_t j );
449  inline ConstIterator find ( size_t i, size_t j ) const;
450  inline Iterator lowerBound( size_t i, size_t j );
451  inline ConstIterator lowerBound( size_t i, size_t j ) const;
452  inline Iterator upperBound( size_t i, size_t j );
453  inline ConstIterator upperBound( size_t i, size_t j ) const;
455  //**********************************************************************************************
456 
457  //**Numeric functions***************************************************************************
460  inline CompressedMatrix& transpose();
461  inline CompressedMatrix& ctranspose();
462 
463  template< typename Other > inline CompressedMatrix& scale( const Other& scalar );
464  template< typename Other > inline CompressedMatrix& scaleDiagonal( const Other& scalar );
466  //**********************************************************************************************
467 
468  //**Expression template evaluation functions****************************************************
471  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
472  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
473 
474  inline bool canSMPAssign() const noexcept;
475 
476  template< typename MT, bool SO2 > inline void assign ( const DenseMatrix<MT,SO2>& rhs );
477  template< typename MT > inline void assign ( const SparseMatrix<MT,SO>& rhs );
478  template< typename MT > inline void assign ( const SparseMatrix<MT,!SO>& rhs );
479  template< typename MT, bool SO2 > inline void addAssign ( const DenseMatrix<MT,SO2>& rhs );
480  template< typename MT, bool SO2 > inline void addAssign ( const SparseMatrix<MT,SO2>& rhs );
481  template< typename MT, bool SO2 > inline void subAssign ( const DenseMatrix<MT,SO2>& rhs );
482  template< typename MT, bool SO2 > inline void subAssign ( const SparseMatrix<MT,SO2>& rhs );
483  template< typename MT, bool SO2 > inline void schurAssign( const DenseMatrix<MT,SO2>& rhs );
485  //**********************************************************************************************
486 
487  private:
488  //**Utility functions***************************************************************************
491  inline size_t extendCapacity() const noexcept;
492  void reserveElements( size_t nonzeros );
493 
494  inline Iterator castDown( IteratorBase it ) const noexcept;
495  inline IteratorBase castUp ( Iterator it ) const noexcept;
497  //**********************************************************************************************
498 
499  //**Insertion functions*************************************************************************
502  Iterator insert( Iterator pos, size_t i, size_t j, const Type& value );
504  //**********************************************************************************************
505 
506  //**Member variables****************************************************************************
509  size_t m_;
510  size_t n_;
511  size_t capacity_;
514 
515  static const Type zero_;
516 
517  //**********************************************************************************************
518 
519  //**Compile time checks*************************************************************************
527  //**********************************************************************************************
528 };
529 //*************************************************************************************************
530 
531 
532 
533 
534 //=================================================================================================
535 //
536 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
537 //
538 //=================================================================================================
539 
540 template< typename Type, bool SO >
541 const Type CompressedMatrix<Type,SO>::zero_ = Type();
542 
543 
544 
545 
546 //=================================================================================================
547 //
548 // CONSTRUCTORS
549 //
550 //=================================================================================================
551 
552 //*************************************************************************************************
555 template< typename Type // Data type of the matrix
556  , bool SO > // Storage order
558  : m_ ( 0UL ) // The current number of rows of the compressed matrix
559  , n_ ( 0UL ) // The current number of columns of the compressed matrix
560  , capacity_( 0UL ) // The current capacity of the pointer array
561  , begin_ ( nullptr ) // Pointers to the first non-zero element of each row
562  , end_ ( nullptr ) // Pointers one past the last non-zero element of each row
563 {}
564 //*************************************************************************************************
565 
566 
567 //*************************************************************************************************
575 template< typename Type // Data type of the matrix
576  , bool SO > // Storage order
578  : m_ ( m ) // The current number of rows of the compressed matrix
579  , n_ ( n ) // The current number of columns of the compressed matrix
580  , capacity_( m ) // The current capacity of the pointer array
581  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
582  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
583 {
584  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
585  begin_[i] = nullptr;
586 }
587 //*************************************************************************************************
588 
589 
590 //*************************************************************************************************
599 template< typename Type // Data type of the matrix
600  , bool SO > // Storage order
601 inline CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
602  : m_ ( m ) // The current number of rows of the compressed matrix
603  , n_ ( n ) // The current number of columns of the compressed matrix
604  , capacity_( m ) // The current capacity of the pointer array
605  , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
606  , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
607 {
608  begin_[0UL] = allocate<Element>( nonzeros );
609  for( size_t i=1UL; i<(2UL*m_+1UL); ++i )
610  begin_[i] = begin_[0UL];
611  end_[m_] = begin_[0UL]+nonzeros;
612 }
613 //*************************************************************************************************
614 
615 
616 //*************************************************************************************************
627 template< typename Type // Data type of the matrix
628  , bool SO > // Storage order
629 CompressedMatrix<Type,SO>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
630  : m_ ( m ) // The current number of rows of the compressed matrix
631  , n_ ( n ) // The current number of columns of the compressed matrix
632  , capacity_( m ) // The current capacity of the pointer array
633  , begin_( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
634  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
635 {
636  BLAZE_USER_ASSERT( nonzeros.size() == m, "Size of capacity vector and number of rows don't match" );
637 
638  size_t newCapacity( 0UL );
639  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
640  newCapacity += *it;
641 
642  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
643  for( size_t i=0UL; i<m_; ++i ) {
644  begin_[i+1UL] = end_[i+1UL] = begin_[i] + nonzeros[i];
645  }
646 }
647 //*************************************************************************************************
648 
649 
650 //*************************************************************************************************
655 template< typename Type // Data type of the matrix
656  , bool SO > // Storage order
658  : m_ ( sm.m_ ) // The current number of rows of the compressed matrix
659  , n_ ( sm.n_ ) // The current number of columns of the compressed matrix
660  , capacity_( sm.m_ ) // The current capacity of the pointer array
661  , begin_( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
662  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
663 {
664  const size_t nonzeros( sm.nonZeros() );
665 
666  begin_[0UL] = allocate<Element>( nonzeros );
667  for( size_t i=0UL; i<m_; ++i ) {
668  end_[i] = castDown( std::copy( sm.begin(i), sm.end(i), castUp( begin_[i] ) ) );
669  begin_[i+1UL] = end_[i];
670  }
671  end_[m_] = begin_[0UL]+nonzeros;
672 }
673 //*************************************************************************************************
674 
675 
676 //*************************************************************************************************
681 template< typename Type // Data type of the matrix
682  , bool SO > // Storage order
684  : m_ ( sm.m_ ) // The current number of rows of the compressed matrix
685  , n_ ( sm.n_ ) // The current number of columns of the compressed matrix
686  , capacity_( sm.capacity_ ) // The current capacity of the pointer array
687  , begin_ ( sm.begin_ ) // Pointers to the first non-zero element of each row
688  , end_ ( sm.end_ ) // Pointers one past the last non-zero element of each row
689 {
690  sm.m_ = 0UL;
691  sm.n_ = 0UL;
692  sm.capacity_ = 0UL;
693  sm.begin_ = nullptr;
694  sm.end_ = nullptr;
695 }
696 //*************************************************************************************************
697 
698 
699 //*************************************************************************************************
704 template< typename Type // Data type of the matrix
705  , bool SO > // Storage order
706 template< typename MT // Type of the foreign dense matrix
707  , bool SO2 > // Storage order of the foreign dense matrix
709  : m_ ( (~dm).rows() ) // The current number of rows of the compressed matrix
710  , n_ ( (~dm).columns() ) // The current number of columns of the compressed matrix
711  , capacity_( m_ ) // The current capacity of the pointer array
712  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
713  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
714 {
715  using blaze::assign;
716 
717  for( size_t i=0UL; i<2UL*m_+2UL; ++i )
718  begin_[i] = nullptr;
719 
720  assign( *this, ~dm );
721 }
722 //*************************************************************************************************
723 
724 
725 //*************************************************************************************************
730 template< typename Type // Data type of the matrix
731  , bool SO > // Storage order
732 template< typename MT // Type of the foreign compressed matrix
733  , bool SO2 > // Storage order of the foreign compressed matrix
735  : m_ ( (~sm).rows() ) // The current number of rows of the compressed matrix
736  , n_ ( (~sm).columns() ) // The current number of columns of the compressed matrix
737  , capacity_( m_ ) // The current capacity of the pointer array
738  , begin_ ( new Iterator[2UL*m_+2UL] ) // Pointers to the first non-zero element of each row
739  , end_ ( begin_+(m_+1UL) ) // Pointers one past the last non-zero element of each row
740 {
741  using blaze::assign;
742 
743  const size_t nonzeros( (~sm).nonZeros() );
744 
745  begin_[0UL] = allocate<Element>( nonzeros );
746  for( size_t i=0UL; i<m_; ++i )
747  begin_[i+1UL] = end_[i] = begin_[0UL];
748  end_[m_] = begin_[0UL]+nonzeros;
749 
750  assign( *this, ~sm );
751 }
752 //*************************************************************************************************
753 
754 
755 
756 
757 //=================================================================================================
758 //
759 // DESTRUCTOR
760 //
761 //=================================================================================================
762 
763 //*************************************************************************************************
766 template< typename Type // Data type of the matrix
767  , bool SO > // Storage order
769 {
770  if( begin_ != nullptr ) {
771  deallocate( begin_[0UL] );
772  delete[] begin_;
773  }
774 }
775 //*************************************************************************************************
776 
777 
778 
779 
780 //=================================================================================================
781 //
782 // DATA ACCESS FUNCTIONS
783 //
784 //=================================================================================================
785 
786 //*************************************************************************************************
799 template< typename Type // Data type of the matrix
800  , bool SO > // Storage order
802  CompressedMatrix<Type,SO>::operator()( size_t i, size_t j ) noexcept
803 {
804  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
805  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
806 
807  return Reference( *this, i, j );
808 }
809 //*************************************************************************************************
810 
811 
812 //*************************************************************************************************
822 template< typename Type // Data type of the matrix
823  , bool SO > // Storage order
825  CompressedMatrix<Type,SO>::operator()( size_t i, size_t j ) const noexcept
826 {
827  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
828  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
829 
830  const ConstIterator pos( lowerBound( i, j ) );
831 
832  if( pos == end_[i] || pos->index_ != j )
833  return zero_;
834  else
835  return pos->value_;
836 }
837 //*************************************************************************************************
838 
839 
840 //*************************************************************************************************
853 template< typename Type // Data type of the matrix
854  , bool SO > // Storage order
856  CompressedMatrix<Type,SO>::at( size_t i, size_t j )
857 {
858  if( i >= m_ ) {
859  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
860  }
861  if( j >= n_ ) {
862  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
863  }
864  return (*this)(i,j);
865 }
866 //*************************************************************************************************
867 
868 
869 //*************************************************************************************************
880 template< typename Type // Data type of the matrix
881  , bool SO > // Storage order
883  CompressedMatrix<Type,SO>::at( size_t i, size_t j ) const
884 {
885  if( i >= m_ ) {
886  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
887  }
888  if( j >= n_ ) {
889  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
890  }
891  return (*this)(i,j);
892 }
893 //*************************************************************************************************
894 
895 
896 //*************************************************************************************************
907 template< typename Type // Data type of the matrix
908  , bool SO > // Storage order
910  CompressedMatrix<Type,SO>::begin( size_t i ) noexcept
911 {
912  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
913  return begin_[i];
914 }
915 //*************************************************************************************************
916 
917 
918 //*************************************************************************************************
929 template< typename Type // Data type of the matrix
930  , bool SO > // Storage order
932  CompressedMatrix<Type,SO>::begin( size_t i ) const noexcept
933 {
934  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
935  return begin_[i];
936 }
937 //*************************************************************************************************
938 
939 
940 //*************************************************************************************************
951 template< typename Type // Data type of the matrix
952  , bool SO > // Storage order
954  CompressedMatrix<Type,SO>::cbegin( size_t i ) const noexcept
955 {
956  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
957  return begin_[i];
958 }
959 //*************************************************************************************************
960 
961 
962 //*************************************************************************************************
973 template< typename Type // Data type of the matrix
974  , bool SO > // Storage order
976  CompressedMatrix<Type,SO>::end( size_t i ) noexcept
977 {
978  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
979  return end_[i];
980 }
981 //*************************************************************************************************
982 
983 
984 //*************************************************************************************************
995 template< typename Type // Data type of the matrix
996  , bool SO > // Storage order
998  CompressedMatrix<Type,SO>::end( size_t i ) const noexcept
999 {
1000  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1001  return end_[i];
1002 }
1003 //*************************************************************************************************
1004 
1005 
1006 //*************************************************************************************************
1017 template< typename Type // Data type of the matrix
1018  , bool SO > // Storage order
1020  CompressedMatrix<Type,SO>::cend( size_t i ) const noexcept
1021 {
1022  BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1023  return end_[i];
1024 }
1025 //*************************************************************************************************
1026 
1027 
1028 
1029 
1030 //=================================================================================================
1031 //
1032 // ASSIGNMENT OPERATORS
1033 //
1034 //=================================================================================================
1035 
1036 //*************************************************************************************************
1045 template< typename Type // Data type of the matrix
1046  , bool SO > // Storage order
1049 {
1050  if( &rhs == this ) return *this;
1051 
1052  const size_t nonzeros( rhs.nonZeros() );
1053 
1054  if( rhs.m_ > capacity_ || nonzeros > capacity() )
1055  {
1056  Iterator* newBegin( new Iterator[2UL*rhs.m_+2UL] );
1057  Iterator* newEnd ( newBegin+(rhs.m_+1UL) );
1058 
1059  newBegin[0UL] = allocate<Element>( nonzeros );
1060  for( size_t i=0UL; i<rhs.m_; ++i ) {
1061  newEnd[i] = castDown( std::copy( rhs.begin_[i], rhs.end_[i], castUp( newBegin[i] ) ) );
1062  newBegin[i+1UL] = newEnd[i];
1063  }
1064  newEnd[rhs.m_] = newBegin[0UL]+nonzeros;
1065 
1066  std::swap( begin_, newBegin );
1067  end_ = newEnd;
1068  capacity_ = rhs.m_;
1069 
1070  if( newBegin != nullptr ) {
1071  deallocate( newBegin[0UL] );
1072  delete[] newBegin;
1073  }
1074  }
1075  else {
1076  for( size_t i=0UL; i<rhs.m_; ++i ) {
1077  end_[i] = castDown( std::copy( rhs.begin_[i], rhs.end_[i], castUp( begin_[i] ) ) );
1078  begin_[i+1UL] = end_[i];
1079  }
1080  }
1081 
1082  m_ = rhs.m_;
1083  n_ = rhs.n_;
1084 
1085  return *this;
1086 }
1087 //*************************************************************************************************
1088 
1089 
1090 //*************************************************************************************************
1096 template< typename Type // Data type of the matrix
1097  , bool SO > // Storage order
1100 {
1101  if( begin_ != nullptr ) {
1102  deallocate( begin_[0UL] );
1103  delete[] begin_;
1104  }
1105 
1106  m_ = rhs.m_;
1107  n_ = rhs.n_;
1108  capacity_ = rhs.capacity_;
1109  begin_ = rhs.begin_;
1110  end_ = rhs.end_;
1111 
1112  rhs.m_ = 0UL;
1113  rhs.n_ = 0UL;
1114  rhs.capacity_ = 0UL;
1115  rhs.begin_ = nullptr;
1116  rhs.end_ = nullptr;
1117 
1118  return *this;
1119 }
1120 //*************************************************************************************************
1121 
1122 
1123 //*************************************************************************************************
1132 template< typename Type // Data type of the matrix
1133  , bool SO > // Storage order
1134 template< typename MT // Type of the right-hand side dense matrix
1135  , bool SO2 > // Storage order of the right-hand side dense matrix
1138 {
1139  using blaze::assign;
1140 
1141  if( (~rhs).canAlias( this ) ) {
1142  CompressedMatrix tmp( ~rhs );
1143  swap( tmp );
1144  }
1145  else {
1146  resize( (~rhs).rows(), (~rhs).columns(), false );
1147  assign( *this, ~rhs );
1148  }
1149 
1150  return *this;
1151 }
1152 //*************************************************************************************************
1153 
1154 
1155 //*************************************************************************************************
1164 template< typename Type // Data type of the matrix
1165  , bool SO > // Storage order
1166 template< typename MT // Type of the right-hand side compressed matrix
1167  , bool SO2 > // Storage order of the right-hand side compressed matrix
1170 {
1171  using blaze::assign;
1172 
1173  if( (~rhs).canAlias( this ) ||
1174  (~rhs).rows() > capacity_ ||
1175  (~rhs).nonZeros() > capacity() ) {
1176  CompressedMatrix tmp( ~rhs );
1177  swap( tmp );
1178  }
1179  else {
1180  resize( (~rhs).rows(), (~rhs).columns(), false );
1181  reset();
1182  assign( *this, ~rhs );
1183  }
1184 
1185  return *this;
1186 }
1187 //*************************************************************************************************
1188 
1189 
1190 //*************************************************************************************************
1200 template< typename Type // Data type of the matrix
1201  , bool SO > // Storage order
1202 template< typename MT // Type of the right-hand side matrix
1203  , bool SO2 > // Storage order of the right-hand side matrix
1206 {
1207  using blaze::addAssign;
1208 
1209  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1210  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1211  }
1212 
1213  addAssign( *this, ~rhs );
1214  return *this;
1215 }
1216 //*************************************************************************************************
1217 
1218 
1219 //*************************************************************************************************
1229 template< typename Type // Data type of the matrix
1230  , bool SO > // Storage order
1231 template< typename MT // Type of the right-hand side matrix
1232  , bool SO2 > // Storage order of the right-hand side matrix
1234 {
1235  using blaze::subAssign;
1236 
1237  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1238  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1239  }
1240 
1241  subAssign( *this, ~rhs );
1242  return *this;
1243 }
1244 //*************************************************************************************************
1245 
1246 
1247 //*************************************************************************************************
1258 template< typename Type // Data type of the matrix
1259  , bool SO > // Storage order
1260 template< typename MT // Type of the right-hand side dense matrix
1261  , bool SO2 > // Storage order of the right-hand side dense matrix
1264 {
1265  using blaze::schurAssign;
1266 
1267  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1268  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1269  }
1270 
1271  if( (~rhs).canAlias( this ) ) {
1272  CompressedMatrix tmp( *this % (~rhs) );
1273  swap( tmp );
1274  }
1275  else {
1276  CompositeType_<MT> tmp( ~rhs );
1277  schurAssign( *this, tmp );
1278  }
1279 
1280  return *this;
1281 }
1282 //*************************************************************************************************
1283 
1284 
1285 //*************************************************************************************************
1296 template< typename Type // Data type of the matrix
1297  , bool SO > // Storage order
1298 template< typename MT // Type of the right-hand side sparse matrix
1299  , bool SO2 > // Storage order of the right-hand side sparse matrix
1302 {
1303  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1304  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1305  }
1306 
1307  CompressedMatrix tmp( *this % (~rhs) );
1308  swap( tmp );
1309 
1310  return *this;
1311 }
1312 //*************************************************************************************************
1313 
1314 
1315 //*************************************************************************************************
1325 template< typename Type // Data type of the matrix
1326  , bool SO > // Storage order
1327 template< typename MT // Type of the right-hand side matrix
1328  , bool SO2 > // Storage order of the right-hand side matrix
1331 {
1332  if( (~rhs).rows() != n_ ) {
1333  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1334  }
1335 
1336  CompressedMatrix tmp( *this * (~rhs) );
1337  swap( tmp );
1338 
1339  return *this;
1340 }
1341 //*************************************************************************************************
1342 
1343 
1344 //*************************************************************************************************
1351 template< typename Type // Data type of the matrix
1352  , bool SO > // Storage order
1353 template< typename Other > // Data type of the right-hand side scalar
1356 {
1357  for( size_t i=0UL; i<m_; ++i ) {
1358  const Iterator last( end(i) );
1359  for( Iterator element=begin(i); element!=last; ++element )
1360  element->value_ *= rhs;
1361  }
1362  return *this;
1363 }
1364 //*************************************************************************************************
1365 
1366 
1367 //*************************************************************************************************
1374 template< typename Type // Data type of the matrix
1375  , bool SO > // Storage order
1376 template< typename Other > // Data type of the right-hand side scalar
1377 inline EnableIf_< IsNumeric<Other>, CompressedMatrix<Type,SO> >&
1379 {
1380  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1381 
1382  using DT = DivTrait_<Type,Other>;
1383  using Tmp = If_< IsNumeric<DT>, DT, Other >;
1384 
1385  // Depending on the two involved data types, an integer division is applied or a
1386  // floating point division is selected.
1388  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1389  for( size_t i=0UL; i<m_; ++i ) {
1390  const Iterator last( end(i) );
1391  for( Iterator element=begin(i); element!=last; ++element )
1392  element->value_ *= tmp;
1393  }
1394  }
1395  else {
1396  for( size_t i=0UL; i<m_; ++i ) {
1397  const Iterator last( end(i) );
1398  for( Iterator element=begin(i); element!=last; ++element )
1399  element->value_ /= rhs;
1400  }
1401  }
1402 
1403  return *this;
1404 }
1405 //*************************************************************************************************
1406 
1407 
1408 
1409 
1410 //=================================================================================================
1411 //
1412 // UTILITY FUNCTIONS
1413 //
1414 //=================================================================================================
1415 
1416 //*************************************************************************************************
1421 template< typename Type // Data type of the matrix
1422  , bool SO > // Storage order
1423 inline size_t CompressedMatrix<Type,SO>::rows() const noexcept
1424 {
1425  return m_;
1426 }
1427 //*************************************************************************************************
1428 
1429 
1430 //*************************************************************************************************
1435 template< typename Type // Data type of the matrix
1436  , bool SO > // Storage order
1437 inline size_t CompressedMatrix<Type,SO>::columns() const noexcept
1438 {
1439  return n_;
1440 }
1441 //*************************************************************************************************
1442 
1443 
1444 //*************************************************************************************************
1449 template< typename Type // Data type of the matrix
1450  , bool SO > // Storage order
1451 inline size_t CompressedMatrix<Type,SO>::capacity() const noexcept
1452 {
1453  if( begin_ != nullptr )
1454  return end_[m_] - begin_[0UL];
1455  else return 0UL;
1456 }
1457 //*************************************************************************************************
1458 
1459 
1460 //*************************************************************************************************
1471 template< typename Type // Data type of the matrix
1472  , bool SO > // Storage order
1473 inline size_t CompressedMatrix<Type,SO>::capacity( size_t i ) const noexcept
1474 {
1475  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1476  return begin_[i+1UL] - begin_[i];
1477 }
1478 //*************************************************************************************************
1479 
1480 
1481 //*************************************************************************************************
1486 template< typename Type // Data type of the matrix
1487  , bool SO > // Storage order
1489 {
1490  size_t nonzeros( 0UL );
1491 
1492  for( size_t i=0UL; i<m_; ++i )
1493  nonzeros += nonZeros( i );
1494 
1495  return nonzeros;
1496 }
1497 //*************************************************************************************************
1498 
1499 
1500 //*************************************************************************************************
1511 template< typename Type // Data type of the matrix
1512  , bool SO > // Storage order
1513 inline size_t CompressedMatrix<Type,SO>::nonZeros( size_t i ) const
1514 {
1515  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1516  return end_[i] - begin_[i];
1517 }
1518 //*************************************************************************************************
1519 
1520 
1521 //*************************************************************************************************
1526 template< typename Type // Data type of the matrix
1527  , bool SO > // Storage order
1529 {
1530  for( size_t i=0UL; i<m_; ++i )
1531  end_[i] = begin_[i];
1532 }
1533 //*************************************************************************************************
1534 
1535 
1536 //*************************************************************************************************
1547 template< typename Type // Data type of the matrix
1548  , bool SO > // Storage order
1549 inline void CompressedMatrix<Type,SO>::reset( size_t i )
1550 {
1551  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1552  end_[i] = begin_[i];
1553 }
1554 //*************************************************************************************************
1555 
1556 
1557 //*************************************************************************************************
1564 template< typename Type // Data type of the matrix
1565  , bool SO > // Storage order
1567 {
1568  if( end_ != nullptr )
1569  end_[0UL] = end_[m_];
1570  m_ = 0UL;
1571  n_ = 0UL;
1572 }
1573 //*************************************************************************************************
1574 
1575 
1576 //*************************************************************************************************
1591 template< typename Type // Data type of the matrix
1592  , bool SO > // Storage order
1593 void CompressedMatrix<Type,SO>::resize( size_t m, size_t n, bool preserve )
1594 {
1595  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1596  BLAZE_INTERNAL_ASSERT( begin_ == nullptr || size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1597 
1598  if( m == m_ && n == n_ ) return;
1599 
1600  if( begin_ == nullptr )
1601  {
1602  begin_ = new Iterator[2UL*m+2UL];
1603  end_ = begin_+m+1UL;
1604 
1605  for( size_t i=0UL; i<2UL*m+2UL; ++i ) {
1606  begin_[i] = nullptr;
1607  }
1608 
1609  capacity_ = m;
1610  }
1611  else if( m > capacity_ )
1612  {
1613  Iterator* newBegin( new Iterator[2UL*m+2UL] );
1614  Iterator* newEnd ( newBegin+m+1UL );
1615 
1616  newBegin[0UL] = begin_[0UL];
1617 
1618  if( preserve ) {
1619  for( size_t i=0UL; i<m_; ++i ) {
1620  newEnd [i] = end_ [i];
1621  newBegin[i+1UL] = begin_[i+1UL];
1622  }
1623  for( size_t i=m_; i<m; ++i ) {
1624  newBegin[i+1UL] = newEnd[i] = begin_[m_];
1625  }
1626  }
1627  else {
1628  for( size_t i=0UL; i<m; ++i ) {
1629  newBegin[i+1UL] = newEnd[i] = begin_[0UL];
1630  }
1631  }
1632 
1633  newEnd[m] = end_[m_];
1634 
1635  std::swap( newBegin, begin_ );
1636  delete[] newBegin;
1637  end_ = newEnd;
1638  capacity_ = m;
1639  }
1640  else if( m > m_ )
1641  {
1642  end_[m] = end_[m_];
1643 
1644  if( !preserve ) {
1645  for( size_t i=0UL; i<m_; ++i )
1646  end_[i] = begin_[i];
1647  }
1648 
1649  for( size_t i=m_; i<m; ++i ) {
1650  begin_[i+1UL] = end_[i] = begin_[m_];
1651  }
1652  }
1653  else
1654  {
1655  if( preserve ) {
1656  for( size_t i=0UL; i<m; ++i )
1657  end_[i] = lowerBound( i, n );
1658  }
1659  else {
1660  for( size_t i=0UL; i<m; ++i )
1661  end_[i] = begin_[i];
1662  }
1663 
1664  end_[m] = end_[m_];
1665  }
1666 
1667  m_ = m;
1668  n_ = n;
1669 
1670  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1671  BLAZE_INTERNAL_ASSERT( size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1672 }
1673 //*************************************************************************************************
1674 
1675 
1676 //*************************************************************************************************
1686 template< typename Type // Data type of the matrix
1687  , bool SO > // Storage order
1688 inline void CompressedMatrix<Type,SO>::reserve( size_t nonzeros )
1689 {
1690  if( nonzeros > capacity() )
1691  reserveElements( nonzeros );
1692 }
1693 //*************************************************************************************************
1694 
1695 
1696 //*************************************************************************************************
1710 template< typename Type // Data type of the matrix
1711  , bool SO > // Storage order
1712 void CompressedMatrix<Type,SO>::reserve( size_t i, size_t nonzeros )
1713 {
1714  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1715 
1716  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1717  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1718 
1719  const size_t current( capacity(i) );
1720 
1721  if( current >= nonzeros ) return;
1722 
1723  const ptrdiff_t additional( nonzeros - current );
1724 
1725  if( end_[m_] - begin_[m_] < additional )
1726  {
1727  const size_t newCapacity( begin_[m_] - begin_[0UL] + additional );
1728  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
1729 
1730  Iterator* newBegin( new Iterator[2UL*m_+2UL] );
1731  Iterator* newEnd ( newBegin+m_+1UL );
1732 
1733  newBegin[0UL] = allocate<Element>( newCapacity );
1734  newEnd [m_ ] = newBegin[0UL]+newCapacity;
1735 
1736  for( size_t k=0UL; k<i; ++k ) {
1737  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
1738  newBegin[k+1UL] = newBegin[k] + capacity(k);
1739  }
1740  newEnd [i ] = castDown( transfer( begin_[i], end_[i], castUp( newBegin[i] ) ) );
1741  newBegin[i+1UL] = newBegin[i] + nonzeros;
1742  for( size_t k=i+1UL; k<m_; ++k ) {
1743  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
1744  newBegin[k+1UL] = newBegin[k] + capacity(k);
1745  }
1746 
1747  BLAZE_INTERNAL_ASSERT( newBegin[m_] == newEnd[m_], "Invalid pointer calculations" );
1748 
1749  std::swap( newBegin, begin_ );
1750  deallocate( newBegin[0UL] );
1751  delete[] newBegin;
1752  end_ = newEnd;
1753  capacity_ = m_;
1754  }
1755  else
1756  {
1757  begin_[m_] += additional;
1758  for( size_t j=m_-1UL; j>i; --j ) {
1759  begin_[j] = castDown( std::move_backward( begin_[j], end_[j], castUp( end_[j]+additional ) ) );
1760  end_ [j] += additional;
1761  }
1762  }
1763 
1764  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1765  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1766 }
1767 //*************************************************************************************************
1768 
1769 
1770 //*************************************************************************************************
1780 template< typename Type // Data type of the matrix
1781  , bool SO > // Storage order
1783 {
1784  for( size_t i=0UL; i<m_; ++i )
1785  trim( i );
1786 }
1787 //*************************************************************************************************
1788 
1789 
1790 //*************************************************************************************************
1801 template< typename Type // Data type of the matrix
1802  , bool SO > // Storage order
1803 inline void CompressedMatrix<Type,SO>::trim( size_t i )
1804 {
1805  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1806 
1807  if( i < ( m_ - 1UL ) )
1808  end_[i+1] = castDown( std::move( begin_[i+1], end_[i+1], castUp( end_[i] ) ) );
1809  begin_[i+1] = end_[i];
1810 }
1811 //*************************************************************************************************
1812 
1813 
1814 //*************************************************************************************************
1823 template< typename Type // Data type of the matrix
1824  , bool SO > // Storage order
1826 {
1827  if( nonZeros() < capacity() ) {
1828  CompressedMatrix( *this ).swap( *this );
1829  }
1830 }
1831 //*************************************************************************************************
1832 
1833 
1834 //*************************************************************************************************
1840 template< typename Type // Data type of the matrix
1841  , bool SO > // Storage order
1843 {
1844  std::swap( m_, sm.m_ );
1845  std::swap( n_, sm.n_ );
1846  std::swap( capacity_, sm.capacity_ );
1847  std::swap( begin_, sm.begin_ );
1848  std::swap( end_ , sm.end_ );
1849 }
1850 //*************************************************************************************************
1851 
1852 
1853 //*************************************************************************************************
1861 template< typename Type // Data type of the matrix
1862  , bool SO > // Storage order
1863 inline size_t CompressedMatrix<Type,SO>::extendCapacity() const noexcept
1864 {
1865  size_t nonzeros( 2UL*capacity()+1UL );
1866  nonzeros = blaze::max( nonzeros, 7UL );
1867 
1868  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
1869 
1870  return nonzeros;
1871 }
1872 //*************************************************************************************************
1873 
1874 
1875 //*************************************************************************************************
1881 template< typename Type // Data type of the matrix
1882  , bool SO > // Storage order
1884 {
1885  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
1886  Iterator* newEnd = newBegin+capacity_+1UL;
1887 
1888  newBegin[0UL] = allocate<Element>( nonzeros );
1889 
1890  for( size_t k=0UL; k<m_; ++k ) {
1891  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid row pointers" );
1892  newEnd [k] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
1893  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
1894  }
1895 
1896  newEnd[m_] = newBegin[0UL]+nonzeros;
1897 
1898  std::swap( newBegin, begin_ );
1899  end_ = newEnd;
1900 
1901  if( newBegin != nullptr ) {
1902  deallocate( newBegin[0UL] );
1903  delete[] newBegin;
1904  }
1905 }
1906 //*************************************************************************************************
1907 
1908 
1909 //*************************************************************************************************
1917 template< typename Type // Data type of the matrix
1918  , bool SO > // Storage order
1921 {
1922  return static_cast<Iterator>( it );
1923 }
1924 //*************************************************************************************************
1925 
1926 
1927 //*************************************************************************************************
1935 template< typename Type // Data type of the matrix
1936  , bool SO > // Storage order
1939 {
1940  return static_cast<IteratorBase>( it );
1941 }
1942 //*************************************************************************************************
1943 
1944 
1945 
1946 
1947 //=================================================================================================
1948 //
1949 // INSERTION FUNCTIONS
1950 //
1951 //=================================================================================================
1952 
1953 //*************************************************************************************************
1965 template< typename Type // Data type of the matrix
1966  , bool SO > // Storage order
1968  CompressedMatrix<Type,SO>::set( size_t i, size_t j, const Type& value )
1969 {
1970  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1971  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1972 
1973  const Iterator pos( lowerBound( i, j ) );
1974 
1975  if( pos != end_[i] && pos->index_ == j ) {
1976  pos->value() = value;
1977  return pos;
1978  }
1979  else return insert( pos, i, j, value );
1980 }
1981 //*************************************************************************************************
1982 
1983 
1984 //*************************************************************************************************
1997 template< typename Type // Data type of the matrix
1998  , bool SO > // Storage order
2000  CompressedMatrix<Type,SO>::insert( size_t i, size_t j, const Type& value )
2001 {
2002  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2003  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2004 
2005  const Iterator pos( lowerBound( i, j ) );
2006 
2007  if( pos != end_[i] && pos->index_ == j ) {
2008  BLAZE_THROW_INVALID_ARGUMENT( "Bad access index" );
2009  }
2010 
2011  return insert( pos, i, j, value );
2012 }
2013 //*************************************************************************************************
2014 
2015 
2016 //*************************************************************************************************
2026 template< typename Type // Data type of the matrix
2027  , bool SO > // Storage order
2029  CompressedMatrix<Type,SO>::insert( Iterator pos, size_t i, size_t j, const Type& value )
2030 {
2031  if( begin_[i+1UL] - end_[i] != 0 ) {
2032  std::move_backward( pos, end_[i], castUp( end_[i]+1UL ) );
2033  pos->value_ = value;
2034  pos->index_ = j;
2035  ++end_[i];
2036 
2037  return pos;
2038  }
2039  else if( end_[m_] - begin_[m_] != 0 ) {
2040  std::move_backward( pos, end_[m_-1UL], castUp( end_[m_-1UL]+1UL ) );
2041 
2042  pos->value_ = value;
2043  pos->index_ = j;
2044 
2045  for( size_t k=i+1UL; k<m_+1UL; ++k ) {
2046  ++begin_[k];
2047  ++end_[k-1UL];
2048  }
2049 
2050  return pos;
2051  }
2052  else {
2053  size_t newCapacity( extendCapacity() );
2054 
2055  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
2056  Iterator* newEnd = newBegin+capacity_+1UL;
2057 
2058  newBegin[0UL] = allocate<Element>( newCapacity );
2059 
2060  for( size_t k=0UL; k<i; ++k ) {
2061  const size_t nonzeros( end_[k] - begin_[k] );
2062  const size_t total( begin_[k+1UL] - begin_[k] );
2063  newEnd [k] = newBegin[k] + nonzeros;
2064  newBegin[k+1UL] = newBegin[k] + total;
2065  }
2066  newEnd [i] = newBegin[i] + ( end_[i] - begin_[i] ) + 1;
2067  newBegin[i+1UL] = newBegin[i] + ( begin_[i+1] - begin_[i] ) + 1;
2068  for( size_t k=i+1UL; k<m_; ++k ) {
2069  const size_t nonzeros( end_[k] - begin_[k] );
2070  const size_t total( begin_[k+1UL] - begin_[k] );
2071  newEnd [k] = newBegin[k] + nonzeros;
2072  newBegin[k+1UL] = newBegin[k] + total;
2073  }
2074 
2075  newEnd[m_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
2076 
2077  Iterator tmp = castDown( std::move( begin_[0UL], pos, castUp( newBegin[0UL] ) ) );
2078  tmp->value_ = value;
2079  tmp->index_ = j;
2080  std::move( pos, end_[m_-1UL], castUp( tmp+1UL ) );
2081 
2082  std::swap( newBegin, begin_ );
2083  end_ = newEnd;
2084  deallocate( newBegin[0UL] );
2085  delete[] newBegin;
2086 
2087  return tmp;
2088  }
2089 }
2090 //*************************************************************************************************
2091 
2092 
2093 //*************************************************************************************************
2146 template< typename Type // Data type of the matrix
2147  , bool SO > // Storage order
2148 inline void CompressedMatrix<Type,SO>::append( size_t i, size_t j, const Type& value, bool check )
2149 {
2150  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2151  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
2152  BLAZE_USER_ASSERT( end_[i] < end_[m_], "Not enough reserved capacity left" );
2153  BLAZE_USER_ASSERT( begin_[i] == end_[i] || j > ( end_[i]-1UL )->index_, "Index is not strictly increasing" );
2154 
2155  end_[i]->value_ = value;
2156 
2157  if( !check || !isDefault<strict>( end_[i]->value_ ) ) {
2158  end_[i]->index_ = j;
2159  ++end_[i];
2160  }
2161 }
2162 //*************************************************************************************************
2163 
2164 
2165 //*************************************************************************************************
2178 template< typename Type // Data type of the matrix
2179  , bool SO > // Storage order
2181 {
2182  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2183 
2184  begin_[i+1UL] = end_[i];
2185  if( i != m_-1UL )
2186  end_[i+1UL] = end_[i];
2187 }
2188 //*************************************************************************************************
2189 
2190 
2191 
2192 
2193 //=================================================================================================
2194 //
2195 // ERASE FUNCTIONS
2196 //
2197 //=================================================================================================
2198 
2199 //*************************************************************************************************
2208 template< typename Type // Data type of the matrix
2209  , bool SO > // Storage order
2210 inline void CompressedMatrix<Type,SO>::erase( size_t i, size_t j )
2211 {
2212  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2213  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2214 
2215  const Iterator pos( find( i, j ) );
2216  if( pos != end_[i] )
2217  end_[i] = castDown( std::move( pos+1, end_[i], castUp( pos ) ) );
2218 }
2219 //*************************************************************************************************
2220 
2221 
2222 //*************************************************************************************************
2233 template< typename Type // Data type of the matrix
2234  , bool SO > // Storage order
2237 {
2238  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2239  BLAZE_USER_ASSERT( pos >= begin_[i] && pos <= end_[i], "Invalid compressed matrix iterator" );
2240 
2241  if( pos != end_[i] )
2242  end_[i] = castDown( std::move( pos+1, end_[i], castUp( pos ) ) );
2243 
2244  return pos;
2245 }
2246 //*************************************************************************************************
2247 
2248 
2249 //*************************************************************************************************
2261 template< typename Type // Data type of the matrix
2262  , bool SO > // Storage order
2265 {
2266  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2267  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
2268  BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i], "Invalid compressed matrix iterator" );
2269  BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i], "Invalid compressed matrix iterator" );
2270 
2271  if( first != last )
2272  end_[i] = castDown( std::move( last, end_[i], castUp( first ) ) );
2273 
2274  return first;
2275 }
2276 //*************************************************************************************************
2277 
2278 
2279 //*************************************************************************************************
2300 template< typename Type // Data type of the matrix
2301  , bool SO > // Storage order
2302 template< typename Pred > // Type of the unary predicate
2303 inline void CompressedMatrix<Type,SO>::erase( Pred predicate )
2304 {
2305  for( size_t i=0UL; i<m_; ++i ) {
2306  end_[i] = castDown( std::remove_if( castUp( begin_[i] ), castUp( end_[i] ),
2307  [predicate=predicate]( const ElementBase& element) {
2308  return predicate( element.value() );
2309  } ) );
2310  }
2311 }
2312 //*************************************************************************************************
2313 
2314 
2315 //*************************************************************************************************
2342 template< typename Type // Data type of the matrix
2343  , bool SO > // Storage order
2344 template< typename Pred > // Type of the unary predicate
2345 inline void CompressedMatrix<Type,SO>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
2346 {
2347  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2348  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
2349  BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i], "Invalid compressed matrix iterator" );
2350  BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i], "Invalid compressed matrix iterator" );
2351 
2352  const auto pos = std::remove_if( castUp( first ), castUp( last ),
2353  [predicate=predicate]( const ElementBase& element ) {
2354  return predicate( element.value() );
2355  } );
2356 
2357  end_[i] = castDown( std::move( last, end_[i], pos ) );
2358 }
2359 //*************************************************************************************************
2360 
2361 
2362 
2363 
2364 //=================================================================================================
2365 //
2366 // LOOKUP FUNCTIONS
2367 //
2368 //=================================================================================================
2369 
2370 //*************************************************************************************************
2385 template< typename Type // Data type of the matrix
2386  , bool SO > // Storage order
2388  CompressedMatrix<Type,SO>::find( size_t i, size_t j )
2389 {
2390  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
2391 }
2392 //*************************************************************************************************
2393 
2394 
2395 //*************************************************************************************************
2410 template< typename Type // Data type of the matrix
2411  , bool SO > // Storage order
2413  CompressedMatrix<Type,SO>::find( size_t i, size_t j ) const
2414 {
2415  const ConstIterator pos( lowerBound( i, j ) );
2416  if( pos != end_[i] && pos->index_ == j )
2417  return pos;
2418  else return end_[i];
2419 }
2420 //*************************************************************************************************
2421 
2422 
2423 //*************************************************************************************************
2438 template< typename Type // Data type of the matrix
2439  , bool SO > // Storage order
2442 {
2443  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
2444 }
2445 //*************************************************************************************************
2446 
2447 
2448 //*************************************************************************************************
2463 template< typename Type // Data type of the matrix
2464  , bool SO > // Storage order
2466  CompressedMatrix<Type,SO>::lowerBound( size_t i, size_t j ) const
2467 {
2468  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2469  return std::lower_bound( begin_[i], end_[i], j,
2470  []( const Element& element, size_t index )
2471  {
2472  return element.index() < index;
2473  } );
2474 }
2475 //*************************************************************************************************
2476 
2477 
2478 //*************************************************************************************************
2493 template< typename Type // Data type of the matrix
2494  , bool SO > // Storage order
2497 {
2498  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
2499 }
2500 //*************************************************************************************************
2501 
2502 
2503 //*************************************************************************************************
2518 template< typename Type // Data type of the matrix
2519  , bool SO > // Storage order
2521  CompressedMatrix<Type,SO>::upperBound( size_t i, size_t j ) const
2522 {
2523  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2524  return std::upper_bound( begin_[i], end_[i], j,
2525  []( size_t index, const Element& element )
2526  {
2527  return index < element.index();
2528  } );
2529 }
2530 //*************************************************************************************************
2531 
2532 
2533 
2534 
2535 //=================================================================================================
2536 //
2537 // NUMERIC FUNCTIONS
2538 //
2539 //=================================================================================================
2540 
2541 //*************************************************************************************************
2546 template< typename Type // Data type of the matrix
2547  , bool SO > // Storage order
2549 {
2550  CompressedMatrix tmp( trans( *this ) );
2551  swap( tmp );
2552  return *this;
2553 }
2554 //*************************************************************************************************
2555 
2556 
2557 //*************************************************************************************************
2562 template< typename Type // Data type of the matrix
2563  , bool SO > // Storage order
2565 {
2566  CompressedMatrix tmp( ctrans( *this ) );
2567  swap( tmp );
2568  return *this;
2569 }
2570 //*************************************************************************************************
2571 
2572 
2573 //*************************************************************************************************
2590 template< typename Type // Data type of the matrix
2591  , bool SO > // Storage order
2592 template< typename Other > // Data type of the scalar value
2594 {
2595  for( size_t i=0UL; i<m_; ++i )
2596  for( Iterator element=begin_[i]; element!=end_[i]; ++element )
2597  element->value_ *= scalar;
2598 
2599  return *this;
2600 }
2601 //*************************************************************************************************
2602 
2603 
2604 //*************************************************************************************************
2613 template< typename Type // Data type of the matrix
2614  , bool SO > // Storage order
2615 template< typename Other > // Data type of the scalar value
2617 {
2618  const size_t size( blaze::min( m_, n_ ) );
2619 
2620  for( size_t i=0UL; i<size; ++i ) {
2621  Iterator pos = lowerBound( i, i );
2622  if( pos != end_[i] && pos->index_ == i )
2623  pos->value_ *= scalar;
2624  }
2625 
2626  return *this;
2627 }
2628 //*************************************************************************************************
2629 
2630 
2631 
2632 
2633 //=================================================================================================
2634 //
2635 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2636 //
2637 //=================================================================================================
2638 
2639 //*************************************************************************************************
2649 template< typename Type // Data type of the matrix
2650  , bool SO > // Storage order
2651 template< typename Other > // Data type of the foreign expression
2652 inline bool CompressedMatrix<Type,SO>::canAlias( const Other* alias ) const noexcept
2653 {
2654  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2655 }
2656 //*************************************************************************************************
2657 
2658 
2659 //*************************************************************************************************
2669 template< typename Type // Data type of the matrix
2670  , bool SO > // Storage order
2671 template< typename Other > // Data type of the foreign expression
2672 inline bool CompressedMatrix<Type,SO>::isAliased( const Other* alias ) const noexcept
2673 {
2674  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2675 }
2676 //*************************************************************************************************
2677 
2678 
2679 //*************************************************************************************************
2689 template< typename Type // Data type of the matrix
2690  , bool SO > // Storage order
2691 inline bool CompressedMatrix<Type,SO>::canSMPAssign() const noexcept
2692 {
2693  return false;
2694 }
2695 //*************************************************************************************************
2696 
2697 
2698 //*************************************************************************************************
2709 template< typename Type // Data type of the matrix
2710  , bool SO > // Storage order
2711 template< typename MT // Type of the right-hand side dense matrix
2712  , bool SO2 > // Storage order of the right-hand side dense matrix
2714 {
2715  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2716  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2717 
2718  if( m_ == 0UL || n_ == 0UL )
2719  return;
2720 
2721  size_t nonzeros( 0UL );
2722 
2723  for( size_t i=1UL; i<=m_; ++i )
2724  begin_[i] = end_[i] = end_[m_];
2725 
2726  for( size_t i=0UL; i<m_; ++i )
2727  {
2728  begin_[i] = end_[i] = begin_[0UL]+nonzeros;
2729 
2730  const size_t jbegin( ( IsUpper<MT>::value )
2731  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2732  :( 0UL ) );
2733  const size_t jend ( ( IsLower<MT>::value )
2734  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2735  :( n_ ) );
2736 
2737  for( size_t j=jbegin; j<jend; ++j )
2738  {
2739  if( nonzeros == capacity() ) {
2741  for( size_t k=i+1UL; k<=m_; ++k )
2742  begin_[k] = end_[k] = end_[m_];
2743  }
2744 
2745  end_[i]->value_ = (~rhs)(i,j);
2746 
2747  if( !isDefault<strict>( end_[i]->value_ ) ) {
2748  end_[i]->index_ = j;
2749  ++end_[i];
2750  ++nonzeros;
2751  }
2752  }
2753  }
2754 
2755  begin_[m_] = begin_[0UL]+nonzeros;
2756 }
2757 //*************************************************************************************************
2758 
2759 
2760 //*************************************************************************************************
2771 template< typename Type // Data type of the matrix
2772  , bool SO > // Storage order
2773 template< typename MT > // Type of the right-hand side compressed matrix
2775 {
2776  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2777  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2778  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2779  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
2780 
2781  if( m_ == 0UL || begin_[0] == nullptr )
2782  return;
2783 
2784  for( size_t i=0UL; i<m_; ++i ) {
2785  end_[i] = castDown( std::copy( (~rhs).begin(i), (~rhs).end(i), castUp( begin_[i] ) ) );
2786  begin_[i+1UL] = end_[i];
2787  }
2788 }
2789 //*************************************************************************************************
2790 
2791 
2792 //*************************************************************************************************
2803 template< typename Type // Data type of the matrix
2804  , bool SO > // Storage order
2805 template< typename MT > // Type of the right-hand side compressed matrix
2807 {
2809 
2810  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2811  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2812  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2813  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
2814 
2815  using RhsIterator = ConstIterator_<MT>;
2816 
2817  // Counting the number of elements per row
2818  std::vector<size_t> rowLengths( m_, 0UL );
2819  for( size_t j=0UL; j<n_; ++j ) {
2820  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2821  ++rowLengths[element->index()];
2822  }
2823 
2824  // Resizing the compressed matrix
2825  for( size_t i=0UL; i<m_; ++i ) {
2826  begin_[i+1UL] = end_[i+1UL] = begin_[i] + rowLengths[i];
2827  }
2828 
2829  // Appending the elements to the rows of the compressed matrix
2830  for( size_t j=0UL; j<n_; ++j ) {
2831  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2832  append( element->index(), j, element->value() );
2833  }
2834 }
2835 //*************************************************************************************************
2836 
2837 
2838 //*************************************************************************************************
2849 template< typename Type // Data type of the matrix
2850  , bool SO > // Storage order
2851 template< typename MT // Type of the right-hand side dense matrix
2852  , bool SO2 > // Storage order of the right-hand side dense matrix
2854 {
2855  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2856  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2857 
2858  CompressedMatrix tmp( serial( *this + (~rhs) ) );
2859  swap( tmp );
2860 }
2861 //*************************************************************************************************
2862 
2863 
2864 //*************************************************************************************************
2875 template< typename Type // Data type of the matrix
2876  , bool SO > // Storage order
2877 template< typename MT // Type of the right-hand side compressed matrix
2878  , bool SO2 > // Storage order of the right-hand side compressed matrix
2880 {
2881  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2882  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2883 
2884  CompressedMatrix tmp( serial( *this + (~rhs) ) );
2885  swap( tmp );
2886 }
2887 //*************************************************************************************************
2888 
2889 
2890 //*************************************************************************************************
2901 template< typename Type // Data type of the matrix
2902  , bool SO > // Storage order
2903 template< typename MT // Type of the right-hand side dense matrix
2904  , bool SO2 > // Storage order of the right-hand side dense matrix
2906 {
2907  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2908  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2909 
2910  CompressedMatrix tmp( serial( *this - (~rhs) ) );
2911  swap( tmp );
2912 }
2913 //*************************************************************************************************
2914 
2915 
2916 //*************************************************************************************************
2927 template< typename Type // Data type of the matrix
2928  , bool SO > // Storage order
2929 template< typename MT // Type of the right-hand side compressed matrix
2930  , bool SO2 > // Storage order of the right-hand compressed matrix
2932 {
2933  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2934  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2935 
2936  CompressedMatrix tmp( serial( *this - (~rhs) ) );
2937  swap( tmp );
2938 }
2939 //*************************************************************************************************
2940 
2941 
2942 //*************************************************************************************************
2953 template< typename Type // Data type of the matrix
2954  , bool SO > // Storage order
2955 template< typename MT // Type of the right-hand side dense matrix
2956  , bool SO2 > // Storage order of the right-hand side dense matrix
2958 {
2959  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2960  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2961 
2963 
2964  for( size_t i=0UL; i<m_; ++i ) {
2965  const Iterator last( end(i) );
2966  for( Iterator element=begin(i); element!=last; ++element )
2967  element->value_ *= (~rhs)(i,element->index_);
2968  }
2969 }
2970 //*************************************************************************************************
2971 
2972 
2973 
2974 
2975 
2976 
2977 
2978 
2979 //=================================================================================================
2980 //
2981 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2982 //
2983 //=================================================================================================
2984 
2985 //*************************************************************************************************
2993 template< typename Type > // Data type of the matrix
2994 class CompressedMatrix<Type,true>
2995  : public SparseMatrix< CompressedMatrix<Type,true>, true >
2996 {
2997  private:
2998  //**Type definitions****************************************************************************
3000  using IteratorBase = ElementBase*;
3001  //**********************************************************************************************
3002 
3003  //**Private class Element***********************************************************************
3010  struct Element
3011  : public ElementBase
3012  {
3013  //**Constructors*****************************************************************************
3014  explicit Element() = default;
3015  Element( const Element& rhs ) = default;
3016  Element( Element&& rhs ) = default;
3017  //*******************************************************************************************
3018 
3019  //**Assignment operators*********************************************************************
3020  inline Element& operator=( const Element& rhs )
3021  {
3022  this->value_ = rhs.value_;
3023  return *this;
3024  }
3025 
3026  inline Element& operator=( Element&& rhs )
3027  {
3028  this->value_ = std::move( rhs.value_ );
3029  return *this;
3030  }
3031 
3032  template< typename Other >
3033  inline EnableIf_< IsSparseElement<Other>, Element& >
3034  operator=( const Other& rhs )
3035  {
3036  this->value_ = rhs.value();
3037  return *this;
3038  }
3039 
3040  template< typename Other >
3042  , IsRValueReference<Other&&> >, Element& >
3043  operator=( Other&& rhs )
3044  {
3045  this->value_ = std::move( rhs.value() );
3046  return *this;
3047  }
3048 
3049  template< typename Other >
3050  inline EnableIf_< Not< IsSparseElement<Other> >, Element& >
3051  operator=( const Other& v )
3052  {
3053  this->value_ = v;
3054  return *this;
3055  }
3056 
3057  template< typename Other >
3059  , IsRValueReference<Other&&> >, Element& >
3060  operator=( Other&& v )
3061  {
3062  this->value_ = std::move( v );
3063  return *this;
3064  }
3065  //*******************************************************************************************
3066 
3067  //**Friend declarations**********************************************************************
3068  friend class CompressedMatrix;
3069  //*******************************************************************************************
3070  };
3072  //**********************************************************************************************
3073 
3074  public:
3075  //**Type definitions****************************************************************************
3078  using ResultType = This;
3081  using ElementType = Type;
3082  using ReturnType = const Type&;
3083  using CompositeType = const This&;
3085  using ConstReference = const Type&;
3086  using Iterator = Element*;
3087  using ConstIterator = const Element*;
3088  //**********************************************************************************************
3089 
3090  //**Rebind struct definition********************************************************************
3093  template< typename NewType > // Data type of the other matrix
3094  struct Rebind {
3096  };
3097  //**********************************************************************************************
3098 
3099  //**Resize struct definition********************************************************************
3102  template< size_t NewM // Number of rows of the other matrix
3103  , size_t NewN > // Number of columns of the other matrix
3104  struct Resize {
3106  };
3107  //**********************************************************************************************
3108 
3109  //**Compilation flags***************************************************************************
3111 
3114  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
3115  //**********************************************************************************************
3116 
3117  //**Constructors********************************************************************************
3120  explicit inline CompressedMatrix();
3121  explicit inline CompressedMatrix( size_t m, size_t n );
3122  explicit inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
3123  explicit CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
3124  inline CompressedMatrix( const CompressedMatrix& sm );
3125  inline CompressedMatrix( CompressedMatrix&& sm ) noexcept;
3126  template< typename MT, bool SO > inline CompressedMatrix( const DenseMatrix<MT,SO>& dm );
3127  template< typename MT, bool SO > inline CompressedMatrix( const SparseMatrix<MT,SO>& sm );
3129  //**********************************************************************************************
3130 
3131  //**Destructor**********************************************************************************
3134  inline ~CompressedMatrix();
3136  //**********************************************************************************************
3137 
3138  //**Data access functions***********************************************************************
3141  inline Reference operator()( size_t i, size_t j ) noexcept;
3142  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3143  inline Reference at( size_t i, size_t j );
3144  inline ConstReference at( size_t i, size_t j ) const;
3145  inline Iterator begin ( size_t i ) noexcept;
3146  inline ConstIterator begin ( size_t i ) const noexcept;
3147  inline ConstIterator cbegin( size_t i ) const noexcept;
3148  inline Iterator end ( size_t i ) noexcept;
3149  inline ConstIterator end ( size_t i ) const noexcept;
3150  inline ConstIterator cend ( size_t i ) const noexcept;
3152  //**********************************************************************************************
3153 
3154  //**Assignment operators************************************************************************
3157  inline CompressedMatrix& operator=( const CompressedMatrix& rhs );
3158  inline CompressedMatrix& operator=( CompressedMatrix&& rhs ) noexcept;
3159 
3160  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO>& rhs );
3161  template< typename MT, bool SO > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO>& rhs );
3162  template< typename MT, bool SO > inline CompressedMatrix& operator+=( const Matrix<MT,SO>& rhs );
3163  template< typename MT, bool SO > inline CompressedMatrix& operator-=( const Matrix<MT,SO>& rhs );
3164  template< typename MT, bool SO > inline CompressedMatrix& operator%=( const DenseMatrix<MT,SO>& rhs );
3165  template< typename MT, bool SO > inline CompressedMatrix& operator%=( const SparseMatrix<MT,SO>& rhs );
3166  template< typename MT, bool SO > inline CompressedMatrix& operator*=( const Matrix<MT,SO>& rhs );
3167 
3168  template< typename Other >
3169  inline EnableIf_< IsNumeric<Other>, CompressedMatrix >& operator*=( Other rhs );
3170 
3171  template< typename Other >
3172  inline EnableIf_< IsNumeric<Other>, CompressedMatrix >& operator/=( Other rhs );
3174  //**********************************************************************************************
3175 
3176  //**Utility functions***************************************************************************
3179  inline size_t rows() const noexcept;
3180  inline size_t columns() const noexcept;
3181  inline size_t capacity() const noexcept;
3182  inline size_t capacity( size_t j ) const noexcept;
3183  inline size_t nonZeros() const;
3184  inline size_t nonZeros( size_t j ) const;
3185  inline void reset();
3186  inline void reset( size_t j );
3187  inline void clear();
3188  void resize ( size_t m, size_t n, bool preserve=true );
3189  inline void reserve( size_t nonzeros );
3190  void reserve( size_t j, size_t nonzeros );
3191  inline void trim ();
3192  inline void trim ( size_t j );
3193  inline void shrinkToFit();
3194  inline void swap( CompressedMatrix& sm ) noexcept;
3196  //**********************************************************************************************
3197 
3198  //**Insertion functions*************************************************************************
3201  inline Iterator set ( size_t i, size_t j, const Type& value );
3202  inline Iterator insert ( size_t i, size_t j, const Type& value );
3203  inline void append ( size_t i, size_t j, const Type& value, bool check=false );
3204  inline void finalize( size_t j );
3206  //**********************************************************************************************
3207 
3208  //**Erase functions*****************************************************************************
3211  inline void erase( size_t i, size_t j );
3212  inline Iterator erase( size_t j, Iterator pos );
3213  inline Iterator erase( size_t j, Iterator first, Iterator last );
3214 
3215  template< typename Pred >
3216  inline void erase( Pred predicate );
3217 
3218  template< typename Pred >
3219  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
3221  //**********************************************************************************************
3222 
3223  //**Lookup functions****************************************************************************
3226  inline Iterator find ( size_t i, size_t j );
3227  inline ConstIterator find ( size_t i, size_t j ) const;
3228  inline Iterator lowerBound( size_t i, size_t j );
3229  inline ConstIterator lowerBound( size_t i, size_t j ) const;
3230  inline Iterator upperBound( size_t i, size_t j );
3231  inline ConstIterator upperBound( size_t i, size_t j ) const;
3233  //**********************************************************************************************
3234 
3235  //**Numeric functions***************************************************************************
3238  inline CompressedMatrix& transpose();
3239  inline CompressedMatrix& ctranspose();
3240 
3241  template< typename Other > inline CompressedMatrix& scale( const Other& scalar );
3242  template< typename Other > inline CompressedMatrix& scaleDiagonal( const Other& scalar );
3244  //**********************************************************************************************
3245 
3246  //**Expression template evaluation functions****************************************************
3249  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3250  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3251 
3252  inline bool canSMPAssign() const noexcept;
3253 
3254  template< typename MT, bool SO > inline void assign ( const DenseMatrix<MT,SO>& rhs );
3255  template< typename MT > inline void assign ( const SparseMatrix<MT,true>& rhs );
3256  template< typename MT > inline void assign ( const SparseMatrix<MT,false>& rhs );
3257  template< typename MT, bool SO > inline void addAssign ( const DenseMatrix<MT,SO>& rhs );
3258  template< typename MT, bool SO > inline void addAssign ( const SparseMatrix<MT,SO>& rhs );
3259  template< typename MT, bool SO > inline void subAssign ( const DenseMatrix<MT,SO>& rhs );
3260  template< typename MT, bool SO > inline void subAssign ( const SparseMatrix<MT,SO>& rhs );
3261  template< typename MT, bool SO > inline void schurAssign( const DenseMatrix<MT,SO>& rhs );
3263  //**********************************************************************************************
3264 
3265  private:
3266  //**Utility functions***************************************************************************
3269  inline size_t extendCapacity() const noexcept;
3270  void reserveElements( size_t nonzeros );
3271 
3272  inline Iterator castDown( IteratorBase it ) const noexcept;
3273  inline IteratorBase castUp ( Iterator it ) const noexcept;
3275  //**********************************************************************************************
3276 
3277  //**Insertion functions*************************************************************************
3280  Iterator insert( Iterator pos, size_t i, size_t j, const Type& value );
3282  //**********************************************************************************************
3283 
3284  //**Member variables****************************************************************************
3287  size_t m_;
3288  size_t n_;
3289  size_t capacity_;
3292 
3293  static const Type zero_;
3294 
3295  //**********************************************************************************************
3296 
3297  //**Compile time checks*************************************************************************
3305  //**********************************************************************************************
3306 };
3308 //*************************************************************************************************
3309 
3310 
3311 
3312 
3313 //=================================================================================================
3314 //
3315 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
3316 //
3317 //=================================================================================================
3318 
3319 template< typename Type >
3320 const Type CompressedMatrix<Type,true>::zero_ = Type();
3321 
3322 
3323 
3324 
3325 //=================================================================================================
3326 //
3327 // CONSTRUCTORS
3328 //
3329 //=================================================================================================
3330 
3331 //*************************************************************************************************
3335 template< typename Type > // Data type of the matrix
3337  : m_ ( 0UL ) // The current number of rows of the compressed matrix
3338  , n_ ( 0UL ) // The current number of columns of the compressed matrix
3339  , capacity_( 0UL ) // The current capacity of the pointer array
3340  , begin_ ( nullptr ) // Pointers to the first non-zero element of each column
3341  , end_ ( nullptr ) // Pointers one past the last non-zero element of each column
3342 {}
3344 //*************************************************************************************************
3345 
3346 
3347 //*************************************************************************************************
3356 template< typename Type > // Data type of the matrix
3357 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n )
3358  : m_ ( m ) // The current number of rows of the compressed matrix
3359  , n_ ( n ) // The current number of columns of the compressed matrix
3360  , capacity_( n ) // The current capacity of the pointer array
3361  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
3362  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
3363 {
3364  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
3365  begin_[j] = nullptr;
3366 }
3368 //*************************************************************************************************
3369 
3370 
3371 //*************************************************************************************************
3381 template< typename Type > // Data type of the matrix
3382 inline CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
3383  : m_ ( m ) // The current number of rows of the compressed matrix
3384  , n_ ( n ) // The current number of columns of the compressed matrix
3385  , capacity_( n ) // The current capacity of the pointer array
3386  , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
3387  , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
3388 {
3389  begin_[0UL] = allocate<Element>( nonzeros );
3390  for( size_t j=1UL; j<(2UL*n_+1UL); ++j )
3391  begin_[j] = begin_[0UL];
3392  end_[n_] = begin_[0UL]+nonzeros;
3393 }
3395 //*************************************************************************************************
3396 
3397 
3398 //*************************************************************************************************
3409 template< typename Type > // Data type of the matrix
3410 CompressedMatrix<Type,true>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
3411  : m_ ( m ) // The current number of rows of the compressed matrix
3412  , n_ ( n ) // The current number of columns of the compressed matrix
3413  , capacity_( n ) // The current capacity of the pointer array
3414  , begin_( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
3415  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
3416 {
3417  BLAZE_USER_ASSERT( nonzeros.size() == n, "Size of capacity vector and number of columns don't match" );
3418 
3419  size_t newCapacity( 0UL );
3420  for( std::vector<size_t>::const_iterator it=nonzeros.begin(); it!=nonzeros.end(); ++it )
3421  newCapacity += *it;
3422 
3423  begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
3424  for( size_t j=0UL; j<n_; ++j ) {
3425  begin_[j+1UL] = end_[j+1UL] = begin_[j] + nonzeros[j];
3426  }
3427 }
3429 //*************************************************************************************************
3430 
3431 
3432 //*************************************************************************************************
3438 template< typename Type > // Data type of the matrix
3440  : m_ ( sm.m_ ) // The current number of rows of the compressed matrix
3441  , n_ ( sm.n_ ) // The current number of columns of the compressed matrix
3442  , capacity_( sm.n_ ) // The current capacity of the pointer array
3443  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
3444  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
3445 {
3446  const size_t nonzeros( sm.nonZeros() );
3447 
3448  begin_[0UL] = allocate<Element>( nonzeros );
3449  for( size_t j=0UL; j<n_; ++j ) {
3450  end_[j] = castDown( std::copy( sm.begin(j), sm.end(j), castUp( begin_[j] ) ) );
3451  begin_[j+1UL] = end_[j];
3452  }
3453  end_[n_] = begin_[0UL]+nonzeros;
3454 }
3456 //*************************************************************************************************
3457 
3458 
3459 //*************************************************************************************************
3465 template< typename Type > // Data type of the matrix
3467  : m_ ( sm.m_ ) // The current number of rows of the compressed matrix
3468  , n_ ( sm.n_ ) // The current number of columns of the compressed matrix
3469  , capacity_( sm.capacity_ ) // The current capacity of the pointer array
3470  , begin_ ( sm.begin_ ) // Pointers to the first non-zero element of each column
3471  , end_ ( sm.end_ ) // Pointers one past the last non-zero element of each column
3472 {
3473  sm.m_ = 0UL;
3474  sm.n_ = 0UL;
3475  sm.capacity_ = 0UL;
3476  sm.begin_ = nullptr;
3477  sm.end_ = nullptr;
3478 }
3480 //*************************************************************************************************
3481 
3482 
3483 //*************************************************************************************************
3489 template< typename Type > // Data type of the matrix
3490 template< typename MT // Type of the foreign dense matrix
3491  , bool SO > // Storage order of the foreign dense matrix
3493  : m_ ( (~dm).rows() ) // The current number of rows of the compressed matrix
3494  , n_ ( (~dm).columns() ) // The current number of columns of the compressed matrix
3495  , capacity_( n_ ) // The current capacity of the pointer array
3496  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
3497  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
3498 {
3499  using blaze::assign;
3500 
3501  for( size_t j=0UL; j<2UL*n_+2UL; ++j )
3502  begin_[j] = nullptr;
3503 
3504  assign( *this, ~dm );
3505 }
3507 //*************************************************************************************************
3508 
3509 
3510 //*************************************************************************************************
3516 template< typename Type > // Data type of the matrix
3517 template< typename MT // Type of the foreign compressed matrix
3518  , bool SO > // Storage order of the foreign compressed matrix
3520  : m_ ( (~sm).rows() ) // The current number of rows of the compressed matrix
3521  , n_ ( (~sm).columns() ) // The current number of columns of the compressed matrix
3522  , capacity_( n_ ) // The current capacity of the pointer array
3523  , begin_ ( new Iterator[2UL*n_+2UL] ) // Pointers to the first non-zero element of each column
3524  , end_ ( begin_+(n_+1UL) ) // Pointers one past the last non-zero element of each column
3525 {
3526  using blaze::assign;
3527 
3528  const size_t nonzeros( (~sm).nonZeros() );
3529 
3530  begin_[0UL] = allocate<Element>( nonzeros );
3531  for( size_t j=0UL; j<n_; ++j )
3532  begin_[j+1UL] = end_[j] = begin_[0UL];
3533  end_[n_] = begin_[0UL]+nonzeros;
3534 
3535  assign( *this, ~sm );
3536 }
3538 //*************************************************************************************************
3539 
3540 
3541 
3542 
3543 //=================================================================================================
3544 //
3545 // DESTRUCTOR
3546 //
3547 //=================================================================================================
3548 
3549 //*************************************************************************************************
3553 template< typename Type > // Data type of the matrix
3555 {
3556  if( begin_ != nullptr ) {
3557  deallocate( begin_[0UL] );
3558  delete[] begin_;
3559  }
3560 }
3562 //*************************************************************************************************
3563 
3564 
3565 
3566 
3567 //=================================================================================================
3568 //
3569 // DATA ACCESS FUNCTIONS
3570 //
3571 //=================================================================================================
3572 
3573 //*************************************************************************************************
3587 template< typename Type > // Data type of the matrix
3589  CompressedMatrix<Type,true>::operator()( size_t i, size_t j ) noexcept
3590 {
3591  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3592  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3593 
3594  return Reference( *this, i, j );
3595 }
3597 //*************************************************************************************************
3598 
3599 
3600 //*************************************************************************************************
3611 template< typename Type > // Data type of the matrix
3613  CompressedMatrix<Type,true>::operator()( size_t i, size_t j ) const noexcept
3614 {
3615  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3616  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3617 
3618  const ConstIterator pos( lowerBound( i, j ) );
3619 
3620  if( pos == end_[j] || pos->index_ != i )
3621  return zero_;
3622  else
3623  return pos->value_;
3624 }
3626 //*************************************************************************************************
3627 
3628 
3629 //*************************************************************************************************
3643 template< typename Type > // Data type of the matrix
3645  CompressedMatrix<Type,true>::at( size_t i, size_t j )
3646 {
3647  if( i >= m_ ) {
3648  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3649  }
3650  if( j >= n_ ) {
3651  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3652  }
3653  return (*this)(i,j);
3654 }
3656 //*************************************************************************************************
3657 
3658 
3659 //*************************************************************************************************
3671 template< typename Type > // Data type of the matrix
3673  CompressedMatrix<Type,true>::at( size_t i, size_t j ) const
3674 {
3675  if( i >= m_ ) {
3676  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3677  }
3678  if( j >= n_ ) {
3679  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3680  }
3681  return (*this)(i,j);
3682 }
3684 //*************************************************************************************************
3685 
3686 
3687 //*************************************************************************************************
3694 template< typename Type > // Data type of the matrix
3696  CompressedMatrix<Type,true>::begin( size_t j ) noexcept
3697 {
3698  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3699  return begin_[j];
3700 }
3702 //*************************************************************************************************
3703 
3704 
3705 //*************************************************************************************************
3712 template< typename Type > // Data type of the matrix
3714  CompressedMatrix<Type,true>::begin( size_t j ) const noexcept
3715 {
3716  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3717  return begin_[j];
3718 }
3720 //*************************************************************************************************
3721 
3722 
3723 //*************************************************************************************************
3730 template< typename Type > // Data type of the matrix
3732  CompressedMatrix<Type,true>::cbegin( size_t j ) const noexcept
3733 {
3734  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3735  return begin_[j];
3736 }
3738 //*************************************************************************************************
3739 
3740 
3741 //*************************************************************************************************
3748 template< typename Type > // Data type of the matrix
3750  CompressedMatrix<Type,true>::end( size_t j ) noexcept
3751 {
3752  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3753  return end_[j];
3754 }
3756 //*************************************************************************************************
3757 
3758 
3759 //*************************************************************************************************
3766 template< typename Type > // Data type of the matrix
3768  CompressedMatrix<Type,true>::end( size_t j ) const noexcept
3769 {
3770  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3771  return end_[j];
3772 }
3774 //*************************************************************************************************
3775 
3776 
3777 //*************************************************************************************************
3784 template< typename Type > // Data type of the matrix
3786  CompressedMatrix<Type,true>::cend( size_t j ) const noexcept
3787 {
3788  BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3789  return end_[j];
3790 }
3792 //*************************************************************************************************
3793 
3794 
3795 
3796 
3797 //=================================================================================================
3798 //
3799 // ASSIGNMENT OPERATORS
3800 //
3801 //=================================================================================================
3802 
3803 //*************************************************************************************************
3813 template< typename Type > // Data type of the matrix
3816 {
3817  if( &rhs == this ) return *this;
3818 
3819  const size_t nonzeros( rhs.nonZeros() );
3820 
3821  if( rhs.n_ > capacity_ || nonzeros > capacity() )
3822  {
3823  Iterator* newBegin( new Iterator[2UL*rhs.n_+2UL] );
3824  Iterator* newEnd ( newBegin+(rhs.n_+1UL) );
3825 
3826  newBegin[0UL] = allocate<Element>( nonzeros );
3827  for( size_t j=0UL; j<rhs.n_; ++j ) {
3828  newEnd[j] = castDown( std::copy( rhs.begin_[j], rhs.end_[j], castUp( newBegin[j] ) ) );
3829  newBegin[j+1UL] = newEnd[j];
3830  }
3831  newEnd[rhs.n_] = newBegin[0UL]+nonzeros;
3832 
3833  std::swap( begin_, newBegin );
3834  end_ = newEnd;
3835  capacity_ = rhs.n_;
3836 
3837  if( newBegin != nullptr ) {
3838  deallocate( newBegin[0UL] );
3839  delete[] newBegin;
3840  }
3841  }
3842  else {
3843  for( size_t j=0UL; j<rhs.n_; ++j ) {
3844  end_[j] = castDown( std::copy( rhs.begin_[j], rhs.end_[j], castUp( begin_[j] ) ) );
3845  begin_[j+1UL] = end_[j];
3846  }
3847  }
3848 
3849  m_ = rhs.m_;
3850  n_ = rhs.n_;
3851 
3852  return *this;
3853 }
3855 //*************************************************************************************************
3856 
3857 
3858 //*************************************************************************************************
3865 template< typename Type > // Data type of the matrix
3868 {
3869  if( begin_ != nullptr ) {
3870  deallocate( begin_[0UL] );
3871  delete[] begin_;
3872  }
3873 
3874  m_ = rhs.m_;
3875  n_ = rhs.n_;
3876  capacity_ = rhs.capacity_;
3877  begin_ = rhs.begin_;
3878  end_ = rhs.end_;
3879 
3880  rhs.m_ = 0UL;
3881  rhs.n_ = 0UL;
3882  rhs.capacity_ = 0UL;
3883  rhs.begin_ = nullptr;
3884  rhs.end_ = nullptr;
3885 
3886  return *this;
3887 }
3889 //*************************************************************************************************
3890 
3891 
3892 //*************************************************************************************************
3902 template< typename Type > // Data type of the matrix
3903 template< typename MT // Type of the right-hand side dense matrix
3904  , bool SO > // Storage order of the right-hand side dense matrix
3907 {
3908  using blaze::assign;
3909 
3910  if( (~rhs).canAlias( this ) ) {
3911  CompressedMatrix tmp( ~rhs );
3912  swap( tmp );
3913  }
3914  else {
3915  resize( (~rhs).rows(), (~rhs).columns(), false );
3916  assign( *this, ~rhs );
3917  }
3918 
3919  return *this;
3920 }
3922 //*************************************************************************************************
3923 
3924 
3925 //*************************************************************************************************
3935 template< typename Type > // Data type of the matrix
3936 template< typename MT // Type of the right-hand side compressed matrix
3937  , bool SO > // Storage order of the right-hand side compressed matrix
3940 {
3941  using blaze::assign;
3942 
3943  if( (~rhs).canAlias( this ) ||
3944  (~rhs).columns() > capacity_ ||
3945  (~rhs).nonZeros() > capacity() ) {
3946  CompressedMatrix tmp( ~rhs );
3947  swap( tmp );
3948  }
3949  else {
3950  resize( (~rhs).rows(), (~rhs).columns(), false );
3951  reset();
3952  assign( *this, ~rhs );
3953  }
3954 
3955  return *this;
3956 }
3958 //*************************************************************************************************
3959 
3960 
3961 //*************************************************************************************************
3972 template< typename Type > // Data type of the matrix
3973 template< typename MT // Type of the right-hand side matrix
3974  , bool SO > // Storage order of the right-hand side matrix
3976 {
3977  using blaze::addAssign;
3978 
3979  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
3980  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3981  }
3982 
3983  addAssign( *this, ~rhs );
3984  return *this;
3985 }
3987 //*************************************************************************************************
3988 
3989 
3990 //*************************************************************************************************
4001 template< typename Type > // Data type of the matrix
4002 template< typename MT // Type of the right-hand side matrix
4003  , bool SO > // Storage order of the right-hand side matrix
4005 {
4006  using blaze::subAssign;
4007 
4008  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4009  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4010  }
4011 
4012  subAssign( *this, ~rhs );
4013  return *this;
4014 }
4016 //*************************************************************************************************
4017 
4018 
4019 //*************************************************************************************************
4031 template< typename Type > // Data type of the matrix
4032 template< typename MT // Type of the right-hand side dense matrix
4033  , bool SO > // Storage order of the right-hand side dense matrix
4036 {
4037  using blaze::schurAssign;
4038 
4039  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4040  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4041  }
4042 
4043  if( (~rhs).canAlias( this ) ) {
4044  CompressedMatrix tmp( *this % (~rhs) );
4045  swap( tmp );
4046  }
4047  else {
4048  CompositeType_<MT> tmp( ~rhs );
4049  schurAssign( *this, tmp );
4050  }
4051 
4052  return *this;
4053 }
4055 //*************************************************************************************************
4056 
4057 
4058 //*************************************************************************************************
4070 template< typename Type > // Data type of the matrix
4071 template< typename MT // Type of the right-hand side sparse matrix
4072  , bool SO > // Storage order of the right-hand side sparse matrix
4075 {
4076  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4077  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4078  }
4079 
4080  CompressedMatrix tmp( *this % (~rhs) );
4081  swap( tmp );
4082 
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
4105 {
4106  if( (~rhs).rows() != n_ ) {
4107  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4108  }
4109 
4110  CompressedMatrix tmp( *this * (~rhs) );
4111  swap( tmp );
4112 
4113  return *this;
4114 }
4116 //*************************************************************************************************
4117 
4118 
4119 //*************************************************************************************************
4127 template< typename Type > // Data type of the matrix
4128 template< typename Other > // Data type of the right-hand side scalar
4129 inline EnableIf_< IsNumeric<Other>, CompressedMatrix<Type,true> >&
4131 {
4132  for( size_t j=0UL; j<n_; ++j ) {
4133  const Iterator last( end(j) );
4134  for( Iterator element=begin(j); element!=last; ++element )
4135  element->value_ *= rhs;
4136  }
4137  return *this;
4138 }
4140 //*************************************************************************************************
4141 
4142 
4143 //*************************************************************************************************
4151 template< typename Type > // Data type of the matrix
4152 template< typename Other > // Data type of the right-hand side scalar
4153 inline EnableIf_< IsNumeric<Other>, CompressedMatrix<Type,true> >&
4154  CompressedMatrix<Type,true>::operator/=( Other rhs )
4155 {
4156  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4157 
4158  using DT = DivTrait_<Type,Other>;
4159  using Tmp = If_< IsNumeric<DT>, DT, Other >;
4160 
4161  // Depending on the two involved data types, an integer division is applied or a
4162  // floating point division is selected.
4163  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
4164  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
4165  for( size_t j=0UL; j<n_; ++j ) {
4166  const Iterator last( end(j) );
4167  for( Iterator element=begin(j); element!=last; ++element )
4168  element->value_ *= tmp;
4169  }
4170  }
4171  else {
4172  for( size_t j=0UL; j<n_; ++j ) {
4173  const Iterator last( end(j) );
4174  for( Iterator element=begin(j); element!=last; ++element )
4175  element->value_ /= rhs;
4176  }
4177  }
4178 
4179  return *this;
4180 }
4182 //*************************************************************************************************
4183 
4184 
4185 
4186 
4187 //=================================================================================================
4188 //
4189 // UTILITY FUNCTIONS
4190 //
4191 //=================================================================================================
4192 
4193 //*************************************************************************************************
4199 template< typename Type > // Data type of the matrix
4200 inline size_t CompressedMatrix<Type,true>::rows() const noexcept
4201 {
4202  return m_;
4203 }
4205 //*************************************************************************************************
4206 
4207 
4208 //*************************************************************************************************
4214 template< typename Type > // Data type of the matrix
4215 inline size_t CompressedMatrix<Type,true>::columns() const noexcept
4216 {
4217  return n_;
4218 }
4220 //*************************************************************************************************
4221 
4222 
4223 //*************************************************************************************************
4229 template< typename Type > // Data type of the matrix
4230 inline size_t CompressedMatrix<Type,true>::capacity() const noexcept
4231 {
4232  if( begin_ != nullptr )
4233  return end_[n_] - begin_[0UL];
4234  else return 0UL;
4235 }
4237 //*************************************************************************************************
4238 
4239 
4240 //*************************************************************************************************
4247 template< typename Type > // Data type of the matrix
4248 inline size_t CompressedMatrix<Type,true>::capacity( size_t j ) const noexcept
4249 {
4250  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4251  return begin_[j+1UL] - begin_[j];
4252 }
4254 //*************************************************************************************************
4255 
4256 
4257 //*************************************************************************************************
4263 template< typename Type > // Data type of the matrix
4264 inline size_t CompressedMatrix<Type,true>::nonZeros() const
4265 {
4266  size_t nonzeros( 0UL );
4267 
4268  for( size_t j=0UL; j<n_; ++j )
4269  nonzeros += nonZeros( j );
4270 
4271  return nonzeros;
4272 }
4274 //*************************************************************************************************
4275 
4276 
4277 //*************************************************************************************************
4284 template< typename Type > // Data type of the matrix
4285 inline size_t CompressedMatrix<Type,true>::nonZeros( size_t j ) const
4286 {
4287  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4288  return end_[j] - begin_[j];
4289 }
4291 //*************************************************************************************************
4292 
4293 
4294 //*************************************************************************************************
4300 template< typename Type > // Data type of the matrix
4302 {
4303  for( size_t j=0UL; j<n_; ++j )
4304  end_[j] = begin_[j];
4305 }
4307 //*************************************************************************************************
4308 
4309 
4310 //*************************************************************************************************
4320 template< typename Type > // Data type of the matrix
4321 inline void CompressedMatrix<Type,true>::reset( size_t j )
4322 {
4323  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4324  end_[j] = begin_[j];
4325 }
4327 //*************************************************************************************************
4328 
4329 
4330 //*************************************************************************************************
4338 template< typename Type > // Data type of the matrix
4340 {
4341  if( end_ != nullptr )
4342  end_[0UL] = end_[n_];
4343  m_ = 0UL;
4344  n_ = 0UL;
4345 }
4347 //*************************************************************************************************
4348 
4349 
4350 //*************************************************************************************************
4366 template< typename Type > // Data type of the matrix
4367 void CompressedMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
4368 {
4369  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4370  BLAZE_INTERNAL_ASSERT( begin_ == nullptr || size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4371 
4372  if( m == m_ && n == n_ ) return;
4373 
4374  if( begin_ == nullptr )
4375  {
4376  begin_ = new Iterator[2UL*n+2UL];
4377  end_ = begin_+n+1UL;
4378 
4379  for( size_t j=0UL; j<2UL*n+2UL; ++j ) {
4380  begin_[j] = nullptr;
4381  }
4382 
4383  capacity_ = n;
4384  }
4385  else if( n > capacity_ )
4386  {
4387  Iterator* newBegin( new Iterator[2UL*n+2UL] );
4388  Iterator* newEnd ( newBegin+n+1UL );
4389 
4390  newBegin[0UL] = begin_[0UL];
4391 
4392  if( preserve ) {
4393  for( size_t j=0UL; j<n_; ++j ) {
4394  newEnd [j] = end_ [j];
4395  newBegin[j+1UL] = begin_[j+1UL];
4396  }
4397  for( size_t j=n_; j<n; ++j ) {
4398  newBegin[j+1UL] = newEnd[j] = begin_[n_];
4399  }
4400  }
4401  else {
4402  for( size_t j=0UL; j<n; ++j ) {
4403  newBegin[j+1UL] = newEnd[j] = begin_[0UL];
4404  }
4405  }
4406 
4407  newEnd[n] = end_[n_];
4408 
4409  std::swap( newBegin, begin_ );
4410  delete[] newBegin;
4411  end_ = newEnd;
4412  capacity_ = n;
4413  }
4414  else if( n > n_ )
4415  {
4416  end_[n] = end_[n_];
4417 
4418  if( !preserve ) {
4419  for( size_t j=0UL; j<n_; ++j )
4420  end_[j] = begin_[j];
4421  }
4422 
4423  for( size_t j=n_; j<n; ++j ) {
4424  begin_[j+1UL] = end_[j] = begin_[n_];
4425  }
4426  }
4427  else
4428  {
4429  if( preserve ) {
4430  for( size_t j=0UL; j<n; ++j )
4431  end_[j] = lowerBound( m, j );
4432  }
4433  else {
4434  for( size_t j=0UL; j<n; ++j )
4435  end_[j] = begin_[j];
4436  }
4437 
4438  end_[n] = end_[n_];
4439  }
4440 
4441  m_ = m;
4442  n_ = n;
4443 
4444  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4445  BLAZE_INTERNAL_ASSERT( size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4446 }
4448 //*************************************************************************************************
4449 
4450 
4451 //*************************************************************************************************
4462 template< typename Type > // Data type of the matrix
4463 inline void CompressedMatrix<Type,true>::reserve( size_t nonzeros )
4464 {
4465  if( nonzeros > capacity() )
4466  reserveElements( nonzeros );
4467 }
4469 //*************************************************************************************************
4470 
4471 
4472 //*************************************************************************************************
4484 template< typename Type > // Data type of the matrix
4485 void CompressedMatrix<Type,true>::reserve( size_t j, size_t nonzeros )
4486 {
4487  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4488 
4489  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4490  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4491 
4492  const size_t current( capacity(j) );
4493 
4494  if( current >= nonzeros ) return;
4495 
4496  const ptrdiff_t additional( nonzeros - current );
4497 
4498  if( end_[n_] - begin_[n_] < additional )
4499  {
4500  const size_t newCapacity( begin_[n_] - begin_[0UL] + additional );
4501  BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
4502 
4503  Iterator* newBegin( new Iterator[2UL*n_+2UL] );
4504  Iterator* newEnd ( newBegin+n_+1UL );
4505 
4506  newBegin[0UL] = allocate<Element>( newCapacity );
4507  newEnd [n_ ] = newBegin[0UL]+newCapacity;
4508 
4509  for( size_t k=0UL; k<j; ++k ) {
4510  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4511  newBegin[k+1UL] = newBegin[k] + capacity(k);
4512  }
4513  newEnd [j ] = castDown( transfer( begin_[j], end_[j], castUp( newBegin[j] ) ) );
4514  newBegin[j+1UL] = newBegin[j] + nonzeros;
4515  for( size_t k=j+1UL; k<n_; ++k ) {
4516  newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4517  newBegin[k+1UL] = newBegin[k] + capacity(k);
4518  }
4519 
4520  BLAZE_INTERNAL_ASSERT( newBegin[n_] == newEnd[n_], "Invalid pointer calculations" );
4521 
4522  std::swap( newBegin, begin_ );
4523  deallocate( newBegin[0UL] );
4524  delete[] newBegin;
4525  end_ = newEnd;
4526  capacity_ = n_;
4527  }
4528  else
4529  {
4530  begin_[n_] += additional;
4531  for( size_t k=n_-1UL; k>j; --k ) {
4532  begin_[k] = castDown( std::move_backward( begin_[k], end_[k], castUp( end_[k]+additional ) ) );
4533  end_ [k] += additional;
4534  }
4535  }
4536 
4537  BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4538  BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4539 }
4541 //*************************************************************************************************
4542 
4543 
4544 //*************************************************************************************************
4554 template< typename Type > // Data type of the matrix
4556 {
4557  for( size_t j=0UL; j<n_; ++j )
4558  trim( j );
4559 }
4561 //*************************************************************************************************
4562 
4563 
4564 //*************************************************************************************************
4575 template< typename Type > // Data type of the matrix
4576 void CompressedMatrix<Type,true>::trim( size_t j )
4577 {
4578  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4579 
4580  if( j < ( n_ - 1UL ) )
4581  end_[j+1] = castDown( std::move( begin_[j+1], end_[j+1], castUp( end_[j] ) ) );
4582  begin_[j+1] = end_[j];
4583 }
4585 //*************************************************************************************************
4586 
4587 
4588 //*************************************************************************************************
4598 template< typename Type > // Data type of the matrix
4600 {
4601  if( nonZeros() < capacity() ) {
4602  CompressedMatrix( *this ).swap( *this );
4603  }
4604 }
4606 //*************************************************************************************************
4607 
4608 
4609 //*************************************************************************************************
4616 template< typename Type > // Data type of the matrix
4617 inline void CompressedMatrix<Type,true>::swap( CompressedMatrix& sm ) noexcept
4618 {
4619  std::swap( m_, sm.m_ );
4620  std::swap( n_, sm.n_ );
4621  std::swap( capacity_, sm.capacity_ );
4622  std::swap( begin_, sm.begin_ );
4623  std::swap( end_ , sm.end_ );
4624 }
4626 //*************************************************************************************************
4627 
4628 
4629 //*************************************************************************************************
4638 template< typename Type > // Data type of the matrix
4639 inline size_t CompressedMatrix<Type,true>::extendCapacity() const noexcept
4640 {
4641  size_t nonzeros( 2UL*capacity()+1UL );
4642  nonzeros = blaze::max( nonzeros, 7UL );
4643 
4644  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
4645 
4646  return nonzeros;
4647 }
4649 //*************************************************************************************************
4650 
4651 
4652 //*************************************************************************************************
4659 template< typename Type > // Data type of the matrix
4660 void CompressedMatrix<Type,true>::reserveElements( size_t nonzeros )
4661 {
4662  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
4663  Iterator* newEnd = newBegin+capacity_+1UL;
4664 
4665  newBegin[0UL] = allocate<Element>( nonzeros );
4666 
4667  for( size_t k=0UL; k<n_; ++k ) {
4668  BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid column pointers" );
4669  newEnd [k] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4670  newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
4671  }
4672 
4673  newEnd[n_] = newBegin[0UL]+nonzeros;
4674 
4675  std::swap( newBegin, begin_ );
4676  end_ = newEnd;
4677 
4678  if( newBegin != nullptr ) {
4679  deallocate( newBegin[0UL] );
4680  delete[] newBegin;
4681  }
4682 }
4684 //*************************************************************************************************
4685 
4686 
4687 //*************************************************************************************************
4695 template< typename Type > // Data type of the matrix
4697  CompressedMatrix<Type,true>::castDown( IteratorBase it ) const noexcept
4698 {
4699  return static_cast<Iterator>( it );
4700 }
4701 //*************************************************************************************************
4702 
4703 
4704 //*************************************************************************************************
4712 template< typename Type > // Data type of the matrix
4714  CompressedMatrix<Type,true>::castUp( Iterator it ) const noexcept
4715 {
4716  return static_cast<IteratorBase>( it );
4717 }
4718 //*************************************************************************************************
4719 
4720 
4721 
4722 
4723 //=================================================================================================
4724 //
4725 // INSERTION FUNCTIONS
4726 //
4727 //=================================================================================================
4728 
4729 //*************************************************************************************************
4742 template< typename Type > // Data type of the matrix
4744  CompressedMatrix<Type,true>::set( size_t i, size_t j, const Type& value )
4745 {
4746  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4747  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4748 
4749  const Iterator pos( lowerBound( i, j ) );
4750 
4751  if( pos != end_[j] && pos->index_ == i ) {
4752  pos->value() = value;
4753  return pos;
4754  }
4755  else return insert( pos, i, j, value );
4756 }
4758 //*************************************************************************************************
4759 
4760 
4761 //*************************************************************************************************
4775 template< typename Type > // Data type of the matrix
4777  CompressedMatrix<Type,true>::insert( size_t i, size_t j, const Type& value )
4778 {
4779  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4780  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4781 
4782  const Iterator pos( lowerBound( i, j ) );
4783 
4784  if( pos != end_[j] && pos->index_ == i ) {
4785  BLAZE_THROW_INVALID_ARGUMENT( "Bad access index" );
4786  }
4787 
4788  return insert( pos, i, j, value );
4789 }
4791 //*************************************************************************************************
4792 
4793 
4794 //*************************************************************************************************
4805 template< typename Type > // Data type of the matrix
4807  CompressedMatrix<Type,true>::insert( Iterator pos, size_t i, size_t j, const Type& value )
4808 {
4809  if( begin_[j+1UL] - end_[j] != 0 ) {
4810  std::move_backward( pos, end_[j], castUp( end_[j]+1UL ) );
4811  pos->value_ = value;
4812  pos->index_ = i;
4813  ++end_[j];
4814 
4815  return pos;
4816  }
4817  else if( end_[n_] - begin_[n_] != 0 ) {
4818  std::move_backward( pos, end_[n_-1UL], castUp( end_[n_-1]+1UL ) );
4819 
4820  pos->value_ = value;
4821  pos->index_ = i;
4822 
4823  for( size_t k=j+1UL; k<n_+1UL; ++k ) {
4824  ++begin_[k];
4825  ++end_[k-1UL];
4826  }
4827 
4828  return pos;
4829  }
4830  else {
4831  size_t newCapacity( extendCapacity() );
4832 
4833  Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
4834  Iterator* newEnd = newBegin+capacity_+1UL;
4835 
4836  newBegin[0UL] = allocate<Element>( newCapacity );
4837 
4838  for( size_t k=0UL; k<j; ++k ) {
4839  const size_t nonzeros( end_[k] - begin_[k] );
4840  const size_t total( begin_[k+1UL] - begin_[k] );
4841  newEnd [k] = newBegin[k] + nonzeros;
4842  newBegin[k+1UL] = newBegin[k] + total;
4843  }
4844  newEnd [j] = newBegin[j] + ( end_[j] - begin_[j] ) + 1;
4845  newBegin[j+1UL] = newBegin[j] + ( begin_[j+1UL] - begin_[j] ) + 1;
4846  for( size_t k=j+1UL; k<n_; ++k ) {
4847  const size_t nonzeros( end_[k] - begin_[k] );
4848  const size_t total( begin_[k+1UL] - begin_[k] );
4849  newEnd [k] = newBegin[k] + nonzeros;
4850  newBegin[k+1UL] = newBegin[k] + total;
4851  }
4852 
4853  newEnd[n_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
4854 
4855  Iterator tmp = castDown( std::move( begin_[0UL], pos, castUp( newBegin[0UL] ) ) );
4856  tmp->value_ = value;
4857  tmp->index_ = i;
4858  std::move( pos, end_[n_-1UL], castUp( tmp+1UL ) );
4859 
4860  std::swap( newBegin, begin_ );
4861  end_ = newEnd;
4862  deallocate( newBegin[0UL] );
4863  delete[] newBegin;
4864 
4865  return tmp;
4866  }
4867 }
4869 //*************************************************************************************************
4870 
4871 
4872 //*************************************************************************************************
4925 template< typename Type > // Data type of the matrix
4926 inline void CompressedMatrix<Type,true>::append( size_t i, size_t j, const Type& value, bool check )
4927 {
4928  BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
4929  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
4930  BLAZE_USER_ASSERT( end_[j] < end_[n_], "Not enough reserved capacity left" );
4931  BLAZE_USER_ASSERT( begin_[j] == end_[j] || i > ( end_[j]-1UL )->index_, "Index is not strictly increasing" );
4932 
4933  end_[j]->value_ = value;
4934 
4935  if( !check || !isDefault<strict>( end_[j]->value_ ) ) {
4936  end_[j]->index_ = i;
4937  ++end_[j];
4938  }
4939 }
4941 //*************************************************************************************************
4942 
4943 
4944 //*************************************************************************************************
4958 template< typename Type > // Data type of the matrix
4959 inline void CompressedMatrix<Type,true>::finalize( size_t j )
4960 {
4961  BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
4962 
4963  begin_[j+1UL] = end_[j];
4964  if( j != n_-1UL )
4965  end_[j+1UL] = end_[j];
4966 }
4968 //*************************************************************************************************
4969 
4970 
4971 
4972 
4973 //=================================================================================================
4974 //
4975 // ERASE FUNCTIONS
4976 //
4977 //=================================================================================================
4978 
4979 //*************************************************************************************************
4989 template< typename Type > // Data type of the matrix
4990 inline void CompressedMatrix<Type,true>::erase( size_t i, size_t j )
4991 {
4992  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4993  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4994 
4995  const Iterator pos( find( i, j ) );
4996  if( pos != end_[j] )
4997  end_[j] = castDown( std::move( pos+1, end_[j], castUp( pos ) ) );
4998 }
5000 //*************************************************************************************************
5001 
5002 
5003 //*************************************************************************************************
5013 template< typename Type > // Data type of the matrix
5016 {
5017  BLAZE_USER_ASSERT( j < columns() , "Invalid column access index" );
5018  BLAZE_USER_ASSERT( pos >= begin_[j] && pos <= end_[j], "Invalid compressed matrix iterator" );
5019 
5020  if( pos != end_[j] )
5021  end_[j] = castDown( std::move( pos+1, end_[j], castUp( pos ) ) );
5022 
5023  return pos;
5024 }
5026 //*************************************************************************************************
5027 
5028 
5029 //*************************************************************************************************
5040 template< typename Type > // Data type of the matrix
5042  CompressedMatrix<Type,true>::erase( size_t j, Iterator first, Iterator last )
5043 {
5044  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5045  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
5046  BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j], "Invalid compressed matrix iterator" );
5047  BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j], "Invalid compressed matrix iterator" );
5048 
5049  if( first != last )
5050  end_[j] = castDown( std::move( last, end_[j], castUp( first ) ) );
5051 
5052  return first;
5053 }
5055 //*************************************************************************************************
5056 
5057 
5058 //*************************************************************************************************
5080 template< typename Type > // Data type of the matrix
5081 template< typename Pred > // Type of the unary predicate
5082 inline void CompressedMatrix<Type,true>::erase( Pred predicate )
5083 {
5084  for( size_t j=0UL; j<n_; ++j ) {
5085  end_[j] = castDown( std::remove_if( castUp( begin_[j] ), castUp( end_[j] ),
5086  [predicate=predicate]( const ElementBase& element ) {
5087  return predicate( element.value() );
5088  } ) );
5089  }
5090 }
5092 //*************************************************************************************************
5093 
5094 
5095 //*************************************************************************************************
5120 template< typename Type > // Data type of the matrix
5121 template< typename Pred > // Type of the unary predicate
5122 inline void CompressedMatrix<Type,true>::erase( size_t j, Iterator first, Iterator last, Pred predicate )
5123 {
5124  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5125  BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
5126  BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j], "Invalid compressed matrix iterator" );
5127  BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j], "Invalid compressed matrix iterator" );
5128 
5129  const auto pos = std::remove_if( castUp( first ), castUp( last ),
5130  [predicate=predicate]( const ElementBase& element ) {
5131  return predicate( element.value() );
5132  } );
5133 
5134  end_[j] = castDown( std::move( last, end_[j], pos ) );
5135 }
5137 //*************************************************************************************************
5138 
5139 
5140 
5141 
5142 //=================================================================================================
5143 //
5144 // LOOKUP FUNCTIONS
5145 //
5146 //=================================================================================================
5147 
5148 //*************************************************************************************************
5163 template< typename Type > // Data type of the matrix
5165  CompressedMatrix<Type,true>::find( size_t i, size_t j )
5166 {
5167  return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
5168 }
5170 //*************************************************************************************************
5171 
5172 
5173 //*************************************************************************************************
5188 template< typename Type > // Data type of the matrix
5190  CompressedMatrix<Type,true>::find( size_t i, size_t j ) const
5191 {
5192  const ConstIterator pos( lowerBound( i, j ) );
5193  if( pos != end_[j] && pos->index_ == i )
5194  return pos;
5195  else return end_[j];
5196 }
5198 //*************************************************************************************************
5199 
5200 
5201 //*************************************************************************************************
5215 template< typename Type > // Data type of the matrix
5217  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j )
5218 {
5219  return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
5220 }
5222 //*************************************************************************************************
5223 
5224 
5225 //*************************************************************************************************
5239 template< typename Type > // Data type of the matrix
5241  CompressedMatrix<Type,true>::lowerBound( size_t i, size_t j ) const
5242 {
5243  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5244  return std::lower_bound( begin_[j], end_[j], i,
5245  []( const Element& element, size_t index )
5246  {
5247  return element.index() < index;
5248  } );
5249 }
5251 //*************************************************************************************************
5252 
5253 
5254 //*************************************************************************************************
5268 template< typename Type > // Data type of the matrix
5270  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j )
5271 {
5272  return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
5273 }
5275 //*************************************************************************************************
5276 
5277 
5278 //*************************************************************************************************
5292 template< typename Type > // Data type of the matrix
5294  CompressedMatrix<Type,true>::upperBound( size_t i, size_t j ) const
5295 {
5296  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5297  return std::upper_bound( begin_[j], end_[j], i,
5298  []( size_t index, const Element& element )
5299  {
5300  return index < element.index();
5301  } );
5302 }
5304 //*************************************************************************************************
5305 
5306 
5307 
5308 
5309 //=================================================================================================
5310 //
5311 // NUMERIC FUNCTIONS
5312 //
5313 //=================================================================================================
5314 
5315 //*************************************************************************************************
5321 template< typename Type > // Data type of the matrix
5322 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::transpose()
5323 {
5324  CompressedMatrix tmp( trans( *this ) );
5325  swap( tmp );
5326  return *this;
5327 }
5329 //*************************************************************************************************
5330 
5331 
5332 //*************************************************************************************************
5338 template< typename Type > // Data type of the matrix
5339 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::ctranspose()
5340 {
5341  CompressedMatrix tmp( ctrans( *this ) );
5342  swap( tmp );
5343  return *this;
5344 }
5346 //*************************************************************************************************
5347 
5348 
5349 //*************************************************************************************************
5367 template< typename Type > // Data type of the matrix
5368 template< typename Other > // Data type of the scalar value
5369 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scale( const Other& scalar )
5370 {
5371  for( size_t j=0UL; j<n_; ++j )
5372  for( Iterator element=begin_[j]; element!=end_[j]; ++element )
5373  element->value_ *= scalar;
5374 
5375  return *this;
5376 }
5378 //*************************************************************************************************
5379 
5380 
5381 //*************************************************************************************************
5391 template< typename Type > // Data type of the matrix
5392 template< typename Other > // Data type of the scalar value
5393 inline CompressedMatrix<Type,true>& CompressedMatrix<Type,true>::scaleDiagonal( const Other& scalar )
5394 {
5395  const size_t size( blaze::min( m_, n_ ) );
5396 
5397  for( size_t j=0UL; j<size; ++j ) {
5398  Iterator pos = lowerBound( j, j );
5399  if( pos != end_[j] && pos->index_ == j )
5400  pos->value_ *= scalar;
5401  }
5402 
5403  return *this;
5404 }
5406 //*************************************************************************************************
5407 
5408 
5409 
5410 
5411 //=================================================================================================
5412 //
5413 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5414 //
5415 //=================================================================================================
5416 
5417 //*************************************************************************************************
5428 template< typename Type > // Data type of the matrix
5429 template< typename Other > // Data type of the foreign expression
5430 inline bool CompressedMatrix<Type,true>::canAlias( const Other* alias ) const noexcept
5431 {
5432  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5433 }
5435 //*************************************************************************************************
5436 
5437 
5438 //*************************************************************************************************
5449 template< typename Type > // Data type of the matrix
5450 template< typename Other > // Data type of the foreign expression
5451 inline bool CompressedMatrix<Type,true>::isAliased( const Other* alias ) const noexcept
5452 {
5453  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5454 }
5456 //*************************************************************************************************
5457 
5458 
5459 //*************************************************************************************************
5470 template< typename Type > // Data type of the matrix
5471 inline bool CompressedMatrix<Type,true>::canSMPAssign() const noexcept
5472 {
5473  return false;
5474 }
5476 //*************************************************************************************************
5477 
5478 
5479 //*************************************************************************************************
5491 template< typename Type > // Data type of the matrix
5492 template< typename MT // Type of the right-hand side dense matrix
5493  , bool SO > // Storage order of the right-hand side dense matrix
5494 inline void CompressedMatrix<Type,true>::assign( const DenseMatrix<MT,SO>& rhs )
5495 {
5496  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5497  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5498 
5499  if( m_ == 0UL || n_ == 0UL )
5500  return;
5501 
5502  size_t nonzeros( 0UL );
5503 
5504  for( size_t j=1UL; j<=n_; ++j )
5505  begin_[j] = end_[j] = end_[n_];
5506 
5507  for( size_t j=0UL; j<n_; ++j )
5508  {
5509  begin_[j] = end_[j] = begin_[0UL]+nonzeros;
5510 
5511  const size_t ibegin( ( IsLower<MT>::value )
5512  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5513  :( 0UL ) );
5514  const size_t iend ( ( IsUpper<MT>::value )
5515  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5516  :( m_ ) );
5517 
5518  for( size_t i=ibegin; i<iend; ++i )
5519  {
5520  if( nonzeros == capacity() ) {
5521  reserveElements( extendCapacity() );
5522  for( size_t k=j+1UL; k<=n_; ++k )
5523  begin_[k] = end_[k] = end_[n_];
5524  }
5525 
5526  end_[j]->value_ = (~rhs)(i,j);
5527 
5528  if( !isDefault<strict>( end_[j]->value_ ) ) {
5529  end_[j]->index_ = i;
5530  ++end_[j];
5531  ++nonzeros;
5532  }
5533  }
5534  }
5535 
5536  begin_[n_] = begin_[0UL]+nonzeros;
5537 }
5539 //*************************************************************************************************
5540 
5541 
5542 //*************************************************************************************************
5554 template< typename Type > // Data type of the matrix
5555 template< typename MT > // Type of the right-hand side compressed matrix
5556 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,true>& rhs )
5557 {
5558  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5559  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5560  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
5561  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
5562 
5563  if( n_ == 0UL || begin_[0] == nullptr )
5564  return;
5565 
5566  for( size_t j=0UL; j<n_; ++j ) {
5567  end_[j] = castDown( std::copy( (~rhs).begin(j), (~rhs).end(j), castUp( begin_[j] ) ) );
5568  begin_[j+1UL] = end_[j];
5569  }
5570 }
5572 //*************************************************************************************************
5573 
5574 
5575 //*************************************************************************************************
5587 template< typename Type > // Data type of the matrix
5588 template< typename MT > // Type of the right-hand side compressed matrix
5589 inline void CompressedMatrix<Type,true>::assign( const SparseMatrix<MT,false>& rhs )
5590 {
5592 
5593  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5594  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5595  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
5596  BLAZE_INTERNAL_ASSERT( capacity() >= (~rhs).nonZeros(), "Invalid capacity detected" );
5597 
5598  using RhsIterator = ConstIterator_<MT>;
5599 
5600  // Counting the number of elements per column
5601  std::vector<size_t> columnLengths( n_, 0UL );
5602  for( size_t i=0UL; i<m_; ++i ) {
5603  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5604  ++columnLengths[element->index()];
5605  }
5606 
5607  // Resizing the compressed matrix
5608  for( size_t j=0UL; j<n_; ++j ) {
5609  begin_[j+1UL] = end_[j+1UL] = begin_[j] + columnLengths[j];
5610  }
5611 
5612  // Appending the elements to the columns of the compressed matrix
5613  for( size_t i=0UL; i<m_; ++i ) {
5614  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5615  append( i, element->index(), element->value() );
5616  }
5617 }
5619 //*************************************************************************************************
5620 
5621 
5622 //*************************************************************************************************
5634 template< typename Type > // Data type of the matrix
5635 template< typename MT // Type of the right-hand side dense matrix
5636  , bool SO > // Storage order of the right-hand side dense matrix
5637 inline void CompressedMatrix<Type,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
5638 {
5639  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5640  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5641 
5642  CompressedMatrix tmp( serial( *this + (~rhs) ) );
5643  swap( tmp );
5644 }
5646 //*************************************************************************************************
5647 
5648 
5649 //*************************************************************************************************
5661 template< typename Type > // Data type of the matrix
5662 template< typename MT // Type of the right-hand side compressed matrix
5663  , bool SO > // Storage order of the right-hand side compressed matrix
5664 inline void CompressedMatrix<Type,true>::addAssign( const SparseMatrix<MT,SO>& rhs )
5665 {
5666  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5667  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5668 
5669  CompressedMatrix tmp( serial( *this + (~rhs) ) );
5670  swap( tmp );
5671 }
5673 //*************************************************************************************************
5674 
5675 
5676 //*************************************************************************************************
5688 template< typename Type > // Data type of the matrix
5689 template< typename MT // Type of the right-hand side dense matrix
5690  , bool SO > // Storage order of the right-hand side dense matrix
5691 inline void CompressedMatrix<Type,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
5692 {
5693  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5694  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5695 
5696  CompressedMatrix tmp( serial( *this - (~rhs) ) );
5697  swap( tmp );
5698 }
5700 //*************************************************************************************************
5701 
5702 
5703 //*************************************************************************************************
5715 template< typename Type > // Data type of the matrix
5716 template< typename MT // Type of the right-hand side compressed matrix
5717  , bool SO > // Storage order of the right-hand side compressed matrix
5718 inline void CompressedMatrix<Type,true>::subAssign( const SparseMatrix<MT,SO>& rhs )
5719 {
5720  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5721  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5722 
5723  CompressedMatrix tmp( serial( *this - (~rhs) ) );
5724  swap( tmp );
5725 }
5727 //*************************************************************************************************
5728 
5729 
5730 //*************************************************************************************************
5742 template< typename Type > // Data type of the matrix
5743 template< typename MT // Type of the right-hand side dense matrix
5744  , bool SO > // Storage order of the right-hand side dense matrix
5745 inline void CompressedMatrix<Type,true>::schurAssign( const DenseMatrix<MT,SO>& rhs )
5746 {
5747  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5748  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5749 
5751 
5752  for( size_t j=0UL; j<n_; ++j ) {
5753  const Iterator last( end(j) );
5754  for( Iterator element=begin(j); element!=last; ++element )
5755  element->value_ *= (~rhs)(element->index_,j);
5756  }
5757 }
5759 //*************************************************************************************************
5760 
5761 
5762 
5763 
5764 
5765 
5766 
5767 
5768 //=================================================================================================
5769 //
5770 // COMPRESSEDMATRIX OPERATORS
5771 //
5772 //=================================================================================================
5773 
5774 //*************************************************************************************************
5777 template< typename Type, bool SO >
5778 inline void reset( CompressedMatrix<Type,SO>& m );
5779 
5780 template< typename Type, bool SO >
5781 inline void reset( CompressedMatrix<Type,SO>& m, size_t i );
5782 
5783 template< typename Type, bool SO >
5784 inline void clear( CompressedMatrix<Type,SO>& m );
5785 
5786 template< bool RF, typename Type, bool SO >
5787 inline bool isDefault( const CompressedMatrix<Type,SO>& m );
5788 
5789 template< typename Type, bool SO >
5790 inline bool isIntact( const CompressedMatrix<Type,SO>& m );
5791 
5792 template< typename Type, bool SO >
5793 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) noexcept;
5795 //*************************************************************************************************
5796 
5797 
5798 //*************************************************************************************************
5805 template< typename Type // Data type of the matrix
5806  , bool SO > // Storage order
5807 inline void reset( CompressedMatrix<Type,SO>& m )
5808 {
5809  m.reset();
5810 }
5811 //*************************************************************************************************
5812 
5813 
5814 //*************************************************************************************************
5827 template< typename Type // Data type of the matrix
5828  , bool SO > // Storage order
5829 inline void reset( CompressedMatrix<Type,SO>& m, size_t i )
5830 {
5831  m.reset( i );
5832 }
5833 //*************************************************************************************************
5834 
5835 
5836 //*************************************************************************************************
5843 template< typename Type // Data type of the matrix
5844  , bool SO > // Storage order
5845 inline void clear( CompressedMatrix<Type,SO>& m )
5846 {
5847  m.clear();
5848 }
5849 //*************************************************************************************************
5850 
5851 
5852 //*************************************************************************************************
5877 template< bool RF // Relaxation flag
5878  , typename Type // Data type of the matrix
5879  , bool SO > // Storage order
5880 inline bool isDefault( const CompressedMatrix<Type,SO>& m )
5881 {
5882  return ( m.rows() == 0UL && m.columns() == 0UL );
5883 }
5884 //*************************************************************************************************
5885 
5886 
5887 //*************************************************************************************************
5905 template< typename Type // Data type of the matrix
5906  , bool SO > // Storage order
5907 inline bool isIntact( const CompressedMatrix<Type,SO>& m )
5908 {
5909  return ( m.nonZeros() <= m.capacity() );
5910 }
5911 //*************************************************************************************************
5912 
5913 
5914 //*************************************************************************************************
5922 template< typename Type // Data type of the matrix
5923  , bool SO > // Storage order
5924 inline void swap( CompressedMatrix<Type,SO>& a, CompressedMatrix<Type,SO>& b ) noexcept
5925 {
5926  a.swap( b );
5927 }
5928 //*************************************************************************************************
5929 
5930 
5931 
5932 
5933 //=================================================================================================
5934 //
5935 // ISRESIZABLE SPECIALIZATIONS
5936 //
5937 //=================================================================================================
5938 
5939 //*************************************************************************************************
5941 template< typename T, bool SO >
5942 struct IsResizable< CompressedMatrix<T,SO> >
5943  : public TrueType
5944 {};
5946 //*************************************************************************************************
5947 
5948 
5949 
5950 
5951 //=================================================================================================
5952 //
5953 // ISSHRINKABLE SPECIALIZATIONS
5954 //
5955 //=================================================================================================
5956 
5957 //*************************************************************************************************
5959 template< typename T, bool SO >
5960 struct IsShrinkable< CompressedMatrix<T,SO> >
5961  : public TrueType
5962 {};
5964 //*************************************************************************************************
5965 
5966 
5967 
5968 
5969 //=================================================================================================
5970 //
5971 // ADDTRAIT SPECIALIZATIONS
5972 //
5973 //=================================================================================================
5974 
5975 //*************************************************************************************************
5977 template< typename T1, bool SO, typename T2, size_t M, size_t N >
5978 struct AddTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
5979 {
5980  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
5981 };
5982 
5983 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5984 struct AddTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
5985 {
5986  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO2 >;
5987 };
5988 
5989 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5990 struct AddTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
5991 {
5992  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
5993 };
5994 
5995 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5996 struct AddTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
5997 {
5998  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO1 >;
5999 };
6000 
6001 template< typename T1, bool SO, typename T2, size_t M, size_t N >
6002 struct AddTrait< CompressedMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
6003 {
6004  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO >;
6005 };
6006 
6007 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6008 struct AddTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
6009 {
6010  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO2 >;
6011 };
6012 
6013 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6014 struct AddTrait< HybridMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
6015 {
6016  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO >;
6017 };
6018 
6019 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6020 struct AddTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
6021 {
6022  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO1 >;
6023 };
6024 
6025 template< typename T1, bool SO, typename T2 >
6026 struct AddTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
6027 {
6028  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6029 };
6030 
6031 template< typename T1, bool SO1, typename T2, bool SO2 >
6032 struct AddTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
6033 {
6034  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO2 >;
6035 };
6036 
6037 template< typename T1, bool SO, typename T2 >
6038 struct AddTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6039 {
6040  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6041 };
6042 
6043 template< typename T1, bool SO1, typename T2, bool SO2 >
6044 struct AddTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
6045 {
6046  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO1 >;
6047 };
6048 
6049 template< typename T1, bool SO, typename T2, bool AF, bool PF >
6050 struct AddTrait< CompressedMatrix<T1,SO>, CustomMatrix<T2,AF,PF,SO> >
6051 {
6052  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6053 };
6054 
6055 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6056 struct AddTrait< CompressedMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6057 {
6058  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO2 >;
6059 };
6060 
6061 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6062 struct AddTrait< CustomMatrix<T1,AF,PF,SO>, CompressedMatrix<T2,SO> >
6063 {
6064  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6065 };
6066 
6067 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6068 struct AddTrait< CustomMatrix<T1,AF,PF,SO1>, CompressedMatrix<T2,SO2> >
6069 {
6070  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO1 >;
6071 };
6072 
6073 template< typename T1, bool SO, typename T2 >
6074 struct AddTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6075 {
6076  using Type = CompressedMatrix< AddTrait_<T1,T2>, SO >;
6077 };
6078 
6079 template< typename T1, bool SO1, typename T2, bool SO2 >
6080 struct AddTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
6081 {
6082  using Type = CompressedMatrix< AddTrait_<T1,T2>, false >;
6083 };
6085 //*************************************************************************************************
6086 
6087 
6088 
6089 
6090 //=================================================================================================
6091 //
6092 // SUBTRAIT SPECIALIZATIONS
6093 //
6094 //=================================================================================================
6095 
6096 //*************************************************************************************************
6098 template< typename T1, bool SO, typename T2, size_t M, size_t N >
6099 struct SubTrait< CompressedMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
6100 {
6101  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
6102 };
6103 
6104 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6105 struct SubTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
6106 {
6107  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO2 >;
6108 };
6109 
6110 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6111 struct SubTrait< StaticMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
6112 {
6113  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
6114 };
6115 
6116 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6117 struct SubTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
6118 {
6119  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO1 >;
6120 };
6121 
6122 template< typename T1, bool SO, typename T2, size_t M, size_t N >
6123 struct SubTrait< CompressedMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
6124 {
6125  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO >;
6126 };
6127 
6128 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6129 struct SubTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
6130 {
6131  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO2 >;
6132 };
6133 
6134 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6135 struct SubTrait< HybridMatrix<T1,M,N,SO>, CompressedMatrix<T2,SO> >
6136 {
6137  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO >;
6138 };
6139 
6140 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6141 struct SubTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
6142 {
6143  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO1 >;
6144 };
6145 
6146 template< typename T1, bool SO, typename T2 >
6147 struct SubTrait< CompressedMatrix<T1,SO>, DynamicMatrix<T2,SO> >
6148 {
6149  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6150 };
6151 
6152 template< typename T1, bool SO1, typename T2, bool SO2 >
6153 struct SubTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
6154 {
6155  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO2 >;
6156 };
6157 
6158 template< typename T1, bool SO, typename T2 >
6159 struct SubTrait< DynamicMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6160 {
6161  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6162 };
6163 
6164 template< typename T1, bool SO1, typename T2, bool SO2 >
6165 struct SubTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
6166 {
6167  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO1 >;
6168 };
6169 
6170 template< typename T1, bool SO, typename T2, bool AF, bool PF >
6171 struct SubTrait< CompressedMatrix<T1,SO>, CustomMatrix<T2,AF,PF,SO> >
6172 {
6173  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6174 };
6175 
6176 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6177 struct SubTrait< CompressedMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6178 {
6179  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO2 >;
6180 };
6181 
6182 template< typename T1, bool AF, bool PF, bool SO, typename T2 >
6183 struct SubTrait< CustomMatrix<T1,AF,PF,SO>, CompressedMatrix<T2,SO> >
6184 {
6185  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6186 };
6187 
6188 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6189 struct SubTrait< CustomMatrix<T1,AF,PF,SO1>, CompressedMatrix<T2,SO2> >
6190 {
6191  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO1 >;
6192 };
6193 
6194 template< typename T1, bool SO, typename T2 >
6195 struct SubTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6196 {
6197  using Type = CompressedMatrix< SubTrait_<T1,T2>, SO >;
6198 };
6199 
6200 template< typename T1, bool SO1, typename T2, bool SO2 >
6201 struct SubTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
6202 {
6203  using Type = CompressedMatrix< SubTrait_<T1,T2>, false >;
6204 };
6206 //*************************************************************************************************
6207 
6208 
6209 
6210 
6211 //=================================================================================================
6212 //
6213 // SCHURTRAIT SPECIALIZATIONS
6214 //
6215 //=================================================================================================
6216 
6217 //*************************************************************************************************
6219 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6220 struct SchurTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
6221 {
6222  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO1 >;
6223 };
6224 
6225 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6226 struct SchurTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
6227 {
6228  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO2 >;
6229 };
6230 
6231 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6232 struct SchurTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
6233 {
6234  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO1 >;
6235 };
6236 
6237 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6238 struct SchurTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
6239 {
6240  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO2 >;
6241 };
6242 
6243 template< typename T1, bool SO1, typename T2, bool SO2 >
6244 struct SchurTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
6245 {
6246  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO1 >;
6247 };
6248 
6249 template< typename T1, bool SO1, typename T2, bool SO2 >
6250 struct SchurTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
6251 {
6252  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO2 >;
6253 };
6254 
6255 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6256 struct SchurTrait< CompressedMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6257 {
6258  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO1 >;
6259 };
6260 
6261 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6262 struct SchurTrait< CustomMatrix<T1,AF,PF,SO1>, CompressedMatrix<T2,SO2> >
6263 {
6264  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO2 >;
6265 };
6266 
6267 template< typename T1, bool SO, typename T2 >
6268 struct SchurTrait< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6269 {
6270  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO >;
6271 };
6272 
6273 template< typename T1, bool SO1, typename T2, bool SO2 >
6274 struct SchurTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
6275 {
6276  using Type = CompressedMatrix< MultTrait_<T1,T2>, false >;
6277 };
6279 //*************************************************************************************************
6280 
6281 
6282 
6283 
6284 //=================================================================================================
6285 //
6286 // MULTTRAIT SPECIALIZATIONS
6287 //
6288 //=================================================================================================
6289 
6290 //*************************************************************************************************
6292 template< typename T1, bool SO, typename T2 >
6293 struct MultTrait< CompressedMatrix<T1,SO>, T2, EnableIf_< IsNumeric<T2> > >
6294 {
6295  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO >;
6296 };
6297 
6298 template< typename T1, typename T2, bool SO >
6299 struct MultTrait< T1, CompressedMatrix<T2,SO>, EnableIf_< IsNumeric<T1> > >
6300 {
6301  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO >;
6302 };
6303 
6304 template< typename T1, bool SO, typename T2, size_t N >
6305 struct MultTrait< CompressedMatrix<T1,SO>, StaticVector<T2,N,false> >
6306 {
6307  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6308 };
6309 
6310 template< typename T1, size_t N, typename T2, bool SO >
6311 struct MultTrait< StaticVector<T1,N,true>, CompressedMatrix<T2,SO> >
6312 {
6313  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6314 };
6315 
6316 template< typename T1, bool SO, typename T2, size_t N >
6317 struct MultTrait< CompressedMatrix<T1,SO>, HybridVector<T2,N,false> >
6318 {
6319  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6320 };
6321 
6322 template< typename T1, size_t N, typename T2, bool SO >
6323 struct MultTrait< HybridVector<T1,N,true>, CompressedMatrix<T2,SO> >
6324 {
6325  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6326 };
6327 
6328 template< typename T1, bool SO, typename T2 >
6329 struct MultTrait< CompressedMatrix<T1,SO>, DynamicVector<T2,false> >
6330 {
6331  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6332 };
6333 
6334 template< typename T1, typename T2, bool SO >
6335 struct MultTrait< DynamicVector<T1,true>, CompressedMatrix<T2,SO> >
6336 {
6337  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6338 };
6339 
6340 template< typename T1, bool SO, typename T2, bool AF, bool PF >
6341 struct MultTrait< CompressedMatrix<T1,SO>, CustomVector<T2,AF,PF,false> >
6342 {
6343  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6344 };
6345 
6346 template< typename T1, bool AF, bool PF, typename T2, bool SO >
6347 struct MultTrait< CustomVector<T1,AF,PF,true>, CompressedMatrix<T2,SO> >
6348 {
6349  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6350 };
6351 
6352 template< typename T1, bool SO, typename T2 >
6353 struct MultTrait< CompressedMatrix<T1,SO>, CompressedVector<T2,false> >
6354 {
6355  using Type = CompressedVector< MultTrait_<T1,T2>, false >;
6356 };
6357 
6358 template< typename T1, typename T2, bool SO >
6359 struct MultTrait< CompressedVector<T1,true>, CompressedMatrix<T2,SO> >
6360 {
6361  using Type = CompressedVector< MultTrait_<T1,T2>, true >;
6362 };
6363 
6364 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6365 struct MultTrait< CompressedMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
6366 {
6367  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6368 };
6369 
6370 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6371 struct MultTrait< StaticMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
6372 {
6373  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6374 };
6375 
6376 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6377 struct MultTrait< CompressedMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
6378 {
6379  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6380 };
6381 
6382 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6383 struct MultTrait< HybridMatrix<T1,M,N,SO1>, CompressedMatrix<T2,SO2> >
6384 {
6385  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6386 };
6387 
6388 template< typename T1, bool SO1, typename T2, bool SO2 >
6389 struct MultTrait< CompressedMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
6390 {
6391  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6392 };
6393 
6394 template< typename T1, bool SO1, typename T2, bool SO2 >
6395 struct MultTrait< DynamicMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
6396 {
6397  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6398 };
6399 
6400 template< typename T1, bool SO1, typename T2, bool AF, bool PF, bool SO2 >
6401 struct MultTrait< CompressedMatrix<T1,SO1>, CustomMatrix<T2,AF,PF,SO2> >
6402 {
6403  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6404 };
6405 
6406 template< typename T1, bool AF, bool PF, bool SO1, typename T2, bool SO2 >
6407 struct MultTrait< CustomMatrix<T1,AF,PF,SO1>, CompressedMatrix<T2,SO2> >
6408 {
6409  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6410 };
6411 
6412 template< typename T1, bool SO1, typename T2, bool SO2 >
6413 struct MultTrait< CompressedMatrix<T1,SO1>, CompressedMatrix<T2,SO2> >
6414 {
6415  using Type = CompressedMatrix< MultTrait_<T1,T2>, SO1 >;
6416 };
6418 //*************************************************************************************************
6419 
6420 
6421 
6422 
6423 //=================================================================================================
6424 //
6425 // DIVTRAIT SPECIALIZATIONS
6426 //
6427 //=================================================================================================
6428 
6429 //*************************************************************************************************
6431 template< typename T1, bool SO, typename T2 >
6432 struct DivTrait< CompressedMatrix<T1,SO>, T2, EnableIf_< IsNumeric<T2> > >
6433 {
6434  using Type = CompressedMatrix< DivTrait_<T1,T2>, SO >;
6435 };
6437 //*************************************************************************************************
6438 
6439 
6440 
6441 
6442 //=================================================================================================
6443 //
6444 // UNARYMAPTRAIT SPECIALIZATIONS
6445 //
6446 //=================================================================================================
6447 
6448 //*************************************************************************************************
6450 template< typename T, bool SO, typename OP >
6451 struct UnaryMapTrait< CompressedMatrix<T,SO>, OP >
6452 {
6453  using Type = CompressedMatrix< UnaryMapTrait_<T,OP>, SO >;
6454 };
6456 //*************************************************************************************************
6457 
6458 
6459 
6460 
6461 //=================================================================================================
6462 //
6463 // HIGHTYPE SPECIALIZATIONS
6464 //
6465 //=================================================================================================
6466 
6467 //*************************************************************************************************
6469 template< typename T1, bool SO, typename T2 >
6470 struct HighType< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6471 {
6472  using Type = CompressedMatrix< typename HighType<T1,T2>::Type, SO >;
6473 };
6475 //*************************************************************************************************
6476 
6477 
6478 
6479 
6480 //=================================================================================================
6481 //
6482 // LOWTYPE SPECIALIZATIONS
6483 //
6484 //=================================================================================================
6485 
6486 //*************************************************************************************************
6488 template< typename T1, bool SO, typename T2 >
6489 struct LowType< CompressedMatrix<T1,SO>, CompressedMatrix<T2,SO> >
6490 {
6491  using Type = CompressedMatrix< typename LowType<T1,T2>::Type, SO >;
6492 };
6494 //*************************************************************************************************
6495 
6496 
6497 
6498 
6499 //=================================================================================================
6500 //
6501 // SUBMATRIXTRAIT SPECIALIZATIONS
6502 //
6503 //=================================================================================================
6504 
6505 //*************************************************************************************************
6507 template< typename T, bool SO >
6508 struct SubmatrixTrait< CompressedMatrix<T,SO> >
6509 {
6510  using Type = CompressedMatrix<T,SO>;
6511 };
6513 //*************************************************************************************************
6514 
6515 
6516 
6517 
6518 //=================================================================================================
6519 //
6520 // ROWTRAIT SPECIALIZATIONS
6521 //
6522 //=================================================================================================
6523 
6524 //*************************************************************************************************
6526 template< typename T, bool SO >
6527 struct RowTrait< CompressedMatrix<T,SO> >
6528 {
6529  using Type = CompressedVector<T,true>;
6530 };
6532 //*************************************************************************************************
6533 
6534 
6535 
6536 
6537 //=================================================================================================
6538 //
6539 // COLUMNTRAIT SPECIALIZATIONS
6540 //
6541 //=================================================================================================
6542 
6543 //*************************************************************************************************
6545 template< typename T, bool SO >
6546 struct ColumnTrait< CompressedMatrix<T,SO> >
6547 {
6548  using Type = CompressedVector<T,false>;
6549 };
6551 //*************************************************************************************************
6552 
6553 } // namespace blaze
6554 
6555 #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:1883
Header file for auxiliary alias declarations.
Headerfile for the generic min algorithm.
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:79
Iterator * end_
Pointers one past the last non-zero element of each row.
Definition: CompressedMatrix.h:513
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:2957
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
void shrinkToFit()
Requesting the removal of unused capacity.
Definition: CompressedMatrix.h:1825
Header file for the subtraction trait.
bool canSMPAssign() const noexcept
Returns whether the matrix can be used in SMP assignments.
Definition: CompressedMatrix.h:2691
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:356
Header file for basic type definitions.
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: CompressedMatrix.h:2672
Header file for the row trait.
CompressedMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: CompressedMatrix.h:2564
CompressedMatrix()
The default constructor for CompressedMatrix.
Definition: CompressedMatrix.h:557
Header file for the serial shim.
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:216
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:265
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1411
Iterator end(size_t i) noexcept
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:976
Reference operator()(size_t i, size_t j) noexcept
2D-access to the compressed matrix elements.
Definition: CompressedMatrix.h:802
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:198
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3076
MatrixAccessProxy< This > Reference
Reference to a compressed matrix value.
Definition: CompressedMatrix.h:306
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:560
size_t m_
The current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:3287
void clear()
Clearing the compressed matrix.
Definition: CompressedMatrix.h:1566
Header file for the And class template.
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1762
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3085
#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:768
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:394
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:1437
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:88
BoolConstant< true > TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3086
Header file for memory allocation and deallocation functionality.
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1393
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first non-zero element of row/column i.
Definition: CompressedMatrix.h:954
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1809
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:515
Resize mechanism to obtain a CompressedMatrix with different fixed dimensions.
Definition: CompressedMatrix.h:3104
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:78
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:129
void swap(CompressedMatrix &sm) noexcept
Swapping the contents of two sparse matrices.
Definition: CompressedMatrix.h:1842
Constraint on the data type.
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:3289
Header file for the SparseMatrix base class.
ElementBase * IteratorBase
Iterator over non-constant base elements.
Definition: CompressedMatrix.h:222
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:511
void reserve(size_t nonzeros)
Setting the minimum capacity of the compressed matrix.
Definition: CompressedMatrix.h:1688
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
void reset()
Reset to the default initial values.
Definition: CompressedMatrix.h:1528
Headerfile for the generic max algorithm.
Header file for the ValueIndexPair class.
Header file for the LowType type trait.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Header file for the unary map trait.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3084
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
decltype(auto) ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatMapExpr.h:1359
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5924
Header file for the If class template.
Header file for the IsFloatingPoint type trait.
Header file for the IsShrinkable type trait.
Iterator set(size_t i, size_t j, const Type &value)
Setting an element of the compressed matrix.
Definition: CompressedMatrix.h:1968
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:3081
void erase(size_t i, size_t j)
Erasing an element from the compressed matrix.
Definition: CompressedMatrix.h:2210
Iterator * end_
Pointers one past the last non-zero element of each column.
Definition: CompressedMatrix.h:3291
size_t rows() const noexcept
Returns the current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:1423
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
#define BLAZE_CONSTRAINT_MUST_HAVE_SAME_SIZE(T1, T2)
Constraint on the size of two data types.In case the types T1 and T2 don&#39;t have the same size...
Definition: SameSize.h:60
Header file for the Not class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3087
size_t capacity() const noexcept
Returns the maximum capacity of the compressed matrix.
Definition: CompressedMatrix.h:1451
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:1020
Constraint on the data type.
CompressedMatrix< Type, SO > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:298
Header file for the IsLower type trait.
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:340
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:1938
Iterator insert(size_t i, size_t j, const Type &value)
Inserting an element into the compressed matrix.
Definition: CompressedMatrix.h:2000
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:304
Header file for the exception macros of the math module.
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
Compile time check for floating point data types.This type trait tests whether or not the given templ...
Definition: IsFloatingPoint.h:75
Compile time check for data types.This type trait tests whether or not the given template parameter i...
Definition: IsSMPAssignable.h:119
BLAZE_ALWAYS_INLINE void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:548
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:264
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:2905
size_t nonZeros() const
Returns the number of non-zero elements in the compressed matrix.
Definition: CompressedMatrix.h:1488
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:580
typename DivTrait< T1, T2 >::Type DivTrait_
Auxiliary alias declaration for the DivTrait class template.The DivTrait_ alias declaration provides ...
Definition: DivTrait.h:250
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the compressed matrix.
Definition: CompressedMatrix.h:1593
Header file for the IsNumeric type trait.
CompressedMatrix & operator=(const CompressedMatrix &rhs)
Copy assignment operator for CompressedMatrix.
Definition: CompressedMatrix.h:1048
#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:2652
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
Header file for run time assertion macros.
Header file for the relaxation flag types.
Header file for the addition trait.
Resize mechanism to obtain a CompressedMatrix with different fixed dimensions.
Definition: CompressedMatrix.h:326
CompressedMatrix & transpose()
In-place transpose of the matrix.
Definition: CompressedMatrix.h:2548
Header file for the division trait.
void trim()
Removing all excessive capacity from all rows/columns.
Definition: CompressedMatrix.h:1782
Header file for the submatrix trait.
Constraint on the data type.
typename If< T1, T2, T3 >::Type If_
Auxiliary alias declaration for the If class template.The If_ alias declaration provides a convenient...
Definition: If.h:154
Headerfile for the generic transfer algorithm.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:79
Header file for the column trait.
Header file for the isDefault shim.
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b) noexcept
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:270
const Type & ConstReference
Reference to a constant compressed matrix value.
Definition: CompressedMatrix.h:307
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:101
Constraint on the data type.
Constraint on the data type.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:309
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:819
Iterator * begin_
Pointers to the first non-zero element of each column.
Definition: CompressedMatrix.h:3290
#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:2713
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:2148
EnableIf_< IsBuiltin< T > > deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:230
void finalize(size_t i)
Finalizing the element insertion of a row/column.
Definition: CompressedMatrix.h:2180
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
Iterator find(size_t i, size_t j)
Searches for a specific matrix element.
Definition: CompressedMatrix.h:2388
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
Iterator * begin_
Pointers to the first non-zero element of each row.
Definition: CompressedMatrix.h:512
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:324
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3082
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:790
size_t n_
The current number of columns of the compressed matrix.
Definition: CompressedMatrix.h:3288
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:1920
void addAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the addition assignment of a dense matrix.
Definition: CompressedMatrix.h:2853
Iterator lowerBound(size_t i, size_t j)
Returns an iterator to the first index not less then the given index.
Definition: CompressedMatrix.h:2441
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:3293
Compile time type check.This class tests whether the given template parameter T is an rvalue referenc...
Definition: IsRValueReference.h:77
Iterator upperBound(size_t i, size_t j)
Returns an iterator to the first index greater then the given index.
Definition: CompressedMatrix.h:2496
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:308
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:252
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:600
size_t extendCapacity() const noexcept
Calculating a new matrix capacity.
Definition: CompressedMatrix.h:1863
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:316
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:3094
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
Header file for the IsUpper type trait.
size_t n_
The current number of columns of the compressed matrix.
Definition: CompressedMatrix.h:510
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:221
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: CompressedMatrix.h:856
Header file for the IsResizable type trait.
size_t m_
The current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:509
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:303
Reference value()
Access to the current value of the value-index-pair.
Definition: ValueIndexPair.h:362
Header file for the HighType type trait.
Iterator begin(size_t i) noexcept
Returns an iterator to the first non-zero element of row/column i.
Definition: CompressedMatrix.h:910