Blaze 3.9
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>
52#include <blaze/math/Forward.h>
96#include <blaze/util/Assert.h>
102#include <blaze/util/EnableIf.h>
104#include <blaze/util/Memory.h>
105#include <blaze/util/Types.h>
108
109
110namespace blaze {
111
112//=================================================================================================
113//
114// CLASS DEFINITION
115//
116//=================================================================================================
117
118//*************************************************************************************************
234template< typename Type // Data type of the matrix
235 , bool SO // Storage order
236 , typename Tag > // Type tag
238 : public SparseMatrix< CompressedMatrix<Type,SO,Tag>, SO >
239{
240 private:
241 //**Type definitions****************************************************************************
244 //**********************************************************************************************
245
246 //**Private class Element***********************************************************************
253 struct Element
254 : public ElementBase
255 {
256 //**Constructors*****************************************************************************
257 Element() = default;
258 Element( const Element& rhs ) = default;
259 Element( Element&& rhs ) = default;
260 //*******************************************************************************************
261
262 //**Assignment operators*********************************************************************
263 inline Element& operator=( const Element& rhs )
264 {
265 this->value_ = rhs.value_;
266 return *this;
267 }
268
269 inline Element& operator=( Element&& rhs )
270 {
271 this->value_ = std::move( rhs.value_ );
272 return *this;
273 }
274
275 template< typename Other >
276 inline auto operator=( const Other& rhs )
278 {
279 this->value_ = rhs.value();
280 return *this;
281 }
282
283 template< typename Other >
284 inline auto operator=( Other&& rhs )
286 IsRValueReference_v<Other&&>, Element& >
287 {
288 this->value_ = std::move( rhs.value() );
289 return *this;
290 }
291
292 template< typename Other >
293 inline auto operator=( const Other& v )
295 {
296 this->value_ = v;
297 return *this;
298 }
299
300 template< typename Other >
301 inline auto operator=( Other&& v )
303 IsRValueReference_v<Other&&>, Element& >
304 {
305 this->value_ = std::move( v );
306 return *this;
307 }
308 //*******************************************************************************************
309
310 //**Friend declarations**********************************************************************
311 friend class CompressedMatrix;
312 //*******************************************************************************************
313 };
315 //**********************************************************************************************
316
317 //**Private class Uninitialized*****************************************************************
321 struct Uninitialized {};
323 //**********************************************************************************************
324
325 public:
326 //**Type definitions****************************************************************************
329 using ResultType = This;
330
333
336
337 using ElementType = Type;
338 using TagType = Tag;
339 using ReturnType = const Type&;
340 using CompositeType = const This&;
342 using ConstReference = const Type&;
343 using Iterator = Element*;
344 using ConstIterator = const Element*;
345 //**********************************************************************************************
346
347 //**Rebind struct definition********************************************************************
350 template< typename NewType > // Data type of the other matrix
351 struct Rebind {
353 };
354 //**********************************************************************************************
355
356 //**Resize struct definition********************************************************************
359 template< size_t NewM // Number of rows of the other matrix
360 , size_t NewN > // Number of columns of the other matrix
361 struct Resize {
363 };
364 //**********************************************************************************************
365
366 //**Compilation flags***************************************************************************
368
371 static constexpr bool smpAssignable = !IsSMPAssignable_v<Type>;
372 //**********************************************************************************************
373
374 //**Constructors********************************************************************************
377 inline CompressedMatrix();
378 inline CompressedMatrix( size_t m, size_t n );
379 inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
380 CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
381 inline CompressedMatrix( initializer_list< initializer_list<Type> > list );
382
383 inline CompressedMatrix( const CompressedMatrix& sm );
384 inline CompressedMatrix( CompressedMatrix&& sm ) noexcept;
385
386 template< typename MT, bool SO2 > inline CompressedMatrix( const DenseMatrix<MT,SO2>& dm );
387 template< typename MT, bool SO2 > inline CompressedMatrix( const SparseMatrix<MT,SO2>& sm );
389 //**********************************************************************************************
390
391 //**Destructor**********************************************************************************
394 inline ~CompressedMatrix();
396 //**********************************************************************************************
397
398 //**Data access functions***********************************************************************
401 inline Reference operator()( size_t i, size_t j ) noexcept;
402 inline ConstReference operator()( size_t i, size_t j ) const noexcept;
403 inline Reference at( size_t i, size_t j );
404 inline ConstReference at( size_t i, size_t j ) const;
405 inline Iterator begin ( size_t i ) noexcept;
406 inline ConstIterator begin ( size_t i ) const noexcept;
407 inline ConstIterator cbegin( size_t i ) const noexcept;
408 inline Iterator end ( size_t i ) noexcept;
409 inline ConstIterator end ( size_t i ) const noexcept;
410 inline ConstIterator cend ( size_t i ) const noexcept;
412 //**********************************************************************************************
413
414 //**Assignment operators************************************************************************
417 inline CompressedMatrix& operator=( initializer_list< initializer_list<Type> > list ) &;
418 inline CompressedMatrix& operator=( const CompressedMatrix& rhs ) &;
419 inline CompressedMatrix& operator=( CompressedMatrix&& rhs ) & noexcept;
420
421 template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO2>& rhs ) &;
422 template< typename MT, bool SO2 > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO2>& rhs ) &;
423 template< typename MT, bool SO2 > inline CompressedMatrix& operator+=( const Matrix<MT,SO2>& rhs ) &;
424 template< typename MT, bool SO2 > inline CompressedMatrix& operator-=( const Matrix<MT,SO2>& rhs ) &;
425 template< typename MT, bool SO2 > inline CompressedMatrix& operator%=( const DenseMatrix<MT,SO2>& rhs ) &;
426 template< typename MT, bool SO2 > inline CompressedMatrix& operator%=( const SparseMatrix<MT,SO2>& rhs ) &;
428 //**********************************************************************************************
429
430 //**Utility functions***************************************************************************
433 inline size_t rows() const noexcept;
434 inline size_t columns() const noexcept;
435 inline size_t capacity() const noexcept;
436 inline size_t capacity( size_t i ) const noexcept;
437 inline size_t nonZeros() const;
438 inline size_t nonZeros( size_t i ) const;
439 inline void reset();
440 inline void reset( size_t i );
441 inline void clear();
442 void resize ( size_t m, size_t n, bool preserve=true );
443 inline void reserve( size_t nonzeros );
444 void reserve( size_t i, size_t nonzeros );
445 inline void trim ();
446 inline void trim ( size_t i );
447 inline void shrinkToFit();
448 inline void swap( CompressedMatrix& sm ) noexcept;
450 //**********************************************************************************************
451
452 //**Insertion functions*************************************************************************
455 inline Iterator set ( size_t i, size_t j, const Type& value );
456 inline Iterator insert ( size_t i, size_t j, const Type& value );
457 inline void append ( size_t i, size_t j, const Type& value, bool check=false );
458 inline void finalize( size_t i );
460 //**********************************************************************************************
461
462 //**Erase functions*****************************************************************************
465 inline void erase( size_t i, size_t j );
466 inline Iterator erase( size_t i, Iterator pos );
467 inline Iterator erase( size_t i, Iterator first, Iterator last );
468
469 template< typename Pred >
470 inline void erase( Pred predicate );
471
472 template< typename Pred >
473 inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
475 //**********************************************************************************************
476
477 //**Lookup functions****************************************************************************
480 inline Iterator find ( size_t i, size_t j );
481 inline ConstIterator find ( size_t i, size_t j ) const;
482 inline Iterator lowerBound( size_t i, size_t j );
483 inline ConstIterator lowerBound( size_t i, size_t j ) const;
484 inline Iterator upperBound( size_t i, size_t j );
485 inline ConstIterator upperBound( size_t i, size_t j ) const;
487 //**********************************************************************************************
488
489 //**Numeric functions***************************************************************************
492 inline CompressedMatrix& transpose();
494
495 template< typename Other > inline CompressedMatrix& scale( const Other& scalar );
497 //**********************************************************************************************
498
499 //**Expression template evaluation functions****************************************************
502 template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
503 template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
504
505 inline bool canSMPAssign() const noexcept;
506
507 template< typename MT, bool SO2 > inline void assign ( const DenseMatrix<MT,SO2>& rhs );
508 template< typename MT > inline void assign ( const SparseMatrix<MT,SO>& rhs );
509 template< typename MT > inline void assign ( const SparseMatrix<MT,!SO>& rhs );
510 template< typename MT, bool SO2 > inline void addAssign ( const DenseMatrix<MT,SO2>& rhs );
511 template< typename MT, bool SO2 > inline void addAssign ( const SparseMatrix<MT,SO2>& rhs );
512 template< typename MT, bool SO2 > inline void subAssign ( const DenseMatrix<MT,SO2>& rhs );
513 template< typename MT, bool SO2 > inline void subAssign ( const SparseMatrix<MT,SO2>& rhs );
514 template< typename MT, bool SO2 > inline void schurAssign( const DenseMatrix<MT,SO2>& rhs );
516 //**********************************************************************************************
517
518 private:
519 //**Constructors********************************************************************************
522 inline CompressedMatrix( size_t m, size_t n, Uninitialized );
524 //**********************************************************************************************
525
526 //**Utility functions***************************************************************************
529 inline size_t extendCapacity() const noexcept;
530 void reserveElements( size_t nonzeros );
531
532 inline Iterator castDown( IteratorBase it ) const noexcept;
533 inline IteratorBase castUp ( Iterator it ) const noexcept;
535 //**********************************************************************************************
536
537 //**Insertion functions*************************************************************************
540 Iterator insert( Iterator pos, size_t i, size_t j, const Type& value );
542 //**********************************************************************************************
543
544 //**Member variables****************************************************************************
547 size_t m_;
548 size_t n_;
549 size_t capacity_;
552
553 static const Type zero_;
555 //**********************************************************************************************
556
557 //**Compile time checks*************************************************************************
565 //**********************************************************************************************
566};
567//*************************************************************************************************
568
569
570
571
572//=================================================================================================
573//
574// DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
575//
576//=================================================================================================
577
578template< typename Type // Data type of the matrix
579 , bool SO // Storage order
580 , typename Tag > // Type tag
581const Type CompressedMatrix<Type,SO,Tag>::zero_{};
582
583
584
585
586//=================================================================================================
587//
588// CONSTRUCTORS
589//
590//=================================================================================================
591
592//*************************************************************************************************
595template< typename Type // Data type of the matrix
596 , bool SO // Storage order
597 , typename Tag > // Type tag
599 : m_ ( 0UL ) // The current number of rows of the compressed matrix
600 , n_ ( 0UL ) // The current number of columns of the compressed matrix
601 , capacity_( 0UL ) // The current capacity of the pointer array
602 , begin_ ( nullptr ) // Pointers to the first non-zero element of each row
603 , end_ ( nullptr ) // Pointers one past the last non-zero element of each row
604{}
605//*************************************************************************************************
606
607
608//*************************************************************************************************
616template< typename Type // Data type of the matrix
617 , bool SO // Storage order
618 , typename Tag > // Type tag
620 : CompressedMatrix( m, n, Uninitialized() )
621{
622 for( size_t i=1UL; i<2UL*m_+2UL; ++i )
623 begin_[i] = nullptr;
624}
625//*************************************************************************************************
626
627
628//*************************************************************************************************
637template< typename Type // Data type of the matrix
638 , bool SO // Storage order
639 , typename Tag > // Type tag
640inline CompressedMatrix<Type,SO,Tag>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
641 : CompressedMatrix( m, n, Uninitialized() )
642{
643 begin_[0UL] = allocate<Element>( nonzeros );
644 for( size_t i=1UL; i<(2UL*m_+1UL); ++i )
645 begin_[i] = begin_[0UL];
646 end_[m_] = begin_[0UL]+nonzeros;
647}
648//*************************************************************************************************
649
650
651//*************************************************************************************************
662template< typename Type // Data type of the matrix
663 , bool SO // Storage order
664 , typename Tag > // Type tag
665CompressedMatrix<Type,SO,Tag>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
666 : CompressedMatrix( m, n, Uninitialized() )
667{
668 BLAZE_USER_ASSERT( nonzeros.size() == m, "Size of capacity vector and number of rows don't match" );
669
670 size_t newCapacity( 0UL );
671 for( auto it=nonzeros.begin(); it!=nonzeros.end(); ++it )
672 newCapacity += *it;
673
674 begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
675 for( size_t i=0UL; i<m_; ++i ) {
676 begin_[i+1UL] = end_[i+1UL] = begin_[i] + nonzeros[i];
677 }
678}
679//*************************************************************************************************
680
681
682//*************************************************************************************************
702template< typename Type // Data type of the matrix
703 , bool SO // Storage order
704 , typename Tag > // Type tag
705inline CompressedMatrix<Type,SO,Tag>::CompressedMatrix( initializer_list< initializer_list<Type> > list )
706 : CompressedMatrix( list.size(), determineColumns( list ), blaze::nonZeros( list ) )
707{
708 size_t i( 0UL );
709
710 for( const auto& rowList : list )
711 {
712 size_t j( 0UL );
713
714 for( const Type& element : rowList ) {
715 if( !isDefault<strict>( element ) )
716 append( i, j, element );
717 ++j;
718 }
719
720 finalize( i );
721 ++i;
722 }
723}
724//*************************************************************************************************
725
726
727//*************************************************************************************************
732template< typename Type // Data type of the matrix
733 , bool SO // Storage order
734 , typename Tag > // Type tag
736 : CompressedMatrix( sm.m_, sm.n_, Uninitialized() )
737{
738 const size_t nonzeros( sm.nonZeros() );
739
740 begin_[0UL] = allocate<Element>( nonzeros );
741 for( size_t i=0UL; i<m_; ++i ) {
742 end_[i] = castDown( std::copy( sm.begin(i), sm.end(i), castUp( begin_[i] ) ) );
743 begin_[i+1UL] = end_[i];
744 }
745 end_[m_] = begin_[0UL]+nonzeros;
746}
747//*************************************************************************************************
748
749
750//*************************************************************************************************
755template< typename Type // Data type of the matrix
756 , bool SO // Storage order
757 , typename Tag > // Type tag
759 : m_ ( sm.m_ ) // The current number of rows of the compressed matrix
760 , n_ ( sm.n_ ) // The current number of columns of the compressed matrix
761 , capacity_( sm.capacity_ ) // The current capacity of the pointer array
762 , begin_ ( sm.begin_ ) // Pointers to the first non-zero element of each row
763 , end_ ( sm.end_ ) // Pointers one past the last non-zero element of each row
764{
765 sm.m_ = 0UL;
766 sm.n_ = 0UL;
767 sm.capacity_ = 0UL;
768 sm.begin_ = nullptr;
769 sm.end_ = nullptr;
770}
771//*************************************************************************************************
772
773
774//*************************************************************************************************
779template< typename Type // Data type of the matrix
780 , bool SO // Storage order
781 , typename Tag > // Type tag
782template< typename MT // Type of the foreign dense matrix
783 , bool SO2 > // Storage order of the foreign dense matrix
785 : CompressedMatrix( (*dm).rows(), (*dm).columns() )
786{
787 using blaze::assign;
788
790
791 assign( *this, *dm );
792}
793//*************************************************************************************************
794
795
796//*************************************************************************************************
801template< typename Type // Data type of the matrix
802 , bool SO // Storage order
803 , typename Tag > // Type tag
804template< typename MT // Type of the foreign compressed matrix
805 , bool SO2 > // Storage order of the foreign compressed matrix
807 : CompressedMatrix( (*sm).rows(), (*sm).columns(), (*sm).nonZeros() )
808{
809 using blaze::assign;
810
812
813 assign( *this, *sm );
814}
815//*************************************************************************************************
816
817
818//*************************************************************************************************
824template< typename Type // Data type of the matrix
825 , bool SO // Storage order
826 , typename Tag > // Type tag
827inline CompressedMatrix<Type,SO,Tag>::CompressedMatrix( size_t m, size_t n, Uninitialized )
828 : m_ ( m ) // The current number of rows of the compressed matrix
829 , n_ ( n ) // The current number of columns of the compressed matrix
830 , capacity_( m ) // The current capacity of the pointer array
831 , begin_( new Iterator[2UL*m+2UL] ) // Pointers to the first non-zero element of each row
832 , end_ ( begin_+(m+1UL) ) // Pointers one past the last non-zero element of each row
833{
834 begin_[0] = nullptr;
835}
836//*************************************************************************************************
837
838
839
840
841//=================================================================================================
842//
843// DESTRUCTOR
844//
845//=================================================================================================
846
847//*************************************************************************************************
850template< typename Type // Data type of the matrix
851 , bool SO // Storage order
852 , typename Tag > // Type tag
854{
855 if( begin_ != nullptr ) {
856 deallocate( begin_[0UL] );
857 delete[] begin_;
858 }
859}
860//*************************************************************************************************
861
862
863
864
865//=================================================================================================
866//
867// DATA ACCESS FUNCTIONS
868//
869//=================================================================================================
870
871//*************************************************************************************************
884template< typename Type // Data type of the matrix
885 , bool SO // Storage order
886 , typename Tag > // Type tag
888 CompressedMatrix<Type,SO,Tag>::operator()( size_t i, size_t j ) noexcept
889{
890 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
891 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
892
893 return Reference( *this, i, j );
894}
895//*************************************************************************************************
896
897
898//*************************************************************************************************
908template< typename Type // Data type of the matrix
909 , bool SO // Storage order
910 , typename Tag > // Type tag
912 CompressedMatrix<Type,SO,Tag>::operator()( size_t i, size_t j ) const noexcept
913{
914 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
915 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
916
917 const ConstIterator pos( lowerBound( i, j ) );
918
919 if( pos == end_[i] || pos->index_ != j )
920 return zero_;
921 else
922 return pos->value_;
923}
924//*************************************************************************************************
925
926
927//*************************************************************************************************
940template< typename Type // Data type of the matrix
941 , bool SO // Storage order
942 , typename Tag > // Type tag
945{
946 if( i >= m_ ) {
947 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
948 }
949 if( j >= n_ ) {
950 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
951 }
952 return (*this)(i,j);
953}
954//*************************************************************************************************
955
956
957//*************************************************************************************************
968template< typename Type // Data type of the matrix
969 , bool SO // Storage order
970 , typename Tag > // Type tag
972 CompressedMatrix<Type,SO,Tag>::at( size_t i, size_t j ) const
973{
974 if( i >= m_ ) {
975 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
976 }
977 if( j >= n_ ) {
978 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
979 }
980 return (*this)(i,j);
981}
982//*************************************************************************************************
983
984
985//*************************************************************************************************
996template< typename Type // Data type of the matrix
997 , bool SO // Storage order
998 , typename Tag > // Type tag
1001{
1002 BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1003 return begin_[i];
1004}
1005//*************************************************************************************************
1006
1007
1008//*************************************************************************************************
1019template< typename Type // Data type of the matrix
1020 , bool SO // Storage order
1021 , typename Tag > // Type tag
1023 CompressedMatrix<Type,SO,Tag>::begin( size_t i ) const noexcept
1024{
1025 BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1026 return begin_[i];
1027}
1028//*************************************************************************************************
1029
1030
1031//*************************************************************************************************
1042template< typename Type // Data type of the matrix
1043 , bool SO // Storage order
1044 , typename Tag > // Type tag
1046 CompressedMatrix<Type,SO,Tag>::cbegin( size_t i ) const noexcept
1047{
1048 BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1049 return begin_[i];
1050}
1051//*************************************************************************************************
1052
1053
1054//*************************************************************************************************
1065template< typename Type // Data type of the matrix
1066 , bool SO // Storage order
1067 , typename Tag > // Type tag
1070{
1071 BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1072 return end_[i];
1073}
1074//*************************************************************************************************
1075
1076
1077//*************************************************************************************************
1088template< typename Type // Data type of the matrix
1089 , bool SO // Storage order
1090 , typename Tag > // Type tag
1092 CompressedMatrix<Type,SO,Tag>::end( size_t i ) const noexcept
1093{
1094 BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1095 return end_[i];
1096}
1097//*************************************************************************************************
1098
1099
1100//*************************************************************************************************
1111template< typename Type // Data type of the matrix
1112 , bool SO // Storage order
1113 , typename Tag > // Type tag
1115 CompressedMatrix<Type,SO,Tag>::cend( size_t i ) const noexcept
1116{
1117 BLAZE_USER_ASSERT( i < m_, "Invalid compressed matrix row access index" );
1118 return end_[i];
1119}
1120//*************************************************************************************************
1121
1122
1123
1124
1125//=================================================================================================
1126//
1127// ASSIGNMENT OPERATORS
1128//
1129//=================================================================================================
1130
1131//*************************************************************************************************
1152template< typename Type // Data type of the matrix
1153 , bool SO // Storage order
1154 , typename Tag > // Type tag
1156 CompressedMatrix<Type,SO,Tag>::operator=( initializer_list< initializer_list<Type> > list ) &
1157{
1158 using blaze::nonZeros;
1159
1160 resize( list.size(), determineColumns( list ), false );
1161 reserve( nonZeros( list ) );
1162
1163 size_t i( 0UL );
1164
1165 for( const auto& rowList : list )
1166 {
1167 size_t j( 0UL );
1168
1169 for( const Type& element : rowList ) {
1170 if( !isDefault<strict>( element ) )
1171 append( i, j, element );
1172 ++j;
1173 }
1174
1175 finalize( i );
1176 ++i;
1177 }
1178
1179 return *this;
1180}
1181//*************************************************************************************************
1182
1183
1184//*************************************************************************************************
1193template< typename Type // Data type of the matrix
1194 , bool SO // Storage order
1195 , typename Tag > // Type tag
1198{
1199 using std::swap;
1200
1201 if( &rhs == this ) return *this;
1202
1203 const size_t nonzeros( rhs.nonZeros() );
1204
1205 if( rhs.m_ > capacity_ || nonzeros > capacity() )
1206 {
1207 Iterator* newBegin( new Iterator[2UL*rhs.m_+2UL] );
1208 Iterator* newEnd ( newBegin+(rhs.m_+1UL) );
1209
1210 newBegin[0UL] = allocate<Element>( nonzeros );
1211 for( size_t i=0UL; i<rhs.m_; ++i ) {
1212 newEnd[i] = castDown( std::copy( rhs.begin_[i], rhs.end_[i], castUp( newBegin[i] ) ) );
1213 newBegin[i+1UL] = newEnd[i];
1214 }
1215 newEnd[rhs.m_] = newBegin[0UL]+nonzeros;
1216
1217 swap( begin_, newBegin );
1218 end_ = newEnd;
1219 capacity_ = rhs.m_;
1220
1221 if( newBegin != nullptr ) {
1222 deallocate( newBegin[0UL] );
1223 delete[] newBegin;
1224 }
1225 }
1226 else {
1227 for( size_t i=0UL; i<rhs.m_; ++i ) {
1228 end_[i] = castDown( std::copy( rhs.begin_[i], rhs.end_[i], castUp( begin_[i] ) ) );
1229 begin_[i+1UL] = end_[i];
1230 }
1231 }
1232
1233 m_ = rhs.m_;
1234 n_ = rhs.n_;
1235
1236 return *this;
1237}
1238//*************************************************************************************************
1239
1240
1241//*************************************************************************************************
1247template< typename Type // Data type of the matrix
1248 , bool SO // Storage order
1249 , typename Tag > // Type tag
1252{
1253 if( begin_ != nullptr ) {
1254 deallocate( begin_[0UL] );
1255 delete[] begin_;
1256 }
1257
1258 m_ = rhs.m_;
1259 n_ = rhs.n_;
1260 capacity_ = rhs.capacity_;
1261 begin_ = rhs.begin_;
1262 end_ = rhs.end_;
1263
1264 rhs.m_ = 0UL;
1265 rhs.n_ = 0UL;
1266 rhs.capacity_ = 0UL;
1267 rhs.begin_ = nullptr;
1268 rhs.end_ = nullptr;
1269
1270 return *this;
1271}
1272//*************************************************************************************************
1273
1274
1275//*************************************************************************************************
1284template< typename Type // Data type of the matrix
1285 , bool SO // Storage order
1286 , typename Tag > // Type tag
1287template< typename MT // Type of the right-hand side dense matrix
1288 , bool SO2 > // Storage order of the right-hand side dense matrix
1289inline CompressedMatrix<Type,SO,Tag>&
1291{
1292 using blaze::assign;
1293
1295
1296 if( (*rhs).canAlias( this ) ) {
1297 CompressedMatrix tmp( *rhs );
1298 swap( tmp );
1299 }
1300 else {
1301 resize( (*rhs).rows(), (*rhs).columns(), false );
1302 assign( *this, *rhs );
1303 }
1304
1305 return *this;
1306}
1307//*************************************************************************************************
1308
1309
1310//*************************************************************************************************
1319template< typename Type // Data type of the matrix
1320 , bool SO // Storage order
1321 , typename Tag > // Type tag
1322template< typename MT // Type of the right-hand side compressed matrix
1323 , bool SO2 > // Storage order of the right-hand side compressed matrix
1326{
1327 using blaze::assign;
1328
1330
1331 if( (*rhs).canAlias( this ) ||
1332 (*rhs).rows() > capacity_ ||
1333 (*rhs).nonZeros() > capacity() ) {
1334 CompressedMatrix tmp( *rhs );
1335 swap( tmp );
1336 }
1337 else {
1338 resize( (*rhs).rows(), (*rhs).columns(), false );
1339 reset();
1340
1341 if( !IsZero_v<MT> ) {
1342 assign( *this, *rhs );
1343 }
1344 }
1345
1346 return *this;
1347}
1348//*************************************************************************************************
1349
1350
1351//*************************************************************************************************
1361template< typename Type // Data type of the matrix
1362 , bool SO // Storage order
1363 , typename Tag > // Type tag
1364template< typename MT // Type of the right-hand side matrix
1365 , bool SO2 > // Storage order of the right-hand side matrix
1368{
1369 using blaze::addAssign;
1370
1372
1373 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
1374 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1375 }
1376
1377 if( !IsZero_v<MT> ) {
1378 addAssign( *this, *rhs );
1379 }
1380
1381 return *this;
1382}
1383//*************************************************************************************************
1384
1385
1386//*************************************************************************************************
1396template< typename Type // Data type of the matrix
1397 , bool SO // Storage order
1398 , typename Tag > // Type tag
1399template< typename MT // Type of the right-hand side matrix
1400 , bool SO2 > // Storage order of the right-hand side matrix
1403{
1404 using blaze::subAssign;
1405
1407
1408 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
1409 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1410 }
1411
1412 if( !IsZero_v<MT> ) {
1413 subAssign( *this, *rhs );
1414 }
1415
1416 return *this;
1417}
1418//*************************************************************************************************
1419
1420
1421//*************************************************************************************************
1432template< typename Type // Data type of the matrix
1433 , bool SO // Storage order
1434 , typename Tag > // Type tag
1435template< typename MT // Type of the right-hand side dense matrix
1436 , bool SO2 > // Storage order of the right-hand side dense matrix
1439{
1440 using blaze::schurAssign;
1441
1443
1444 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
1445 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1446 }
1447
1448 if( (*rhs).canAlias( this ) ) {
1449 CompressedMatrix tmp( *this % (*rhs) );
1450 swap( tmp );
1451 }
1452 else {
1453 CompositeType_t<MT> tmp( *rhs );
1454 schurAssign( *this, tmp );
1455 }
1456
1457 return *this;
1458}
1459//*************************************************************************************************
1460
1461
1462//*************************************************************************************************
1473template< typename Type // Data type of the matrix
1474 , bool SO // Storage order
1475 , typename Tag > // Type tag
1476template< typename MT // Type of the right-hand side sparse matrix
1477 , bool SO2 > // Storage order of the right-hand side sparse matrix
1480{
1482
1483 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
1484 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1485 }
1486
1487 if( !IsZero_v<MT> ) {
1488 CompressedMatrix tmp( *this % (*rhs) );
1489 swap( tmp );
1490 }
1491 else {
1492 reset();
1493 }
1494
1495 return *this;
1496}
1497//*************************************************************************************************
1498
1499
1500
1501
1502//=================================================================================================
1503//
1504// UTILITY FUNCTIONS
1505//
1506//=================================================================================================
1507
1508//*************************************************************************************************
1513template< typename Type // Data type of the matrix
1514 , bool SO // Storage order
1515 , typename Tag > // Type tag
1516inline size_t CompressedMatrix<Type,SO,Tag>::rows() const noexcept
1517{
1518 return m_;
1519}
1520//*************************************************************************************************
1521
1522
1523//*************************************************************************************************
1528template< typename Type // Data type of the matrix
1529 , bool SO // Storage order
1530 , typename Tag > // Type tag
1531inline size_t CompressedMatrix<Type,SO,Tag>::columns() const noexcept
1532{
1533 return n_;
1534}
1535//*************************************************************************************************
1536
1537
1538//*************************************************************************************************
1543template< typename Type // Data type of the matrix
1544 , bool SO // Storage order
1545 , typename Tag > // Type tag
1546inline size_t CompressedMatrix<Type,SO,Tag>::capacity() const noexcept
1547{
1548 if( begin_ != nullptr )
1549 return end_[m_] - begin_[0UL];
1550 else return 0UL;
1551}
1552//*************************************************************************************************
1553
1554
1555//*************************************************************************************************
1566template< typename Type // Data type of the matrix
1567 , bool SO // Storage order
1568 , typename Tag > // Type tag
1569inline size_t CompressedMatrix<Type,SO,Tag>::capacity( size_t i ) const noexcept
1570{
1571 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1572 return begin_[i+1UL] - begin_[i];
1573}
1574//*************************************************************************************************
1575
1576
1577//*************************************************************************************************
1582template< typename Type // Data type of the matrix
1583 , bool SO // Storage order
1584 , typename Tag > // Type tag
1586{
1587 size_t nonzeros( 0UL );
1588
1589 for( size_t i=0UL; i<m_; ++i )
1590 nonzeros += nonZeros( i );
1591
1592 return nonzeros;
1593}
1594//*************************************************************************************************
1595
1596
1597//*************************************************************************************************
1608template< typename Type // Data type of the matrix
1609 , bool SO // Storage order
1610 , typename Tag > // Type tag
1611inline size_t CompressedMatrix<Type,SO,Tag>::nonZeros( size_t i ) const
1612{
1613 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1614 return end_[i] - begin_[i];
1615}
1616//*************************************************************************************************
1617
1618
1619//*************************************************************************************************
1624template< typename Type // Data type of the matrix
1625 , bool SO // Storage order
1626 , typename Tag > // Type tag
1628{
1629 for( size_t i=0UL; i<m_; ++i )
1630 end_[i] = begin_[i];
1631}
1632//*************************************************************************************************
1633
1634
1635//*************************************************************************************************
1646template< typename Type // Data type of the matrix
1647 , bool SO // Storage order
1648 , typename Tag > // Type tag
1650{
1651 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1652 end_[i] = begin_[i];
1653}
1654//*************************************************************************************************
1655
1656
1657//*************************************************************************************************
1664template< typename Type // Data type of the matrix
1665 , bool SO // Storage order
1666 , typename Tag > // Type tag
1668{
1669 if( end_ != nullptr )
1670 end_[0UL] = end_[m_];
1671 m_ = 0UL;
1672 n_ = 0UL;
1673}
1674//*************************************************************************************************
1675
1676
1677//*************************************************************************************************
1692template< typename Type // Data type of the matrix
1693 , bool SO // Storage order
1694 , typename Tag > // Type tag
1695void CompressedMatrix<Type,SO,Tag>::resize( size_t m, size_t n, bool preserve )
1696{
1697 using std::swap;
1698
1699 BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1700 BLAZE_INTERNAL_ASSERT( begin_ == nullptr || size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1701
1702 if( m == m_ && n == n_ ) return;
1703
1704 if( begin_ == nullptr )
1705 {
1706 begin_ = new Iterator[2UL*m+2UL];
1707 end_ = begin_+m+1UL;
1708
1709 for( size_t i=0UL; i<2UL*m+2UL; ++i ) {
1710 begin_[i] = nullptr;
1711 }
1712
1713 capacity_ = m;
1714 }
1715 else if( m > capacity_ )
1716 {
1717 Iterator* newBegin( new Iterator[2UL*m+2UL] );
1718 Iterator* newEnd ( newBegin+m+1UL );
1719
1720 newBegin[0UL] = begin_[0UL];
1721
1722 if( preserve ) {
1723 for( size_t i=0UL; i<m_; ++i ) {
1724 newEnd [i] = end_ [i];
1725 newBegin[i+1UL] = begin_[i+1UL];
1726 }
1727 for( size_t i=m_; i<m; ++i ) {
1728 newBegin[i+1UL] = newEnd[i] = begin_[m_];
1729 }
1730 }
1731 else {
1732 for( size_t i=0UL; i<m; ++i ) {
1733 newBegin[i+1UL] = newEnd[i] = begin_[0UL];
1734 }
1735 }
1736
1737 newEnd[m] = end_[m_];
1738
1739 swap( newBegin, begin_ );
1740 delete[] newBegin;
1741 end_ = newEnd;
1742 capacity_ = m;
1743 }
1744 else if( m > m_ )
1745 {
1746 end_[m] = end_[m_];
1747
1748 if( !preserve ) {
1749 for( size_t i=0UL; i<m_; ++i )
1750 end_[i] = begin_[i];
1751 }
1752
1753 for( size_t i=m_; i<m; ++i ) {
1754 begin_[i+1UL] = end_[i] = begin_[m_];
1755 }
1756 }
1757 else
1758 {
1759 if( preserve ) {
1760 for( size_t i=0UL; i<m; ++i )
1761 end_[i] = lowerBound( i, n );
1762 }
1763 else {
1764 for( size_t i=0UL; i<m; ++i )
1765 end_[i] = begin_[i];
1766 }
1767
1768 end_[m] = end_[m_];
1769 }
1770
1771 m_ = m;
1772 n_ = n;
1773
1774 BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1775 BLAZE_INTERNAL_ASSERT( size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1776}
1777//*************************************************************************************************
1778
1779
1780//*************************************************************************************************
1790template< typename Type // Data type of the matrix
1791 , bool SO // Storage order
1792 , typename Tag > // Type tag
1793inline void CompressedMatrix<Type,SO,Tag>::reserve( size_t nonzeros )
1794{
1795 if( nonzeros > capacity() )
1796 reserveElements( nonzeros );
1797}
1798//*************************************************************************************************
1799
1800
1801//*************************************************************************************************
1815template< typename Type // Data type of the matrix
1816 , bool SO // Storage order
1817 , typename Tag > // Type tag
1818void CompressedMatrix<Type,SO,Tag>::reserve( size_t i, size_t nonzeros )
1819{
1820 using std::swap;
1821
1822 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1823
1824 BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1825 BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1826
1827 const size_t current( capacity(i) );
1828
1829 if( current >= nonzeros ) return;
1830
1831 const ptrdiff_t additional( nonzeros - current );
1832
1833 if( end_[m_] - begin_[m_] < additional )
1834 {
1835 const size_t newCapacity( begin_[m_] - begin_[0UL] + additional );
1836 BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
1837
1838 Iterator* newBegin( new Iterator[2UL*m_+2UL] );
1839 Iterator* newEnd ( newBegin+m_+1UL );
1840
1841 newBegin[0UL] = allocate<Element>( newCapacity );
1842 newEnd [m_ ] = newBegin[0UL]+newCapacity;
1843
1844 for( size_t k=0UL; k<i; ++k ) {
1845 newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
1846 newBegin[k+1UL] = newBegin[k] + capacity(k);
1847 }
1848 newEnd [i ] = castDown( transfer( begin_[i], end_[i], castUp( newBegin[i] ) ) );
1849 newBegin[i+1UL] = newBegin[i] + nonzeros;
1850 for( size_t k=i+1UL; k<m_; ++k ) {
1851 newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
1852 newBegin[k+1UL] = newBegin[k] + capacity(k);
1853 }
1854
1855 BLAZE_INTERNAL_ASSERT( newBegin[m_] == newEnd[m_], "Invalid pointer calculations" );
1856
1857 swap( newBegin, begin_ );
1858 deallocate( newBegin[0UL] );
1859 delete[] newBegin;
1860 end_ = newEnd;
1861 capacity_ = m_;
1862 }
1863 else
1864 {
1865 begin_[m_] += additional;
1866 for( size_t j=m_-1UL; j>i; --j ) {
1867 begin_[j] = castDown( std::move_backward( begin_[j], end_[j], castUp( end_[j]+additional ) ) );
1868 end_ [j] += additional;
1869 }
1870 }
1871
1872 BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
1873 BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
1874}
1875//*************************************************************************************************
1876
1877
1878//*************************************************************************************************
1888template< typename Type // Data type of the matrix
1889 , bool SO // Storage order
1890 , typename Tag > // Type tag
1892{
1893 for( size_t i=0UL; i<m_; ++i )
1894 trim( i );
1895}
1896//*************************************************************************************************
1897
1898
1899//*************************************************************************************************
1910template< typename Type // Data type of the matrix
1911 , bool SO // Storage order
1912 , typename Tag > // Type tag
1914{
1915 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1916
1917 if( i < ( m_ - 1UL ) )
1918 end_[i+1] = castDown( std::move( begin_[i+1], end_[i+1], castUp( end_[i] ) ) );
1919 begin_[i+1] = end_[i];
1920}
1921//*************************************************************************************************
1922
1923
1924//*************************************************************************************************
1933template< typename Type // Data type of the matrix
1934 , bool SO // Storage order
1935 , typename Tag > // Type tag
1937{
1938 if( nonZeros() < capacity() ) {
1939 CompressedMatrix( *this ).swap( *this );
1940 }
1941}
1942//*************************************************************************************************
1943
1944
1945//*************************************************************************************************
1951template< typename Type // Data type of the matrix
1952 , bool SO // Storage order
1953 , typename Tag > // Type tag
1955{
1956 using std::swap;
1957
1958 swap( m_, sm.m_ );
1959 swap( n_, sm.n_ );
1960 swap( capacity_, sm.capacity_ );
1961 swap( begin_, sm.begin_ );
1962 swap( end_ , sm.end_ );
1963}
1964//*************************************************************************************************
1965
1966
1967//*************************************************************************************************
1975template< typename Type // Data type of the matrix
1976 , bool SO // Storage order
1977 , typename Tag > // Type tag
1979{
1980 size_t nonzeros( 2UL*capacity()+1UL );
1981 nonzeros = blaze::max( nonzeros, 7UL );
1982
1983 BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
1984
1985 return nonzeros;
1986}
1987//*************************************************************************************************
1988
1989
1990//*************************************************************************************************
1996template< typename Type // Data type of the matrix
1997 , bool SO // Storage order
1998 , typename Tag > // Type tag
2000{
2001 using std::swap;
2002
2003 Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
2004 Iterator* newEnd = newBegin+capacity_+1UL;
2005
2006 newBegin[0UL] = allocate<Element>( nonzeros );
2007
2008 for( size_t k=0UL; k<m_; ++k ) {
2009 BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid row pointers" );
2010 newEnd [k] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
2011 newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
2012 }
2013
2014 newEnd[m_] = newBegin[0UL]+nonzeros;
2015
2016 swap( newBegin, begin_ );
2017 end_ = newEnd;
2018
2019 if( newBegin != nullptr ) {
2020 deallocate( newBegin[0UL] );
2021 delete[] newBegin;
2022 }
2023}
2024//*************************************************************************************************
2025
2026
2027//*************************************************************************************************
2035template< typename Type // Data type of the matrix
2036 , bool SO // Storage order
2037 , typename Tag > // Type tag
2040{
2041 return static_cast<Iterator>( it );
2042}
2043//*************************************************************************************************
2044
2045
2046//*************************************************************************************************
2054template< typename Type // Data type of the matrix
2055 , bool SO // Storage order
2056 , typename Tag > // Type tag
2059{
2060 return static_cast<IteratorBase>( it );
2061}
2062//*************************************************************************************************
2063
2064
2065
2066
2067//=================================================================================================
2068//
2069// INSERTION FUNCTIONS
2070//
2071//=================================================================================================
2072
2073//*************************************************************************************************
2085template< typename Type // Data type of the matrix
2086 , bool SO // Storage order
2087 , typename Tag > // Type tag
2089 CompressedMatrix<Type,SO,Tag>::set( size_t i, size_t j, const Type& value )
2090{
2091 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2092 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2093
2094 const Iterator pos( lowerBound( i, j ) );
2095
2096 if( pos != end_[i] && pos->index_ == j ) {
2097 pos->value() = value;
2098 return pos;
2099 }
2100 else return insert( pos, i, j, value );
2101}
2102//*************************************************************************************************
2103
2104
2105//*************************************************************************************************
2118template< typename Type // Data type of the matrix
2119 , bool SO // Storage order
2120 , typename Tag > // Type tag
2122 CompressedMatrix<Type,SO,Tag>::insert( size_t i, size_t j, const Type& value )
2123{
2124 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2125 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2126
2127 const Iterator pos( lowerBound( i, j ) );
2128
2129 if( pos != end_[i] && pos->index_ == j ) {
2130 BLAZE_THROW_INVALID_ARGUMENT( "Bad access index" );
2131 }
2132
2133 return insert( pos, i, j, value );
2134}
2135//*************************************************************************************************
2136
2137
2138//*************************************************************************************************
2148template< typename Type // Data type of the matrix
2149 , bool SO // Storage order
2150 , typename Tag > // Type tag
2152 CompressedMatrix<Type,SO,Tag>::insert( Iterator pos, size_t i, size_t j, const Type& value )
2153{
2154 using std::swap;
2155
2156 if( begin_[i+1UL] - end_[i] != 0 ) {
2157 std::move_backward( pos, end_[i], castUp( end_[i]+1UL ) );
2158 pos->value_ = value;
2159 pos->index_ = j;
2160 ++end_[i];
2161
2162 return pos;
2163 }
2164 else if( end_[m_] - begin_[m_] != 0 ) {
2165 std::move_backward( pos, end_[m_-1UL], castUp( end_[m_-1UL]+1UL ) );
2166
2167 pos->value_ = value;
2168 pos->index_ = j;
2169
2170 for( size_t k=i+1UL; k<m_+1UL; ++k ) {
2171 ++begin_[k];
2172 ++end_[k-1UL];
2173 }
2174
2175 return pos;
2176 }
2177 else {
2178 size_t newCapacity( extendCapacity() );
2179
2180 Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
2181 Iterator* newEnd = newBegin+capacity_+1UL;
2182
2183 newBegin[0UL] = allocate<Element>( newCapacity );
2184
2185 for( size_t k=0UL; k<i; ++k ) {
2186 const size_t nonzeros( end_[k] - begin_[k] );
2187 const size_t total( begin_[k+1UL] - begin_[k] );
2188 newEnd [k] = newBegin[k] + nonzeros;
2189 newBegin[k+1UL] = newBegin[k] + total;
2190 }
2191 newEnd [i] = newBegin[i] + ( end_[i] - begin_[i] ) + 1;
2192 newBegin[i+1UL] = newBegin[i] + ( begin_[i+1] - begin_[i] ) + 1;
2193 for( size_t k=i+1UL; k<m_; ++k ) {
2194 const size_t nonzeros( end_[k] - begin_[k] );
2195 const size_t total( begin_[k+1UL] - begin_[k] );
2196 newEnd [k] = newBegin[k] + nonzeros;
2197 newBegin[k+1UL] = newBegin[k] + total;
2198 }
2199
2200 newEnd[m_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
2201
2202 Iterator tmp = castDown( std::move( begin_[0UL], pos, castUp( newBegin[0UL] ) ) );
2203 tmp->value_ = value;
2204 tmp->index_ = j;
2205 std::move( pos, end_[m_-1UL], castUp( tmp+1UL ) );
2206
2207 swap( newBegin, begin_ );
2208 end_ = newEnd;
2209 deallocate( newBegin[0UL] );
2210 delete[] newBegin;
2211
2212 return tmp;
2213 }
2214}
2215//*************************************************************************************************
2216
2217
2218//*************************************************************************************************
2271template< typename Type // Data type of the matrix
2272 , bool SO // Storage order
2273 , typename Tag > // Type tag
2274inline void CompressedMatrix<Type,SO,Tag>::append( size_t i, size_t j, const Type& value, bool check )
2275{
2276 BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2277 BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
2278 BLAZE_USER_ASSERT( end_[i] < end_[m_], "Not enough reserved capacity left" );
2279 BLAZE_USER_ASSERT( begin_[i] == end_[i] || j > ( end_[i]-1UL )->index_, "Index is not strictly increasing" );
2280
2281 end_[i]->value_ = value;
2282
2283 if( !check || !isDefault<strict>( end_[i]->value_ ) ) {
2284 end_[i]->index_ = j;
2285 ++end_[i];
2286 }
2287}
2288//*************************************************************************************************
2289
2290
2291//*************************************************************************************************
2304template< typename Type // Data type of the matrix
2305 , bool SO // Storage order
2306 , typename Tag > // Type tag
2308{
2309 BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
2310
2311 begin_[i+1UL] = end_[i];
2312 if( i != m_-1UL )
2313 end_[i+1UL] = end_[i];
2314}
2315//*************************************************************************************************
2316
2317
2318
2319
2320//=================================================================================================
2321//
2322// ERASE FUNCTIONS
2323//
2324//=================================================================================================
2325
2326//*************************************************************************************************
2335template< typename Type // Data type of the matrix
2336 , bool SO // Storage order
2337 , typename Tag > // Type tag
2338inline void CompressedMatrix<Type,SO,Tag>::erase( size_t i, size_t j )
2339{
2340 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2341 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2342
2343 const Iterator pos( find( i, j ) );
2344 if( pos != end_[i] )
2345 end_[i] = castDown( std::move( pos+1, end_[i], castUp( pos ) ) );
2346}
2347//*************************************************************************************************
2348
2349
2350//*************************************************************************************************
2361template< typename Type // Data type of the matrix
2362 , bool SO // Storage order
2363 , typename Tag > // Type tag
2366{
2367 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2368 BLAZE_USER_ASSERT( pos >= begin_[i] && pos <= end_[i], "Invalid compressed matrix iterator" );
2369
2370 if( pos != end_[i] )
2371 end_[i] = castDown( std::move( pos+1, end_[i], castUp( pos ) ) );
2372
2373 return pos;
2374}
2375//*************************************************************************************************
2376
2377
2378//*************************************************************************************************
2390template< typename Type // Data type of the matrix
2391 , bool SO // Storage order
2392 , typename Tag > // Type tag
2395{
2396 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2397 BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
2398 BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i], "Invalid compressed matrix iterator" );
2399 BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i], "Invalid compressed matrix iterator" );
2400
2401 if( first != last )
2402 end_[i] = castDown( std::move( last, end_[i], castUp( first ) ) );
2403
2404 return first;
2405}
2406//*************************************************************************************************
2407
2408
2409//*************************************************************************************************
2430template< typename Type // Data type of the matrix
2431 , bool SO // Storage order
2432 , typename Tag > // Type tag
2433template< typename Pred > // Type of the unary predicate
2434inline void CompressedMatrix<Type,SO,Tag>::erase( Pred predicate )
2435{
2436 for( size_t i=0UL; i<m_; ++i ) {
2437 end_[i] = castDown( std::remove_if( castUp( begin_[i] ), castUp( end_[i] ),
2438 [predicate=predicate]( const ElementBase& element) {
2439 return predicate( element.value() );
2440 } ) );
2441 }
2442}
2443//*************************************************************************************************
2444
2445
2446//*************************************************************************************************
2473template< typename Type // Data type of the matrix
2474 , bool SO // Storage order
2475 , typename Tag > // Type tag
2476template< typename Pred > // Type of the unary predicate
2477inline void CompressedMatrix<Type,SO,Tag>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
2478{
2479 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2480 BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
2481 BLAZE_USER_ASSERT( first >= begin_[i] && first <= end_[i], "Invalid compressed matrix iterator" );
2482 BLAZE_USER_ASSERT( last >= begin_[i] && last <= end_[i], "Invalid compressed matrix iterator" );
2483
2484 const auto pos = std::remove_if( castUp( first ), castUp( last ),
2485 [predicate=predicate]( const ElementBase& element ) {
2486 return predicate( element.value() );
2487 } );
2488
2489 end_[i] = castDown( std::move( last, end_[i], pos ) );
2490}
2491//*************************************************************************************************
2492
2493
2494
2495
2496//=================================================================================================
2497//
2498// LOOKUP FUNCTIONS
2499//
2500//=================================================================================================
2501
2502//*************************************************************************************************
2517template< typename Type // Data type of the matrix
2518 , bool SO // Storage order
2519 , typename Tag > // Type tag
2522{
2523 return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
2524}
2525//*************************************************************************************************
2526
2527
2528//*************************************************************************************************
2543template< typename Type // Data type of the matrix
2544 , bool SO // Storage order
2545 , typename Tag > // Type tag
2547 CompressedMatrix<Type,SO,Tag>::find( size_t i, size_t j ) const
2548{
2549 const ConstIterator pos( lowerBound( i, j ) );
2550 if( pos != end_[i] && pos->index_ == j )
2551 return pos;
2552 else return end_[i];
2553}
2554//*************************************************************************************************
2555
2556
2557//*************************************************************************************************
2572template< typename Type // Data type of the matrix
2573 , bool SO // Storage order
2574 , typename Tag > // Type tag
2577{
2578 return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
2579}
2580//*************************************************************************************************
2581
2582
2583//*************************************************************************************************
2598template< typename Type // Data type of the matrix
2599 , bool SO // Storage order
2600 , typename Tag > // Type tag
2603{
2604 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2605 return std::lower_bound( begin_[i], end_[i], j,
2606 []( const Element& element, size_t index )
2607 {
2608 return element.index() < index;
2609 } );
2610}
2611//*************************************************************************************************
2612
2613
2614//*************************************************************************************************
2629template< typename Type // Data type of the matrix
2630 , bool SO // Storage order
2631 , typename Tag > // Type tag
2634{
2635 return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
2636}
2637//*************************************************************************************************
2638
2639
2640//*************************************************************************************************
2655template< typename Type // Data type of the matrix
2656 , bool SO // Storage order
2657 , typename Tag > // Type tag
2660{
2661 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2662 return std::upper_bound( begin_[i], end_[i], j,
2663 []( size_t index, const Element& element )
2664 {
2665 return index < element.index();
2666 } );
2667}
2668//*************************************************************************************************
2669
2670
2671
2672
2673//=================================================================================================
2674//
2675// NUMERIC FUNCTIONS
2676//
2677//=================================================================================================
2678
2679//*************************************************************************************************
2684template< typename Type // Data type of the matrix
2685 , bool SO // Storage order
2686 , typename Tag > // Type tag
2688{
2689 CompressedMatrix tmp( trans( *this ) );
2690 swap( tmp );
2691 return *this;
2692}
2693//*************************************************************************************************
2694
2695
2696//*************************************************************************************************
2701template< typename Type // Data type of the matrix
2702 , bool SO // Storage order
2703 , typename Tag > // Type tag
2705{
2706 CompressedMatrix tmp( ctrans( *this ) );
2707 swap( tmp );
2708 return *this;
2709}
2710//*************************************************************************************************
2711
2712
2713//*************************************************************************************************
2730template< typename Type // Data type of the matrix
2731 , bool SO // Storage order
2732 , typename Tag > // Type tag
2733template< typename Other > // Data type of the scalar value
2735{
2736 for( size_t i=0UL; i<m_; ++i )
2737 for( auto element=begin_[i]; element!=end_[i]; ++element )
2738 element->value_ *= scalar;
2739
2740 return *this;
2741}
2742//*************************************************************************************************
2743
2744
2745
2746
2747//=================================================================================================
2748//
2749// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2750//
2751//=================================================================================================
2752
2753//*************************************************************************************************
2763template< typename Type // Data type of the matrix
2764 , bool SO // Storage order
2765 , typename Tag > // Type tag
2766template< typename Other > // Data type of the foreign expression
2767inline bool CompressedMatrix<Type,SO,Tag>::canAlias( const Other* alias ) const noexcept
2768{
2769 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2770}
2771//*************************************************************************************************
2772
2773
2774//*************************************************************************************************
2784template< typename Type // Data type of the matrix
2785 , bool SO // Storage order
2786 , typename Tag > // Type tag
2787template< typename Other > // Data type of the foreign expression
2788inline bool CompressedMatrix<Type,SO,Tag>::isAliased( const Other* alias ) const noexcept
2789{
2790 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2791}
2792//*************************************************************************************************
2793
2794
2795//*************************************************************************************************
2805template< typename Type // Data type of the matrix
2806 , bool SO // Storage order
2807 , typename Tag > // Type tag
2809{
2810 return false;
2811}
2812//*************************************************************************************************
2813
2814
2815//*************************************************************************************************
2826template< typename Type // Data type of the matrix
2827 , bool SO // Storage order
2828 , typename Tag > // Type tag
2829template< typename MT // Type of the right-hand side dense matrix
2830 , bool SO2 > // Storage order of the right-hand side dense matrix
2832{
2833 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2834 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2835
2836 if( m_ == 0UL || n_ == 0UL )
2837 return;
2838
2839 size_t nonzeros( 0UL );
2840
2841 for( size_t i=1UL; i<=m_; ++i )
2842 begin_[i] = end_[i] = end_[m_];
2843
2844 for( size_t i=0UL; i<m_; ++i )
2845 {
2846 begin_[i] = end_[i] = begin_[0UL]+nonzeros;
2847
2848 const size_t jbegin( ( IsUpper_v<MT> )
2849 ?( IsStrictlyUpper_v<MT> ? i+1UL : i )
2850 :( 0UL ) );
2851 const size_t jend ( ( IsLower_v<MT> )
2852 ?( IsStrictlyLower_v<MT> ? i : i+1UL )
2853 :( n_ ) );
2854
2855 for( size_t j=jbegin; j<jend; ++j )
2856 {
2857 if( nonzeros == capacity() ) {
2858 reserveElements( extendCapacity() );
2859 for( size_t k=i+1UL; k<=m_; ++k )
2860 begin_[k] = end_[k] = end_[m_];
2861 }
2862
2863 end_[i]->value_ = (*rhs)(i,j);
2864
2865 if( !isDefault<strict>( end_[i]->value_ ) ) {
2866 end_[i]->index_ = j;
2867 ++end_[i];
2868 ++nonzeros;
2869 }
2870 }
2871 }
2872
2873 begin_[m_] = begin_[0UL]+nonzeros;
2874}
2875//*************************************************************************************************
2876
2877
2878//*************************************************************************************************
2889template< typename Type // Data type of the matrix
2890 , bool SO // Storage order
2891 , typename Tag > // Type tag
2892template< typename MT > // Type of the right-hand side compressed matrix
2894{
2895 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2896 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2897 BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2898 BLAZE_INTERNAL_ASSERT( capacity() >= (*rhs).nonZeros(), "Invalid capacity detected" );
2899
2900 if( m_ == 0UL || begin_[0] == nullptr )
2901 return;
2902
2903 for( size_t i=0UL; i<m_; ++i ) {
2904 end_[i] = castDown( std::copy( (*rhs).begin(i), (*rhs).end(i), castUp( begin_[i] ) ) );
2905 begin_[i+1UL] = end_[i];
2906 }
2907}
2908//*************************************************************************************************
2909
2910
2911//*************************************************************************************************
2922template< typename Type // Data type of the matrix
2923 , bool SO // Storage order
2924 , typename Tag > // Type tag
2925template< typename MT > // Type of the right-hand side compressed matrix
2927{
2929
2930 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2931 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2932 BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2933 BLAZE_INTERNAL_ASSERT( capacity() >= (*rhs).nonZeros(), "Invalid capacity detected" );
2934
2935 // Counting the number of elements per row
2936 std::vector<size_t> rowLengths( m_, 0UL );
2937 for( size_t j=0UL; j<n_; ++j ) {
2938 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
2939 ++rowLengths[element->index()];
2940 }
2941
2942 // Resizing the compressed matrix
2943 for( size_t i=0UL; i<m_; ++i ) {
2944 begin_[i+1UL] = end_[i+1UL] = begin_[i] + rowLengths[i];
2945 }
2946
2947 // Appending the elements to the rows of the compressed matrix
2948 for( size_t j=0UL; j<n_; ++j ) {
2949 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
2950 append( element->index(), j, element->value() );
2951 }
2952}
2953//*************************************************************************************************
2954
2955
2956//*************************************************************************************************
2967template< typename Type // Data type of the matrix
2968 , bool SO // Storage order
2969 , typename Tag > // Type tag
2970template< typename MT // Type of the right-hand side dense matrix
2971 , bool SO2 > // Storage order of the right-hand side dense matrix
2973{
2974 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2975 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2976
2977 CompressedMatrix tmp( serial( *this + (*rhs) ) );
2978 swap( tmp );
2979}
2980//*************************************************************************************************
2981
2982
2983//*************************************************************************************************
2994template< typename Type // Data type of the matrix
2995 , bool SO // Storage order
2996 , typename Tag > // Type tag
2997template< typename MT // Type of the right-hand side compressed matrix
2998 , bool SO2 > // Storage order of the right-hand side compressed matrix
3000{
3001 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3002 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3003
3004 CompressedMatrix tmp( serial( *this + (*rhs) ) );
3005 swap( tmp );
3006}
3007//*************************************************************************************************
3008
3009
3010//*************************************************************************************************
3021template< typename Type // Data type of the matrix
3022 , bool SO // Storage order
3023 , typename Tag > // Type tag
3024template< typename MT // Type of the right-hand side dense matrix
3025 , bool SO2 > // Storage order of the right-hand side dense matrix
3027{
3028 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3029 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3030
3031 CompressedMatrix tmp( serial( *this - (*rhs) ) );
3032 swap( tmp );
3033}
3034//*************************************************************************************************
3035
3036
3037//*************************************************************************************************
3048template< typename Type // Data type of the matrix
3049 , bool SO // Storage order
3050 , typename Tag > // Type tag
3051template< typename MT // Type of the right-hand side compressed matrix
3052 , bool SO2 > // Storage order of the right-hand compressed matrix
3054{
3055 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3056 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3057
3058 CompressedMatrix tmp( serial( *this - (*rhs) ) );
3059 swap( tmp );
3060}
3061//*************************************************************************************************
3062
3063
3064//*************************************************************************************************
3075template< typename Type // Data type of the matrix
3076 , bool SO // Storage order
3077 , typename Tag > // Type tag
3078template< typename MT // Type of the right-hand side dense matrix
3079 , bool SO2 > // Storage order of the right-hand side dense matrix
3081{
3082 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3083 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3084
3086
3087 for( size_t i=0UL; i<m_; ++i ) {
3088 const Iterator last( end(i) );
3089 for( auto element=begin(i); element!=last; ++element )
3090 element->value_ *= (*rhs)(i,element->index_);
3091 }
3092}
3093//*************************************************************************************************
3094
3095
3096
3097
3098
3099
3100
3101
3102//=================================================================================================
3103//
3104// CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
3105//
3106//=================================================================================================
3107
3108//*************************************************************************************************
3116template< typename Type // Data type of the matrix
3117 , typename Tag > // Type tag
3118class CompressedMatrix<Type,true,Tag>
3119 : public SparseMatrix< CompressedMatrix<Type,true,Tag>, true >
3120{
3121 private:
3122 //**Type definitions****************************************************************************
3124 using IteratorBase = ElementBase*;
3125 //**********************************************************************************************
3126
3127 //**Private class Element***********************************************************************
3133 struct Element
3134 : public ElementBase
3135 {
3136 //**Constructors*****************************************************************************
3137 Element() = default;
3138 Element( const Element& rhs ) = default;
3139 Element( Element&& rhs ) = default;
3140 //*******************************************************************************************
3141
3142 //**Assignment operators*********************************************************************
3143 inline Element& operator=( const Element& rhs )
3144 {
3145 this->value_ = rhs.value_;
3146 return *this;
3147 }
3148
3149 inline Element& operator=( Element&& rhs )
3150 {
3151 this->value_ = std::move( rhs.value_ );
3152 return *this;
3153 }
3154
3155 template< typename Other >
3156 inline auto operator=( const Other& rhs )
3157 -> EnableIf_t< IsSparseElement_v<Other>, Element& >
3158 {
3159 this->value_ = rhs.value();
3160 return *this;
3161 }
3162
3163 template< typename Other >
3164 inline auto operator=( Other&& rhs )
3165 -> EnableIf_t< IsSparseElement_v< RemoveReference_t<Other> > &&
3166 IsRValueReference_v<Other&&>, Element& >
3167 {
3168 this->value_ = std::move( rhs.value() );
3169 return *this;
3170 }
3171
3172 template< typename Other >
3173 inline auto operator=( const Other& v )
3174 -> EnableIf_t< !IsSparseElement_v<Other>, Element& >
3175 {
3176 this->value_ = v;
3177 return *this;
3178 }
3179
3180 template< typename Other >
3181 inline auto operator=( Other&& v )
3182 -> EnableIf_t< !IsSparseElement_v< RemoveReference_t<Other> > &&
3183 IsRValueReference_v<Other&&>, Element& >
3184 {
3185 this->value_ = std::move( v );
3186 return *this;
3187 }
3188 //*******************************************************************************************
3189
3190 //**Friend declarations**********************************************************************
3191 friend class CompressedMatrix;
3192 //*******************************************************************************************
3193 };
3194 //**********************************************************************************************
3195
3196 //**Private class Uninitialized*****************************************************************
3199 struct Uninitialized {};
3200 //**********************************************************************************************
3201
3202 public:
3203 //**Type definitions****************************************************************************
3204 using This = CompressedMatrix<Type,true,Tag>;
3205 using BaseType = SparseMatrix<This,true>;
3206 using ResultType = This;
3207
3209 using OppositeType = CompressedMatrix<Type,false,Tag>;
3210
3212 using TransposeType = CompressedMatrix<Type,false,Tag>;
3213
3214 using ElementType = Type;
3215 using TagType = Tag;
3216 using ReturnType = const Type&;
3217 using CompositeType = const This&;
3218 using Reference = MatrixAccessProxy<This>;
3219 using ConstReference = const Type&;
3220 using Iterator = Element*;
3221 using ConstIterator = const Element*;
3222 //**********************************************************************************************
3223
3224 //**Rebind struct definition********************************************************************
3227 template< typename NewType > // Data type of the other matrix
3228 struct Rebind {
3229 using Other = CompressedMatrix<NewType,true,Tag>;
3230 };
3231 //**********************************************************************************************
3232
3233 //**Resize struct definition********************************************************************
3236 template< size_t NewM // Number of rows of the other matrix
3237 , size_t NewN > // Number of columns of the other matrix
3238 struct Resize {
3239 using Other = CompressedMatrix<Type,true,Tag>;
3240 };
3241 //**********************************************************************************************
3242
3243 //**Compilation flags***************************************************************************
3245
3248 static constexpr bool smpAssignable = !IsSMPAssignable_v<Type>;
3249 //**********************************************************************************************
3250
3251 //**Constructors********************************************************************************
3254 inline CompressedMatrix();
3255 inline CompressedMatrix( size_t m, size_t n );
3256 inline CompressedMatrix( size_t m, size_t n, size_t nonzeros );
3257 CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros );
3259
3260 inline CompressedMatrix( const CompressedMatrix& sm );
3261 inline CompressedMatrix( CompressedMatrix&& sm ) noexcept;
3262
3263 template< typename MT, bool SO > inline CompressedMatrix( const DenseMatrix<MT,SO>& dm );
3264 template< typename MT, bool SO > inline CompressedMatrix( const SparseMatrix<MT,SO>& sm );
3266 //**********************************************************************************************
3267
3268 //**Destructor**********************************************************************************
3271 inline ~CompressedMatrix();
3273 //**********************************************************************************************
3274
3275 //**Data access functions***********************************************************************
3278 inline Reference operator()( size_t i, size_t j ) noexcept;
3279 inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3280 inline Reference at( size_t i, size_t j );
3281 inline ConstReference at( size_t i, size_t j ) const;
3282 inline Iterator begin ( size_t j ) noexcept;
3283 inline ConstIterator begin ( size_t j ) const noexcept;
3284 inline ConstIterator cbegin( size_t j ) const noexcept;
3285 inline Iterator end ( size_t j ) noexcept;
3286 inline ConstIterator end ( size_t j ) const noexcept;
3287 inline ConstIterator cend ( size_t j ) const noexcept;
3289 //**********************************************************************************************
3290
3291 //**Assignment operators************************************************************************
3295 inline CompressedMatrix& operator=( const CompressedMatrix& rhs ) &;
3296 inline CompressedMatrix& operator=( CompressedMatrix&& rhs ) & noexcept;
3297
3298 template< typename MT, bool SO > inline CompressedMatrix& operator= ( const DenseMatrix<MT,SO>& rhs ) &;
3299 template< typename MT, bool SO > inline CompressedMatrix& operator= ( const SparseMatrix<MT,SO>& rhs ) &;
3300 template< typename MT, bool SO > inline CompressedMatrix& operator+=( const Matrix<MT,SO>& rhs ) &;
3301 template< typename MT, bool SO > inline CompressedMatrix& operator-=( const Matrix<MT,SO>& rhs ) &;
3302 template< typename MT, bool SO > inline CompressedMatrix& operator%=( const DenseMatrix<MT,SO>& rhs ) &;
3303 template< typename MT, bool SO > inline CompressedMatrix& operator%=( const SparseMatrix<MT,SO>& rhs ) &;
3305 //**********************************************************************************************
3306
3307 //**Utility functions***************************************************************************
3310 inline size_t rows() const noexcept;
3311 inline size_t columns() const noexcept;
3312 inline size_t capacity() const noexcept;
3313 inline size_t capacity( size_t j ) const noexcept;
3314 inline size_t nonZeros() const;
3315 inline size_t nonZeros( size_t j ) const;
3316 inline void reset();
3317 inline void reset( size_t j );
3318 inline void clear();
3319 void resize ( size_t m, size_t n, bool preserve=true );
3320 inline void reserve( size_t nonzeros );
3321 void reserve( size_t j, size_t nonzeros );
3322 inline void trim ();
3323 inline void trim ( size_t j );
3324 inline void shrinkToFit();
3325 inline void swap( CompressedMatrix& sm ) noexcept;
3327 //**********************************************************************************************
3328
3329 //**Insertion functions*************************************************************************
3332 inline Iterator set ( size_t i, size_t j, const Type& value );
3333 inline Iterator insert ( size_t i, size_t j, const Type& value );
3334 inline void append ( size_t i, size_t j, const Type& value, bool check=false );
3335 inline void finalize( size_t j );
3337 //**********************************************************************************************
3338
3339 //**Erase functions*****************************************************************************
3342 inline void erase( size_t i, size_t j );
3343 inline Iterator erase( size_t j, Iterator pos );
3344 inline Iterator erase( size_t j, Iterator first, Iterator last );
3345
3346 template< typename Pred >
3347 inline void erase( Pred predicate );
3348
3349 template< typename Pred >
3350 inline void erase( size_t j, Iterator first, Iterator last, Pred predicate );
3352 //**********************************************************************************************
3353
3354 //**Lookup functions****************************************************************************
3357 inline Iterator find ( size_t i, size_t j );
3358 inline ConstIterator find ( size_t i, size_t j ) const;
3359 inline Iterator lowerBound( size_t i, size_t j );
3360 inline ConstIterator lowerBound( size_t i, size_t j ) const;
3361 inline Iterator upperBound( size_t i, size_t j );
3362 inline ConstIterator upperBound( size_t i, size_t j ) const;
3364 //**********************************************************************************************
3365
3366 //**Numeric functions***************************************************************************
3369 inline CompressedMatrix& transpose();
3370 inline CompressedMatrix& ctranspose();
3371
3372 template< typename Other > inline CompressedMatrix& scale( const Other& scalar );
3374 //**********************************************************************************************
3375
3376 //**Expression template evaluation functions****************************************************
3379 template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3380 template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3381
3382 inline bool canSMPAssign() const noexcept;
3383
3384 template< typename MT, bool SO > inline void assign ( const DenseMatrix<MT,SO>& rhs );
3385 template< typename MT > inline void assign ( const SparseMatrix<MT,true>& rhs );
3386 template< typename MT > inline void assign ( const SparseMatrix<MT,false>& rhs );
3387 template< typename MT, bool SO > inline void addAssign ( const DenseMatrix<MT,SO>& rhs );
3388 template< typename MT, bool SO > inline void addAssign ( const SparseMatrix<MT,SO>& rhs );
3389 template< typename MT, bool SO > inline void subAssign ( const DenseMatrix<MT,SO>& rhs );
3390 template< typename MT, bool SO > inline void subAssign ( const SparseMatrix<MT,SO>& rhs );
3391 template< typename MT, bool SO > inline void schurAssign( const DenseMatrix<MT,SO>& rhs );
3393 //**********************************************************************************************
3394
3395 private:
3396 //**Constructors********************************************************************************
3399 inline CompressedMatrix( size_t m, size_t n, Uninitialized );
3401 //**********************************************************************************************
3402
3403 //**Utility functions***************************************************************************
3406 inline size_t extendCapacity() const noexcept;
3407 void reserveElements( size_t nonzeros );
3408
3409 inline Iterator castDown( IteratorBase it ) const noexcept;
3410 inline IteratorBase castUp ( Iterator it ) const noexcept;
3412 //**********************************************************************************************
3413
3414 //**Insertion functions*************************************************************************
3417 Iterator insert( Iterator pos, size_t i, size_t j, const Type& value );
3419 //**********************************************************************************************
3420
3421 //**Member variables****************************************************************************
3424 size_t m_;
3425 size_t n_;
3426 size_t capacity_;
3427 Iterator* begin_;
3428 Iterator* end_;
3429
3430 static const Type zero_;
3432 //**********************************************************************************************
3433
3434 //**Compile time checks*************************************************************************
3440 //**********************************************************************************************
3441};
3443//*************************************************************************************************
3444
3445
3446
3447
3448//=================================================================================================
3449//
3450// DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
3451//
3452//=================================================================================================
3453
3454template< typename Type // Data type of the matrix
3455 , typename Tag > // Type tag
3456const Type CompressedMatrix<Type,true,Tag>::zero_{};
3457
3458
3459
3460
3461//=================================================================================================
3462//
3463// CONSTRUCTORS
3464//
3465//=================================================================================================
3466
3467//*************************************************************************************************
3471template< typename Type // Data type of the matrix
3472 , typename Tag > // Type tag
3474 : m_ ( 0UL ) // The current number of rows of the compressed matrix
3475 , n_ ( 0UL ) // The current number of columns of the compressed matrix
3476 , capacity_( 0UL ) // The current capacity of the pointer array
3477 , begin_ ( nullptr ) // Pointers to the first non-zero element of each column
3478 , end_ ( nullptr ) // Pointers one past the last non-zero element of each column
3479{}
3481//*************************************************************************************************
3482
3483
3484//*************************************************************************************************
3493template< typename Type // Data type of the matrix
3494 , typename Tag > // Type tag
3495inline CompressedMatrix<Type,true,Tag>::CompressedMatrix( size_t m, size_t n )
3496 : CompressedMatrix( m, n, Uninitialized() )
3497{
3498 for( size_t j=1UL; j<2UL*n_+2UL; ++j )
3499 begin_[j] = nullptr;
3500}
3502//*************************************************************************************************
3503
3504
3505//*************************************************************************************************
3515template< typename Type // Data type of the matrix
3516 , typename Tag > // Type tag
3517inline CompressedMatrix<Type,true,Tag>::CompressedMatrix( size_t m, size_t n, size_t nonzeros )
3518 : CompressedMatrix( m, n, Uninitialized() )
3519{
3520 begin_[0UL] = allocate<Element>( nonzeros );
3521 for( size_t j=1UL; j<(2UL*n_+1UL); ++j )
3522 begin_[j] = begin_[0UL];
3523 end_[n_] = begin_[0UL]+nonzeros;
3524}
3526//*************************************************************************************************
3527
3528
3529//*************************************************************************************************
3540template< typename Type // Data type of the matrix
3541 , typename Tag > // Type tag
3542CompressedMatrix<Type,true,Tag>::CompressedMatrix( size_t m, size_t n, const std::vector<size_t>& nonzeros )
3543 : CompressedMatrix( m, n, Uninitialized() )
3544{
3545 BLAZE_USER_ASSERT( nonzeros.size() == n, "Size of capacity vector and number of columns don't match" );
3546
3547 size_t newCapacity( 0UL );
3548 for( auto it=nonzeros.begin(); it!=nonzeros.end(); ++it )
3549 newCapacity += *it;
3550
3551 begin_[0UL] = end_[0UL] = allocate<Element>( newCapacity );
3552 for( size_t j=0UL; j<n_; ++j ) {
3553 begin_[j+1UL] = end_[j+1UL] = begin_[j] + nonzeros[j];
3554 }
3555}
3557//*************************************************************************************************
3558
3559
3560//*************************************************************************************************
3581template< typename Type // Data type of the matrix
3582 , typename Tag > // Type tag
3584 : CompressedMatrix( list.size(), determineColumns( list ), blaze::nonZeros( list ) )
3585{
3586 for( size_t j=0UL; j<n_; ++j )
3587 {
3588 size_t i( 0UL );
3589
3590 for( const auto& rowList : list )
3591 {
3592 if( rowList.size() <= j ) {
3593 ++i;
3594 continue;
3595 }
3596
3597 auto pos( rowList.begin() );
3598 std::advance( pos, j );
3599 if( !isDefault<strict>( *pos ) )
3600 append( i, j, *pos );
3601 ++i;
3602 }
3603
3604 finalize( j );
3605 }
3606}
3608//*************************************************************************************************
3609
3610
3611//*************************************************************************************************
3617template< typename Type // Data type of the matrix
3618 , typename Tag > // Type tag
3619inline CompressedMatrix<Type,true,Tag>::CompressedMatrix( const CompressedMatrix& sm )
3620 : CompressedMatrix( sm.m_, sm.n_, Uninitialized() )
3621{
3622 const size_t nonzeros( sm.nonZeros() );
3623
3624 begin_[0UL] = allocate<Element>( nonzeros );
3625 for( size_t j=0UL; j<n_; ++j ) {
3626 end_[j] = castDown( std::copy( sm.begin(j), sm.end(j), castUp( begin_[j] ) ) );
3627 begin_[j+1UL] = end_[j];
3628 }
3629 end_[n_] = begin_[0UL]+nonzeros;
3630}
3632//*************************************************************************************************
3633
3634
3635//*************************************************************************************************
3641template< typename Type // Data type of the matrix
3642 , typename Tag > // Type tag
3643inline CompressedMatrix<Type,true,Tag>::CompressedMatrix( CompressedMatrix&& sm ) noexcept
3644 : m_ ( sm.m_ ) // The current number of rows of the compressed matrix
3645 , n_ ( sm.n_ ) // The current number of columns of the compressed matrix
3646 , capacity_( sm.capacity_ ) // The current capacity of the pointer array
3647 , begin_ ( sm.begin_ ) // Pointers to the first non-zero element of each column
3648 , end_ ( sm.end_ ) // Pointers one past the last non-zero element of each column
3649{
3650 sm.m_ = 0UL;
3651 sm.n_ = 0UL;
3652 sm.capacity_ = 0UL;
3653 sm.begin_ = nullptr;
3654 sm.end_ = nullptr;
3655}
3657//*************************************************************************************************
3658
3659
3660//*************************************************************************************************
3666template< typename Type // Data type of the matrix
3667 , typename Tag > // Type tag
3668template< typename MT // Type of the foreign dense matrix
3669 , bool SO > // Storage order of the foreign dense matrix
3670inline CompressedMatrix<Type,true,Tag>::CompressedMatrix( const DenseMatrix<MT,SO>& dm )
3671 : CompressedMatrix( (*dm).rows(), (*dm).columns() )
3672{
3673 using blaze::assign;
3674
3675 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
3676
3677 assign( *this, *dm );
3678}
3680//*************************************************************************************************
3681
3682
3683//*************************************************************************************************
3689template< typename Type // Data type of the matrix
3690 , typename Tag > // Type tag
3691template< typename MT // Type of the foreign compressed matrix
3692 , bool SO > // Storage order of the foreign compressed matrix
3693inline CompressedMatrix<Type,true,Tag>::CompressedMatrix( const SparseMatrix<MT,SO>& sm )
3694 : CompressedMatrix( (*sm).rows(), (*sm).columns(), (*sm).nonZeros() )
3695{
3696 using blaze::assign;
3697
3698 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
3699
3700 assign( *this, *sm );
3701}
3703//*************************************************************************************************
3704
3705
3706//*************************************************************************************************
3713template< typename Type // Data type of the matrix
3714 , typename Tag > // Type tag
3715inline CompressedMatrix<Type,true,Tag>::CompressedMatrix( size_t m, size_t n, Uninitialized )
3716 : m_ ( m ) // The current number of rows of the compressed matrix
3717 , n_ ( n ) // The current number of columns of the compressed matrix
3718 , capacity_( n ) // The current capacity of the pointer array
3719 , begin_( new Iterator[2UL*n+2UL] ) // Pointers to the first non-zero element of each column
3720 , end_ ( begin_+(n+1UL) ) // Pointers one past the last non-zero element of each column
3721{
3722 begin_[0UL] = nullptr;
3723}
3725//*************************************************************************************************
3726
3727
3728
3729
3730//=================================================================================================
3731//
3732// DESTRUCTOR
3733//
3734//=================================================================================================
3735
3736//*************************************************************************************************
3740template< typename Type // Data type of the matrix
3741 , typename Tag > // Type tag
3743{
3744 if( begin_ != nullptr ) {
3745 deallocate( begin_[0UL] );
3746 delete[] begin_;
3747 }
3748}
3750//*************************************************************************************************
3751
3752
3753
3754
3755//=================================================================================================
3756//
3757// DATA ACCESS FUNCTIONS
3758//
3759//=================================================================================================
3760
3761//*************************************************************************************************
3775template< typename Type // Data type of the matrix
3776 , typename Tag > // Type tag
3778 CompressedMatrix<Type,true,Tag>::operator()( size_t i, size_t j ) noexcept
3779{
3780 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3781 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3782
3783 return Reference( *this, i, j );
3784}
3786//*************************************************************************************************
3787
3788
3789//*************************************************************************************************
3800template< typename Type // Data type of the matrix
3801 , typename Tag > // Type tag
3803 CompressedMatrix<Type,true,Tag>::operator()( size_t i, size_t j ) const noexcept
3804{
3805 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3806 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3807
3808 const ConstIterator pos( lowerBound( i, j ) );
3809
3810 if( pos == end_[j] || pos->index_ != i )
3811 return zero_;
3812 else
3813 return pos->value_;
3814}
3816//*************************************************************************************************
3817
3818
3819//*************************************************************************************************
3833template< typename Type // Data type of the matrix
3834 , typename Tag > // Type tag
3836 CompressedMatrix<Type,true,Tag>::at( size_t i, size_t j )
3837{
3838 if( i >= m_ ) {
3839 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3840 }
3841 if( j >= n_ ) {
3842 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3843 }
3844 return (*this)(i,j);
3845}
3847//*************************************************************************************************
3848
3849
3850//*************************************************************************************************
3862template< typename Type // Data type of the matrix
3863 , typename Tag > // Type tag
3865 CompressedMatrix<Type,true,Tag>::at( size_t i, size_t j ) const
3866{
3867 if( i >= m_ ) {
3868 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3869 }
3870 if( j >= n_ ) {
3871 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3872 }
3873 return (*this)(i,j);
3874}
3876//*************************************************************************************************
3877
3878
3879//*************************************************************************************************
3886template< typename Type // Data type of the matrix
3887 , typename Tag > // Type tag
3889 CompressedMatrix<Type,true,Tag>::begin( size_t j ) noexcept
3890{
3891 BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3892 return begin_[j];
3893}
3895//*************************************************************************************************
3896
3897
3898//*************************************************************************************************
3905template< typename Type // Data type of the matrix
3906 , typename Tag > // Type tag
3908 CompressedMatrix<Type,true,Tag>::begin( size_t j ) const noexcept
3909{
3910 BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3911 return begin_[j];
3912}
3914//*************************************************************************************************
3915
3916
3917//*************************************************************************************************
3924template< typename Type // Data type of the matrix
3925 , typename Tag > // Type tag
3927 CompressedMatrix<Type,true,Tag>::cbegin( size_t j ) const noexcept
3928{
3929 BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3930 return begin_[j];
3931}
3933//*************************************************************************************************
3934
3935
3936//*************************************************************************************************
3943template< typename Type // Data type of the matrix
3944 , typename Tag > // Type tag
3946 CompressedMatrix<Type,true,Tag>::end( size_t j ) noexcept
3947{
3948 BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3949 return end_[j];
3950}
3952//*************************************************************************************************
3953
3954
3955//*************************************************************************************************
3962template< typename Type // Data type of the matrix
3963 , typename Tag > // Type tag
3965 CompressedMatrix<Type,true,Tag>::end( size_t j ) const noexcept
3966{
3967 BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3968 return end_[j];
3969}
3971//*************************************************************************************************
3972
3973
3974//*************************************************************************************************
3981template< typename Type // Data type of the matrix
3982 , typename Tag > // Type tag
3984 CompressedMatrix<Type,true,Tag>::cend( size_t j ) const noexcept
3985{
3986 BLAZE_USER_ASSERT( j < n_, "Invalid compressed matrix column access index" );
3987 return end_[j];
3988}
3990//*************************************************************************************************
3991
3992
3993
3994
3995//=================================================================================================
3996//
3997// ASSIGNMENT OPERATORS
3998//
3999//=================================================================================================
4000
4001//*************************************************************************************************
4023template< typename Type // Data type of the matrix
4024 , typename Tag > // Type tag
4025inline CompressedMatrix<Type,true,Tag>&
4027{
4028 using blaze::nonZeros;
4029
4030 resize( list.size(), determineColumns( list ), false );
4031 reserve( nonZeros( list ) );
4032
4033 for( size_t j=0UL; j<n_; ++j )
4034 {
4035 size_t i( 0UL );
4036
4037 for( const auto& rowList : list )
4038 {
4039 if( rowList.size() <= j ) {
4040 ++i;
4041 continue;
4042 }
4043
4044 auto pos( rowList.begin() );
4045 std::advance( pos, j );
4046 if( !isDefault<strict>( *pos ) )
4047 append( i, j, *pos );
4048 ++i;
4049 }
4050
4051 finalize( j );
4052 }
4053
4054 return *this;
4055}
4057//*************************************************************************************************
4058
4059
4060//*************************************************************************************************
4070template< typename Type // Data type of the matrix
4071 , typename Tag > // Type tag
4072inline CompressedMatrix<Type,true,Tag>&
4073 CompressedMatrix<Type,true,Tag>::operator=( const CompressedMatrix& rhs ) &
4074{
4075 using std::swap;
4076
4077 if( &rhs == this ) return *this;
4078
4079 const size_t nonzeros( rhs.nonZeros() );
4080
4081 if( rhs.n_ > capacity_ || nonzeros > capacity() )
4082 {
4083 Iterator* newBegin( new Iterator[2UL*rhs.n_+2UL] );
4084 Iterator* newEnd ( newBegin+(rhs.n_+1UL) );
4085
4086 newBegin[0UL] = allocate<Element>( nonzeros );
4087 for( size_t j=0UL; j<rhs.n_; ++j ) {
4088 newEnd[j] = castDown( std::copy( rhs.begin_[j], rhs.end_[j], castUp( newBegin[j] ) ) );
4089 newBegin[j+1UL] = newEnd[j];
4090 }
4091 newEnd[rhs.n_] = newBegin[0UL]+nonzeros;
4092
4093 swap( begin_, newBegin );
4094 end_ = newEnd;
4095 capacity_ = rhs.n_;
4096
4097 if( newBegin != nullptr ) {
4098 deallocate( newBegin[0UL] );
4099 delete[] newBegin;
4100 }
4101 }
4102 else {
4103 for( size_t j=0UL; j<rhs.n_; ++j ) {
4104 end_[j] = castDown( std::copy( rhs.begin_[j], rhs.end_[j], castUp( begin_[j] ) ) );
4105 begin_[j+1UL] = end_[j];
4106 }
4107 }
4108
4109 m_ = rhs.m_;
4110 n_ = rhs.n_;
4111
4112 return *this;
4113}
4115//*************************************************************************************************
4116
4117
4118//*************************************************************************************************
4125template< typename Type // Data type of the matrix
4126 , typename Tag > // Type tag
4127inline CompressedMatrix<Type,true,Tag>&
4128 CompressedMatrix<Type,true,Tag>::operator=( CompressedMatrix&& rhs ) & noexcept
4129{
4130 if( begin_ != nullptr ) {
4131 deallocate( begin_[0UL] );
4132 delete[] begin_;
4133 }
4134
4135 m_ = rhs.m_;
4136 n_ = rhs.n_;
4137 capacity_ = rhs.capacity_;
4138 begin_ = rhs.begin_;
4139 end_ = rhs.end_;
4140
4141 rhs.m_ = 0UL;
4142 rhs.n_ = 0UL;
4143 rhs.capacity_ = 0UL;
4144 rhs.begin_ = nullptr;
4145 rhs.end_ = nullptr;
4146
4147 return *this;
4148}
4150//*************************************************************************************************
4151
4152
4153//*************************************************************************************************
4163template< typename Type // Data type of the matrix
4164 , typename Tag > // Type tag
4165template< typename MT // Type of the right-hand side dense matrix
4166 , bool SO > // Storage order of the right-hand side dense matrix
4167inline CompressedMatrix<Type,true,Tag>&
4168 CompressedMatrix<Type,true,Tag>::operator=( const DenseMatrix<MT,SO>& rhs ) &
4169{
4170 using blaze::assign;
4171
4172 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
4173
4174 if( (*rhs).canAlias( this ) ) {
4175 CompressedMatrix tmp( *rhs );
4176 swap( tmp );
4177 }
4178 else {
4179 resize( (*rhs).rows(), (*rhs).columns(), false );
4180 assign( *this, *rhs );
4181 }
4182
4183 return *this;
4184}
4186//*************************************************************************************************
4187
4188
4189//*************************************************************************************************
4199template< typename Type // Data type of the matrix
4200 , typename Tag > // Type tag
4201template< typename MT // Type of the right-hand side compressed matrix
4202 , bool SO > // Storage order of the right-hand side compressed matrix
4203inline CompressedMatrix<Type,true,Tag>&
4204 CompressedMatrix<Type,true,Tag>::operator=( const SparseMatrix<MT,SO>& rhs ) &
4205{
4206 using blaze::assign;
4207
4208 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
4209
4210 if( (*rhs).canAlias( this ) ||
4211 (*rhs).columns() > capacity_ ||
4212 (*rhs).nonZeros() > capacity() ) {
4213 CompressedMatrix tmp( *rhs );
4214 swap( tmp );
4215 }
4216 else {
4217 resize( (*rhs).rows(), (*rhs).columns(), false );
4218 reset();
4219
4220 if( !IsZero_v<MT> ) {
4221 assign( *this, *rhs );
4222 }
4223 }
4224
4225 return *this;
4226}
4228//*************************************************************************************************
4229
4230
4231//*************************************************************************************************
4242template< typename Type // Data type of the matrix
4243 , typename Tag > // Type tag
4244template< typename MT // Type of the right-hand side matrix
4245 , bool SO > // Storage order of the right-hand side matrix
4246inline CompressedMatrix<Type,true,Tag>&
4247 CompressedMatrix<Type,true,Tag>::operator+=( const Matrix<MT,SO>& rhs ) &
4248{
4249 using blaze::addAssign;
4250
4251 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
4252
4253 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
4254 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4255 }
4256
4257 if( !IsZero_v<MT> ) {
4258 addAssign( *this, *rhs );
4259 }
4260
4261 return *this;
4262}
4264//*************************************************************************************************
4265
4266
4267//*************************************************************************************************
4278template< typename Type // Data type of the matrix
4279 , typename Tag > // Type tag
4280template< typename MT // Type of the right-hand side matrix
4281 , bool SO > // Storage order of the right-hand side matrix
4282inline CompressedMatrix<Type,true,Tag>&
4283 CompressedMatrix<Type,true,Tag>::operator-=( const Matrix<MT,SO>& rhs ) &
4284{
4285 using blaze::subAssign;
4286
4287 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
4288
4289 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
4290 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4291 }
4292
4293 if( !IsZero_v<MT> ) {
4294 subAssign( *this, *rhs );
4295 }
4296
4297 return *this;
4298}
4300//*************************************************************************************************
4301
4302
4303//*************************************************************************************************
4315template< typename Type // Data type of the matrix
4316 , typename Tag > // Type tag
4317template< typename MT // Type of the right-hand side dense matrix
4318 , bool SO > // Storage order of the right-hand side dense matrix
4319inline CompressedMatrix<Type,true,Tag>&
4320 CompressedMatrix<Type,true,Tag>::operator%=( const DenseMatrix<MT,SO>& rhs ) &
4321{
4322 using blaze::schurAssign;
4323
4324 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
4325
4326 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
4327 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4328 }
4329
4330 if( (*rhs).canAlias( this ) ) {
4331 CompressedMatrix tmp( *this % (*rhs) );
4332 swap( tmp );
4333 }
4334 else {
4335 CompositeType_t<MT> tmp( *rhs );
4336 schurAssign( *this, tmp );
4337 }
4338
4339 return *this;
4340}
4342//*************************************************************************************************
4343
4344
4345//*************************************************************************************************
4357template< typename Type // Data type of the matrix
4358 , typename Tag > // Type tag
4359template< typename MT // Type of the right-hand side sparse matrix
4360 , bool SO > // Storage order of the right-hand side sparse matrix
4361inline CompressedMatrix<Type,true,Tag>&
4362 CompressedMatrix<Type,true,Tag>::operator%=( const SparseMatrix<MT,SO>& rhs ) &
4363{
4364 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
4365
4366 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
4367 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4368 }
4369
4370 if( !IsZero_v<MT> ) {
4371 CompressedMatrix tmp( *this % (*rhs) );
4372 swap( tmp );
4373 }
4374 else {
4375 reset();
4376 }
4377
4378 return *this;
4379}
4381//*************************************************************************************************
4382
4383
4384
4385
4386//=================================================================================================
4387//
4388// UTILITY FUNCTIONS
4389//
4390//=================================================================================================
4391
4392//*************************************************************************************************
4398template< typename Type // Data type of the matrix
4399 , typename Tag > // Type tag
4400inline size_t CompressedMatrix<Type,true,Tag>::rows() const noexcept
4401{
4402 return m_;
4403}
4405//*************************************************************************************************
4406
4407
4408//*************************************************************************************************
4414template< typename Type // Data type of the matrix
4415 , typename Tag > // Type tag
4416inline size_t CompressedMatrix<Type,true,Tag>::columns() const noexcept
4417{
4418 return n_;
4419}
4421//*************************************************************************************************
4422
4423
4424//*************************************************************************************************
4430template< typename Type // Data type of the matrix
4431 , typename Tag > // Type tag
4432inline size_t CompressedMatrix<Type,true,Tag>::capacity() const noexcept
4433{
4434 if( begin_ != nullptr )
4435 return end_[n_] - begin_[0UL];
4436 else return 0UL;
4437}
4439//*************************************************************************************************
4440
4441
4442//*************************************************************************************************
4449template< typename Type // Data type of the matrix
4450 , typename Tag > // Type tag
4451inline size_t CompressedMatrix<Type,true,Tag>::capacity( size_t j ) const noexcept
4452{
4453 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4454 return begin_[j+1UL] - begin_[j];
4455}
4457//*************************************************************************************************
4458
4459
4460//*************************************************************************************************
4466template< typename Type // Data type of the matrix
4467 , typename Tag > // Type tag
4469{
4470 size_t nonzeros( 0UL );
4471
4472 for( size_t j=0UL; j<n_; ++j )
4473 nonzeros += nonZeros( j );
4474
4475 return nonzeros;
4476}
4478//*************************************************************************************************
4479
4480
4481//*************************************************************************************************
4488template< typename Type // Data type of the matrix
4489 , typename Tag > // Type tag
4490inline size_t CompressedMatrix<Type,true,Tag>::nonZeros( size_t j ) const
4491{
4492 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4493 return end_[j] - begin_[j];
4494}
4496//*************************************************************************************************
4497
4498
4499//*************************************************************************************************
4505template< typename Type // Data type of the matrix
4506 , typename Tag > // Type tag
4508{
4509 for( size_t j=0UL; j<n_; ++j )
4510 end_[j] = begin_[j];
4511}
4513//*************************************************************************************************
4514
4515
4516//*************************************************************************************************
4526template< typename Type // Data type of the matrix
4527 , typename Tag > // Type tag
4528inline void CompressedMatrix<Type,true,Tag>::reset( size_t j )
4529{
4530 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4531 end_[j] = begin_[j];
4532}
4534//*************************************************************************************************
4535
4536
4537//*************************************************************************************************
4545template< typename Type // Data type of the matrix
4546 , typename Tag > // Type tag
4548{
4549 if( end_ != nullptr )
4550 end_[0UL] = end_[n_];
4551 m_ = 0UL;
4552 n_ = 0UL;
4553}
4555//*************************************************************************************************
4556
4557
4558//*************************************************************************************************
4574template< typename Type // Data type of the matrix
4575 , typename Tag > // Type tag
4576void CompressedMatrix<Type,true,Tag>::resize( size_t m, size_t n, bool preserve )
4577{
4578 using std::swap;
4579
4580 BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4581 BLAZE_INTERNAL_ASSERT( begin_ == nullptr || size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4582
4583 if( m == m_ && n == n_ ) return;
4584
4585 if( begin_ == nullptr )
4586 {
4587 begin_ = new Iterator[2UL*n+2UL];
4588 end_ = begin_+n+1UL;
4589
4590 for( size_t j=0UL; j<2UL*n+2UL; ++j ) {
4591 begin_[j] = nullptr;
4592 }
4593
4594 capacity_ = n;
4595 }
4596 else if( n > capacity_ )
4597 {
4598 Iterator* newBegin( new Iterator[2UL*n+2UL] );
4599 Iterator* newEnd ( newBegin+n+1UL );
4600
4601 newBegin[0UL] = begin_[0UL];
4602
4603 if( preserve ) {
4604 for( size_t j=0UL; j<n_; ++j ) {
4605 newEnd [j] = end_ [j];
4606 newBegin[j+1UL] = begin_[j+1UL];
4607 }
4608 for( size_t j=n_; j<n; ++j ) {
4609 newBegin[j+1UL] = newEnd[j] = begin_[n_];
4610 }
4611 }
4612 else {
4613 for( size_t j=0UL; j<n; ++j ) {
4614 newBegin[j+1UL] = newEnd[j] = begin_[0UL];
4615 }
4616 }
4617
4618 newEnd[n] = end_[n_];
4619
4620 swap( newBegin, begin_ );
4621 delete[] newBegin;
4622 end_ = newEnd;
4623 capacity_ = n;
4624 }
4625 else if( n > n_ )
4626 {
4627 end_[n] = end_[n_];
4628
4629 if( !preserve ) {
4630 for( size_t j=0UL; j<n_; ++j )
4631 end_[j] = begin_[j];
4632 }
4633
4634 for( size_t j=n_; j<n; ++j ) {
4635 begin_[j+1UL] = end_[j] = begin_[n_];
4636 }
4637 }
4638 else
4639 {
4640 if( preserve ) {
4641 for( size_t j=0UL; j<n; ++j )
4642 end_[j] = lowerBound( m, j );
4643 }
4644 else {
4645 for( size_t j=0UL; j<n; ++j )
4646 end_[j] = begin_[j];
4647 }
4648
4649 end_[n] = end_[n_];
4650 }
4651
4652 m_ = m;
4653 n_ = n;
4654
4655 BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4656 BLAZE_INTERNAL_ASSERT( size_t( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4657}
4659//*************************************************************************************************
4660
4661
4662//*************************************************************************************************
4673template< typename Type // Data type of the matrix
4674 , typename Tag > // Type tag
4675inline void CompressedMatrix<Type,true,Tag>::reserve( size_t nonzeros )
4676{
4677 if( nonzeros > capacity() )
4678 reserveElements( nonzeros );
4679}
4681//*************************************************************************************************
4682
4683
4684//*************************************************************************************************
4696template< typename Type // Data type of the matrix
4697 , typename Tag > // Type tag
4698void CompressedMatrix<Type,true,Tag>::reserve( size_t j, size_t nonzeros )
4699{
4700 using std::swap;
4701
4702 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4703
4704 BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4705 BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4706
4707 const size_t current( capacity(j) );
4708
4709 if( current >= nonzeros ) return;
4710
4711 const ptrdiff_t additional( nonzeros - current );
4712
4713 if( end_[n_] - begin_[n_] < additional )
4714 {
4715 const size_t newCapacity( begin_[n_] - begin_[0UL] + additional );
4716 BLAZE_INTERNAL_ASSERT( newCapacity > capacity(), "Invalid capacity value" );
4717
4718 Iterator* newBegin( new Iterator[2UL*n_+2UL] );
4719 Iterator* newEnd ( newBegin+n_+1UL );
4720
4721 newBegin[0UL] = allocate<Element>( newCapacity );
4722 newEnd [n_ ] = newBegin[0UL]+newCapacity;
4723
4724 for( size_t k=0UL; k<j; ++k ) {
4725 newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4726 newBegin[k+1UL] = newBegin[k] + capacity(k);
4727 }
4728 newEnd [j ] = castDown( transfer( begin_[j], end_[j], castUp( newBegin[j] ) ) );
4729 newBegin[j+1UL] = newBegin[j] + nonzeros;
4730 for( size_t k=j+1UL; k<n_; ++k ) {
4731 newEnd [k ] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4732 newBegin[k+1UL] = newBegin[k] + capacity(k);
4733 }
4734
4735 BLAZE_INTERNAL_ASSERT( newBegin[n_] == newEnd[n_], "Invalid pointer calculations" );
4736
4737 swap( newBegin, begin_ );
4738 deallocate( newBegin[0UL] );
4739 delete[] newBegin;
4740 end_ = newEnd;
4741 capacity_ = n_;
4742 }
4743 else
4744 {
4745 begin_[n_] += additional;
4746 for( size_t k=n_-1UL; k>j; --k ) {
4747 begin_[k] = castDown( std::move_backward( begin_[k], end_[k], castUp( end_[k]+additional ) ) );
4748 end_ [k] += additional;
4749 }
4750 }
4751
4752 BLAZE_INTERNAL_ASSERT( end_ >= begin_, "Invalid internal storage detected" );
4753 BLAZE_INTERNAL_ASSERT( static_cast<size_t>( end_ - begin_ ) == capacity_ + 1UL, "Invalid storage setting detected" );
4754}
4756//*************************************************************************************************
4757
4758
4759//*************************************************************************************************
4769template< typename Type // Data type of the matrix
4770 , typename Tag > // Type tag
4772{
4773 for( size_t j=0UL; j<n_; ++j )
4774 trim( j );
4775}
4777//*************************************************************************************************
4778
4779
4780//*************************************************************************************************
4791template< typename Type // Data type of the matrix
4792 , typename Tag > // Type tag
4794{
4795 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4796
4797 if( j < ( n_ - 1UL ) )
4798 end_[j+1] = castDown( std::move( begin_[j+1], end_[j+1], castUp( end_[j] ) ) );
4799 begin_[j+1] = end_[j];
4800}
4802//*************************************************************************************************
4803
4804
4805//*************************************************************************************************
4815template< typename Type // Data type of the matrix
4816 , typename Tag > // Type tag
4818{
4819 if( nonZeros() < capacity() ) {
4820 CompressedMatrix( *this ).swap( *this );
4821 }
4822}
4824//*************************************************************************************************
4825
4826
4827//*************************************************************************************************
4834template< typename Type // Data type of the matrix
4835 , typename Tag > // Type tag
4836inline void CompressedMatrix<Type,true,Tag>::swap( CompressedMatrix& sm ) noexcept
4837{
4838 using std::swap;
4839
4840 swap( m_, sm.m_ );
4841 swap( n_, sm.n_ );
4842 swap( capacity_, sm.capacity_ );
4843 swap( begin_, sm.begin_ );
4844 swap( end_ , sm.end_ );
4845}
4847//*************************************************************************************************
4848
4849
4850//*************************************************************************************************
4859template< typename Type // Data type of the matrix
4860 , typename Tag > // Type tag
4861inline size_t CompressedMatrix<Type,true,Tag>::extendCapacity() const noexcept
4862{
4863 size_t nonzeros( 2UL*capacity()+1UL );
4864 nonzeros = blaze::max( nonzeros, 7UL );
4865
4866 BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
4867
4868 return nonzeros;
4869}
4871//*************************************************************************************************
4872
4873
4874//*************************************************************************************************
4881template< typename Type // Data type of the matrix
4882 , typename Tag > // Type tag
4884{
4885 using std::swap;
4886
4887 Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
4888 Iterator* newEnd = newBegin+capacity_+1UL;
4889
4890 newBegin[0UL] = allocate<Element>( nonzeros );
4891
4892 for( size_t k=0UL; k<n_; ++k ) {
4893 BLAZE_INTERNAL_ASSERT( begin_[k] <= end_[k], "Invalid column pointers" );
4894 newEnd [k] = castDown( transfer( begin_[k], end_[k], castUp( newBegin[k] ) ) );
4895 newBegin[k+1UL] = newBegin[k] + ( begin_[k+1UL] - begin_[k] );
4896 }
4897
4898 newEnd[n_] = newBegin[0UL]+nonzeros;
4899
4900 swap( newBegin, begin_ );
4901 end_ = newEnd;
4902
4903 if( newBegin != nullptr ) {
4904 deallocate( newBegin[0UL] );
4905 delete[] newBegin;
4906 }
4907}
4909//*************************************************************************************************
4910
4911
4912//*************************************************************************************************
4920template< typename Type // Data type of the matrix
4921 , typename Tag > // Type tag
4923 CompressedMatrix<Type,true,Tag>::castDown( IteratorBase it ) const noexcept
4924{
4925 return static_cast<Iterator>( it );
4926}
4927//*************************************************************************************************
4928
4929
4930//*************************************************************************************************
4938template< typename Type // Data type of the matrix
4939 , typename Tag > // Type tag
4941 CompressedMatrix<Type,true,Tag>::castUp( Iterator it ) const noexcept
4942{
4943 return static_cast<IteratorBase>( it );
4944}
4945//*************************************************************************************************
4946
4947
4948
4949
4950//=================================================================================================
4951//
4952// INSERTION FUNCTIONS
4953//
4954//=================================================================================================
4955
4956//*************************************************************************************************
4969template< typename Type // Data type of the matrix
4970 , typename Tag > // Type tag
4972 CompressedMatrix<Type,true,Tag>::set( size_t i, size_t j, const Type& value )
4973{
4974 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4975 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4976
4977 const Iterator pos( lowerBound( i, j ) );
4978
4979 if( pos != end_[j] && pos->index_ == i ) {
4980 pos->value() = value;
4981 return pos;
4982 }
4983 else return insert( pos, i, j, value );
4984}
4986//*************************************************************************************************
4987
4988
4989//*************************************************************************************************
5003template< typename Type // Data type of the matrix
5004 , typename Tag > // Type tag
5006 CompressedMatrix<Type,true,Tag>::insert( size_t i, size_t j, const Type& value )
5007{
5008 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
5009 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5010
5011 const Iterator pos( lowerBound( i, j ) );
5012
5013 if( pos != end_[j] && pos->index_ == i ) {
5014 BLAZE_THROW_INVALID_ARGUMENT( "Bad access index" );
5015 }
5016
5017 return insert( pos, i, j, value );
5018}
5020//*************************************************************************************************
5021
5022
5023//*************************************************************************************************
5034template< typename Type // Data type of the matrix
5035 , typename Tag > // Type tag
5037 CompressedMatrix<Type,true,Tag>::insert( Iterator pos, size_t i, size_t j, const Type& value )
5038{
5039 using std::swap;
5040
5041 if( begin_[j+1UL] - end_[j] != 0 ) {
5042 std::move_backward( pos, end_[j], castUp( end_[j]+1UL ) );
5043 pos->value_ = value;
5044 pos->index_ = i;
5045 ++end_[j];
5046
5047 return pos;
5048 }
5049 else if( end_[n_] - begin_[n_] != 0 ) {
5050 std::move_backward( pos, end_[n_-1UL], castUp( end_[n_-1]+1UL ) );
5051
5052 pos->value_ = value;
5053 pos->index_ = i;
5054
5055 for( size_t k=j+1UL; k<n_+1UL; ++k ) {
5056 ++begin_[k];
5057 ++end_[k-1UL];
5058 }
5059
5060 return pos;
5061 }
5062 else {
5063 size_t newCapacity( extendCapacity() );
5064
5065 Iterator* newBegin = new Iterator[2UL*capacity_+2UL];
5066 Iterator* newEnd = newBegin+capacity_+1UL;
5067
5068 newBegin[0UL] = allocate<Element>( newCapacity );
5069
5070 for( size_t k=0UL; k<j; ++k ) {
5071 const size_t nonzeros( end_[k] - begin_[k] );
5072 const size_t total( begin_[k+1UL] - begin_[k] );
5073 newEnd [k] = newBegin[k] + nonzeros;
5074 newBegin[k+1UL] = newBegin[k] + total;
5075 }
5076 newEnd [j] = newBegin[j] + ( end_[j] - begin_[j] ) + 1;
5077 newBegin[j+1UL] = newBegin[j] + ( begin_[j+1UL] - begin_[j] ) + 1;
5078 for( size_t k=j+1UL; k<n_; ++k ) {
5079 const size_t nonzeros( end_[k] - begin_[k] );
5080 const size_t total( begin_[k+1UL] - begin_[k] );
5081 newEnd [k] = newBegin[k] + nonzeros;
5082 newBegin[k+1UL] = newBegin[k] + total;
5083 }
5084
5085 newEnd[n_] = newEnd[capacity_] = newBegin[0UL]+newCapacity;
5086
5087 Iterator tmp = castDown( std::move( begin_[0UL], pos, castUp( newBegin[0UL] ) ) );
5088 tmp->value_ = value;
5089 tmp->index_ = i;
5090 std::move( pos, end_[n_-1UL], castUp( tmp+1UL ) );
5091
5092 swap( newBegin, begin_ );
5093 end_ = newEnd;
5094 deallocate( newBegin[0UL] );
5095 delete[] newBegin;
5096
5097 return tmp;
5098 }
5099}
5101//*************************************************************************************************
5102
5103
5104//*************************************************************************************************
5157template< typename Type // Data type of the matrix
5158 , typename Tag > // Type tag
5159inline void CompressedMatrix<Type,true,Tag>::append( size_t i, size_t j, const Type& value, bool check )
5160{
5161 BLAZE_USER_ASSERT( i < m_, "Invalid row access index" );
5162 BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
5163 BLAZE_USER_ASSERT( end_[j] < end_[n_], "Not enough reserved capacity left" );
5164 BLAZE_USER_ASSERT( begin_[j] == end_[j] || i > ( end_[j]-1UL )->index_, "Index is not strictly increasing" );
5165
5166 end_[j]->value_ = value;
5167
5168 if( !check || !isDefault<strict>( end_[j]->value_ ) ) {
5169 end_[j]->index_ = i;
5170 ++end_[j];
5171 }
5172}
5174//*************************************************************************************************
5175
5176
5177//*************************************************************************************************
5191template< typename Type // Data type of the matrix
5192 , typename Tag > // Type tag
5193inline void CompressedMatrix<Type,true,Tag>::finalize( size_t j )
5194{
5195 BLAZE_USER_ASSERT( j < n_, "Invalid column access index" );
5196
5197 begin_[j+1UL] = end_[j];
5198 if( j != n_-1UL )
5199 end_[j+1UL] = end_[j];
5200}
5202//*************************************************************************************************
5203
5204
5205
5206
5207//=================================================================================================
5208//
5209// ERASE FUNCTIONS
5210//
5211//=================================================================================================
5212
5213//*************************************************************************************************
5223template< typename Type // Data type of the matrix
5224 , typename Tag > // Type tag
5225inline void CompressedMatrix<Type,true,Tag>::erase( size_t i, size_t j )
5226{
5227 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
5228 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5229
5230 const Iterator pos( find( i, j ) );
5231 if( pos != end_[j] )
5232 end_[j] = castDown( std::move( pos+1, end_[j], castUp( pos ) ) );
5233}
5235//*************************************************************************************************
5236
5237
5238//*************************************************************************************************
5248template< typename Type // Data type of the matrix
5249 , typename Tag > // Type tag
5251 CompressedMatrix<Type,true,Tag>::erase( size_t j, Iterator pos )
5252{
5253 BLAZE_USER_ASSERT( j < columns() , "Invalid column access index" );
5254 BLAZE_USER_ASSERT( pos >= begin_[j] && pos <= end_[j], "Invalid compressed matrix iterator" );
5255
5256 if( pos != end_[j] )
5257 end_[j] = castDown( std::move( pos+1, end_[j], castUp( pos ) ) );
5258
5259 return pos;
5260}
5262//*************************************************************************************************
5263
5264
5265//*************************************************************************************************
5276template< typename Type // Data type of the matrix
5277 , typename Tag > // Type tag
5279 CompressedMatrix<Type,true,Tag>::erase( size_t j, Iterator first, Iterator last )
5280{
5281 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5282 BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
5283 BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j], "Invalid compressed matrix iterator" );
5284 BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j], "Invalid compressed matrix iterator" );
5285
5286 if( first != last )
5287 end_[j] = castDown( std::move( last, end_[j], castUp( first ) ) );
5288
5289 return first;
5290}
5292//*************************************************************************************************
5293
5294
5295//*************************************************************************************************
5317template< typename Type // Data type of the matrix
5318 , typename Tag > // Type tag
5319template< typename Pred > // Type of the unary predicate
5320inline void CompressedMatrix<Type,true,Tag>::erase( Pred predicate )
5321{
5322 for( size_t j=0UL; j<n_; ++j ) {
5323 end_[j] = castDown( std::remove_if( castUp( begin_[j] ), castUp( end_[j] ),
5324 [predicate=predicate]( const ElementBase& element ) {
5325 return predicate( element.value() );
5326 } ) );
5327 }
5328}
5330//*************************************************************************************************
5331
5332
5333//*************************************************************************************************
5358template< typename Type // Data type of the matrix
5359 , typename Tag > // Type tag
5360template< typename Pred > // Type of the unary predicate
5361inline void CompressedMatrix<Type,true,Tag>::erase( size_t j, Iterator first, Iterator last, Pred predicate )
5362{
5363 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5364 BLAZE_USER_ASSERT( first <= last, "Invalid iterator range" );
5365 BLAZE_USER_ASSERT( first >= begin_[j] && first <= end_[j], "Invalid compressed matrix iterator" );
5366 BLAZE_USER_ASSERT( last >= begin_[j] && last <= end_[j], "Invalid compressed matrix iterator" );
5367
5368 const auto pos = std::remove_if( castUp( first ), castUp( last ),
5369 [predicate=predicate]( const ElementBase& element ) {
5370 return predicate( element.value() );
5371 } );
5372
5373 end_[j] = castDown( std::move( last, end_[j], pos ) );
5374}
5376//*************************************************************************************************
5377
5378
5379
5380
5381//=================================================================================================
5382//
5383// LOOKUP FUNCTIONS
5384//
5385//=================================================================================================
5386
5387//*************************************************************************************************
5402template< typename Type // Data type of the matrix
5403 , typename Tag > // Type tag
5405 CompressedMatrix<Type,true,Tag>::find( size_t i, size_t j )
5406{
5407 return const_cast<Iterator>( const_cast<const This&>( *this ).find( i, j ) );
5408}
5410//*************************************************************************************************
5411
5412
5413//*************************************************************************************************
5428template< typename Type // Data type of the matrix
5429 , typename Tag > // Type tag
5431 CompressedMatrix<Type,true,Tag>::find( size_t i, size_t j ) const
5432{
5433 const ConstIterator pos( lowerBound( i, j ) );
5434 if( pos != end_[j] && pos->index_ == i )
5435 return pos;
5436 else return end_[j];
5437}
5439//*************************************************************************************************
5440
5441
5442//*************************************************************************************************
5456template< typename Type // Data type of the matrix
5457 , typename Tag > // Type tag
5460{
5461 return const_cast<Iterator>( const_cast<const This&>( *this ).lowerBound( i, j ) );
5462}
5464//*************************************************************************************************
5465
5466
5467//*************************************************************************************************
5481template< typename Type // Data type of the matrix
5482 , typename Tag > // Type tag
5484 CompressedMatrix<Type,true,Tag>::lowerBound( size_t i, size_t j ) const
5485{
5486 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5487 return std::lower_bound( begin_[j], end_[j], i,
5488 []( const Element& element, size_t index )
5489 {
5490 return element.index() < index;
5491 } );
5492}
5494//*************************************************************************************************
5495
5496
5497//*************************************************************************************************
5511template< typename Type // Data type of the matrix
5512 , typename Tag > // Type tag
5515{
5516 return const_cast<Iterator>( const_cast<const This&>( *this ).upperBound( i, j ) );
5517}
5519//*************************************************************************************************
5520
5521
5522//*************************************************************************************************
5536template< typename Type // Data type of the matrix
5537 , typename Tag > // Type tag
5539 CompressedMatrix<Type,true,Tag>::upperBound( size_t i, size_t j ) const
5540{
5541 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5542 return std::upper_bound( begin_[j], end_[j], i,
5543 []( size_t index, const Element& element )
5544 {
5545 return index < element.index();
5546 } );
5547}
5549//*************************************************************************************************
5550
5551
5552
5553
5554//=================================================================================================
5555//
5556// NUMERIC FUNCTIONS
5557//
5558//=================================================================================================
5559
5560//*************************************************************************************************
5566template< typename Type // Data type of the matrix
5567 , typename Tag > // Type tag
5568inline CompressedMatrix<Type,true,Tag>& CompressedMatrix<Type,true,Tag>::transpose()
5569{
5570 CompressedMatrix tmp( trans( *this ) );
5571 swap( tmp );
5572 return *this;
5573}
5575//*************************************************************************************************
5576
5577
5578//*************************************************************************************************
5584template< typename Type // Data type of the matrix
5585 , typename Tag > // Type tag
5586inline CompressedMatrix<Type,true,Tag>& CompressedMatrix<Type,true,Tag>::ctranspose()
5587{
5588 CompressedMatrix tmp( ctrans( *this ) );
5589 swap( tmp );
5590 return *this;
5591}
5593//*************************************************************************************************
5594
5595
5596//*************************************************************************************************
5614template< typename Type // Data type of the matrix
5615 , typename Tag > // Type tag
5616template< typename Other > // Data type of the scalar value
5617inline CompressedMatrix<Type,true,Tag>& CompressedMatrix<Type,true,Tag>::scale( const Other& scalar )
5618{
5619 for( size_t j=0UL; j<n_; ++j )
5620 for( auto element=begin_[j]; element!=end_[j]; ++element )
5621 element->value_ *= scalar;
5622
5623 return *this;
5624}
5626//*************************************************************************************************
5627
5628
5629
5630
5631//=================================================================================================
5632//
5633// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5634//
5635//=================================================================================================
5636
5637//*************************************************************************************************
5648template< typename Type // Data type of the matrix
5649 , typename Tag > // Type tag
5650template< typename Other > // Data type of the foreign expression
5651inline bool CompressedMatrix<Type,true,Tag>::canAlias( const Other* alias ) const noexcept
5652{
5653 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5654}
5656//*************************************************************************************************
5657
5658
5659//*************************************************************************************************
5670template< typename Type // Data type of the matrix
5671 , typename Tag > // Type tag
5672template< typename Other > // Data type of the foreign expression
5673inline bool CompressedMatrix<Type,true,Tag>::isAliased( const Other* alias ) const noexcept
5674{
5675 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5676}
5678//*************************************************************************************************
5679
5680
5681//*************************************************************************************************
5692template< typename Type // Data type of the matrix
5693 , typename Tag > // Type tag
5694inline bool CompressedMatrix<Type,true,Tag>::canSMPAssign() const noexcept
5695{
5696 return false;
5697}
5699//*************************************************************************************************
5700
5701
5702//*************************************************************************************************
5714template< typename Type // Data type of the matrix
5715 , typename Tag > // Type tag
5716template< typename MT // Type of the right-hand side dense matrix
5717 , bool SO > // Storage order of the right-hand side dense matrix
5718inline void CompressedMatrix<Type,true,Tag>::assign( const DenseMatrix<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 if( m_ == 0UL || n_ == 0UL )
5724 return;
5725
5726 size_t nonzeros( 0UL );
5727
5728 for( size_t j=1UL; j<=n_; ++j )
5729 begin_[j] = end_[j] = end_[n_];
5730
5731 for( size_t j=0UL; j<n_; ++j )
5732 {
5733 begin_[j] = end_[j] = begin_[0UL]+nonzeros;
5734
5735 const size_t ibegin( ( IsLower_v<MT> )
5736 ?( IsStrictlyLower_v<MT> ? j+1UL : j )
5737 :( 0UL ) );
5738 const size_t iend ( ( IsUpper_v<MT> )
5739 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
5740 :( m_ ) );
5741
5742 for( size_t i=ibegin; i<iend; ++i )
5743 {
5744 if( nonzeros == capacity() ) {
5745 reserveElements( extendCapacity() );
5746 for( size_t k=j+1UL; k<=n_; ++k )
5747 begin_[k] = end_[k] = end_[n_];
5748 }
5749
5750 end_[j]->value_ = (*rhs)(i,j);
5751
5752 if( !isDefault<strict>( end_[j]->value_ ) ) {
5753 end_[j]->index_ = i;
5754 ++end_[j];
5755 ++nonzeros;
5756 }
5757 }
5758 }
5759
5760 begin_[n_] = begin_[0UL]+nonzeros;
5761}
5763//*************************************************************************************************
5764
5765
5766//*************************************************************************************************
5778template< typename Type // Data type of the matrix
5779 , typename Tag > // Type tag
5780template< typename MT > // Type of the right-hand side compressed matrix
5781inline void CompressedMatrix<Type,true,Tag>::assign( const SparseMatrix<MT,true>& rhs )
5782{
5783 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
5784 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
5785 BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
5786 BLAZE_INTERNAL_ASSERT( capacity() >= (*rhs).nonZeros(), "Invalid capacity detected" );
5787
5788 if( n_ == 0UL || begin_[0] == nullptr )
5789 return;
5790
5791 for( size_t j=0UL; j<n_; ++j ) {
5792 end_[j] = castDown( std::copy( (*rhs).begin(j), (*rhs).end(j), castUp( begin_[j] ) ) );
5793 begin_[j+1UL] = end_[j];
5794 }
5795}
5797//*************************************************************************************************
5798
5799
5800//*************************************************************************************************
5812template< typename Type // Data type of the matrix
5813 , typename Tag > // Type tag
5814template< typename MT > // Type of the right-hand side compressed matrix
5815inline void CompressedMatrix<Type,true,Tag>::assign( const SparseMatrix<MT,false>& rhs )
5816{
5818
5819 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
5820 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
5821 BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
5822 BLAZE_INTERNAL_ASSERT( capacity() >= (*rhs).nonZeros(), "Invalid capacity detected" );
5823
5824 // Counting the number of elements per column
5825 std::vector<size_t> columnLengths( n_, 0UL );
5826 for( size_t i=0UL; i<m_; ++i ) {
5827 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
5828 ++columnLengths[element->index()];
5829 }
5830
5831 // Resizing the compressed matrix
5832 for( size_t j=0UL; j<n_; ++j ) {
5833 begin_[j+1UL] = end_[j+1UL] = begin_[j] + columnLengths[j];
5834 }
5835
5836 // Appending the elements to the columns of the compressed matrix
5837 for( size_t i=0UL; i<m_; ++i ) {
5838 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
5839 append( i, element->index(), element->value() );
5840 }
5841}
5843//*************************************************************************************************
5844
5845
5846//*************************************************************************************************
5858template< typename Type // Data type of the matrix
5859 , typename Tag > // Type tag
5860template< typename MT // Type of the right-hand side dense matrix
5861 , bool SO > // Storage order of the right-hand side dense matrix
5862inline void CompressedMatrix<Type,true,Tag>::addAssign( const DenseMatrix<MT,SO>& rhs )
5863{
5864 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
5865 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
5866
5867 CompressedMatrix tmp( serial( *this + (*rhs) ) );
5868 swap( tmp );
5869}
5871//*************************************************************************************************
5872
5873
5874//*************************************************************************************************
5886template< typename Type // Data type of the matrix
5887 , typename Tag > // Type tag
5888template< typename MT // Type of the right-hand side compressed matrix
5889 , bool SO > // Storage order of the right-hand side compressed matrix
5890inline void CompressedMatrix<Type,true,Tag>::addAssign( const SparseMatrix<MT,SO>& rhs )
5891{
5892 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
5893 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
5894
5895 CompressedMatrix tmp( serial( *this + (*rhs) ) );
5896 swap( tmp );
5897}
5899//*************************************************************************************************
5900
5901
5902//*************************************************************************************************
5914template< typename Type // Data type of the matrix
5915 , typename Tag > // Type tag
5916template< typename MT // Type of the right-hand side dense matrix
5917 , bool SO > // Storage order of the right-hand side dense matrix
5918inline void CompressedMatrix<Type,true,Tag>::subAssign( const DenseMatrix<MT,SO>& rhs )
5919{
5920 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
5921 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
5922
5923 CompressedMatrix tmp( serial( *this - (*rhs) ) );
5924 swap( tmp );
5925}
5927//*************************************************************************************************
5928
5929
5930//*************************************************************************************************
5942template< typename Type // Data type of the matrix
5943 , typename Tag > // Type tag
5944template< typename MT // Type of the right-hand side compressed matrix
5945 , bool SO > // Storage order of the right-hand side compressed matrix
5946inline void CompressedMatrix<Type,true,Tag>::subAssign( const SparseMatrix<MT,SO>& rhs )
5947{
5948 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
5949 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
5950
5951 CompressedMatrix tmp( serial( *this - (*rhs) ) );
5952 swap( tmp );
5953}
5955//*************************************************************************************************
5956
5957
5958//*************************************************************************************************
5970template< typename Type // Data type of the matrix
5971 , typename Tag > // Type tag
5972template< typename MT // Type of the right-hand side dense matrix
5973 , bool SO > // Storage order of the right-hand side dense matrix
5974inline void CompressedMatrix<Type,true,Tag>::schurAssign( const DenseMatrix<MT,SO>& rhs )
5975{
5976 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
5977 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
5978
5980
5981 for( size_t j=0UL; j<n_; ++j ) {
5982 const Iterator last( end(j) );
5983 for( auto element=begin(j); element!=last; ++element )
5984 element->value_ *= (*rhs)(element->index_,j);
5985 }
5986}
5988//*************************************************************************************************
5989
5990
5991
5992
5993
5994
5995
5996
5997//=================================================================================================
5998//
5999// COMPRESSEDMATRIX OPERATORS
6000//
6001//=================================================================================================
6002
6003//*************************************************************************************************
6006template< RelaxationFlag RF, typename Type, bool SO, typename Tag >
6007bool isDefault( const CompressedMatrix<Type,SO,Tag>& m );
6008
6009template< typename Type, bool SO, typename Tag >
6010bool isIntact( const CompressedMatrix<Type,SO,Tag>& m );
6011
6012template< typename Type, bool SO, typename Tag >
6013void swap( CompressedMatrix<Type,SO,Tag>& a, CompressedMatrix<Type,SO,Tag>& b ) noexcept;
6015//*************************************************************************************************
6016
6017
6018//*************************************************************************************************
6043template< RelaxationFlag RF // Relaxation flag
6044 , typename Type // Data type of the matrix
6045 , bool SO // Storage order
6046 , typename Tag > // Type tag
6048{
6049 return ( m.rows() == 0UL && m.columns() == 0UL );
6050}
6051//*************************************************************************************************
6052
6053
6054//*************************************************************************************************
6072template< typename Type // Data type of the matrix
6073 , bool SO // Storage order
6074 , typename Tag > // Type tag
6076{
6077 return ( m.nonZeros() <= m.capacity() );
6078}
6079//*************************************************************************************************
6080
6081
6082//*************************************************************************************************
6090template< typename Type // Data type of the matrix
6091 , bool SO // Storage order
6092 , typename Tag > // Type tag
6094{
6095 a.swap( b );
6096}
6097//*************************************************************************************************
6098
6099
6100
6101
6102//=================================================================================================
6103//
6104// ADDTRAIT SPECIALIZATIONS
6105//
6106//=================================================================================================
6107
6108//*************************************************************************************************
6110template< typename T1, typename T2 >
6111struct AddTraitEval2< T1, T2
6112 , EnableIf_t< IsSparseMatrix_v<T1> && IsSparseMatrix_v<T2> > >
6113{
6114 using Type = CompressedMatrix< AddTrait_t< ElementType_t<T1>, ElementType_t<T2> >
6115 , ( StorageOrder_v<T1> && StorageOrder_v<T2> )
6116 , AddTrait_t< TagType_t<T1>, TagType_t<T2> > >;
6117};
6119//*************************************************************************************************
6120
6121
6122
6123
6124//=================================================================================================
6125//
6126// SUBTRAIT SPECIALIZATIONS
6127//
6128//=================================================================================================
6129
6130//*************************************************************************************************
6132template< typename T1, typename T2 >
6133struct SubTraitEval2< T1, T2
6134 , EnableIf_t< IsSparseMatrix_v<T1> && IsSparseMatrix_v<T2> > >
6135{
6136 using Type = CompressedMatrix< SubTrait_t< ElementType_t<T1>, ElementType_t<T2> >
6137 , ( StorageOrder_v<T1> && StorageOrder_v<T2> )
6138 , SubTrait_t< TagType_t<T1>, TagType_t<T2> > >;
6139};
6141//*************************************************************************************************
6142
6143
6144
6145
6146//=================================================================================================
6147//
6148// SCHURTRAIT SPECIALIZATIONS
6149//
6150//=================================================================================================
6151
6152//*************************************************************************************************
6154template< typename T1 // Type of the left-hand side operand
6155 , typename T2 > // Type of the right-hand side operand
6156struct SchurTraitEval2< T1, T2
6157 , EnableIf_t< IsMatrix_v<T1> &&
6158 IsMatrix_v<T2> &&
6159 ( IsSparseMatrix_v<T1> || IsSparseMatrix_v<T2> ) > >
6160{
6161 static constexpr bool SO = ( IsSparseMatrix_v<T1> && IsSparseMatrix_v<T2>
6162 ? ( StorageOrder_v<T1> && StorageOrder_v<T2> )
6163 : ( IsSparseMatrix_v<T1>
6164 ? StorageOrder_v<T1>
6165 : StorageOrder_v<T2> ) );
6166
6167 using Type = CompressedMatrix< MultTrait_t< ElementType_t<T1>, ElementType_t<T2> >
6168 , SO
6169 , MultTrait_t< TagType_t<T1>, TagType_t<T2> > >;
6170};
6172//*************************************************************************************************
6173
6174
6175
6176
6177//=================================================================================================
6178//
6179// MULTTRAIT SPECIALIZATIONS
6180//
6181//=================================================================================================
6182
6183//*************************************************************************************************
6185template< typename T1, typename T2 >
6186struct MultTraitEval2< T1, T2
6187 , EnableIf_t< IsSparseMatrix_v<T1> && IsScalar_v<T2> > >
6188{
6189 using Type = CompressedMatrix< MultTrait_t< ElementType_t<T1>, T2 >
6190 , StorageOrder_v<T1>
6191 , MultTrait_t< TagType_t<T1>, T2 > >;
6192};
6193
6194template< typename T1, typename T2 >
6195struct MultTraitEval2< T1, T2
6196 , EnableIf_t< IsScalar_v<T1> && IsSparseMatrix_v<T2> > >
6197{
6198 using Type = CompressedMatrix< MultTrait_t< T1, ElementType_t<T2> >
6199 , StorageOrder_v<T2>
6200 , MultTrait_t< T1, TagType_t<T2> > >;
6201};
6202
6203template< typename T1, typename T2 >
6204struct MultTraitEval2< T1, T2
6205 , EnableIf_t< ( IsSparseVector_v<T1> ||
6206 IsSparseVector_v<T2> ) &&
6207 IsColumnVector_v<T1> &&
6208 IsRowVector_v<T2> > >
6209{
6210 using Type = CompressedMatrix< MultTrait_t< ElementType_t<T1>, ElementType_t<T2> >
6211 , ( IsSparseVector_v<T2> ? rowMajor : columnMajor )
6212 , MultTrait_t< TagType_t<T1>, TagType_t<T2> > >;
6213};
6214
6215template< typename T1, typename T2 >
6216struct MultTraitEval2< T1, T2
6218 IsSparseMatrix_v<T2> &&
6219 !( IsIdentity_v<T1> && IsIdentity_v<T2> ) > >
6220{
6221 using MultType = MultTrait_t< ElementType_t<T1>, ElementType_t<T2> >;
6222 using MultTag = MultTrait_t< TagType_t<T1>, TagType_t<T2> >;
6223
6224 using Type = CompressedMatrix< AddTrait_t<MultType,MultType>
6225 , StorageOrder_v<T1>
6226 , AddTrait_t<MultTag,MultTag> >;
6227};
6229//*************************************************************************************************
6230
6231
6232
6233
6234//=================================================================================================
6235//
6236// KRONTRAIT SPECIALIZATIONS
6237//
6238//=================================================================================================
6239
6240//*************************************************************************************************
6242template< typename T1 // Type of the left-hand side operand
6243 , typename T2 > // Type of the right-hand side operand
6244struct KronTraitEval2< T1, T2
6245 , EnableIf_t< IsMatrix_v<T1> &&
6246 IsMatrix_v<T2> &&
6247 ( IsSparseMatrix_v<T1> || IsSparseMatrix_v<T2> ) > >
6248{
6249 using Type = CompressedMatrix< MultTrait_t< ElementType_t<T1>, ElementType_t<T2> >
6250 , ( IsDenseMatrix_v<T2> ? StorageOrder_v<T1> : StorageOrder_v<T2> )
6251 , MultTrait_t< TagType_t<T1>, TagType_t<T2> > >;
6252};
6254//*************************************************************************************************
6255
6256
6257
6258
6259//=================================================================================================
6260//
6261// DIVTRAIT SPECIALIZATIONS
6262//
6263//=================================================================================================
6264
6265//*************************************************************************************************
6267template< typename T1, typename T2 >
6268struct DivTraitEval2< T1, T2
6269 , EnableIf_t< IsSparseMatrix_v<T1> && IsScalar_v<T2> > >
6270{
6271 using Type = CompressedMatrix< DivTrait_t< ElementType_t<T1>, T2 >
6272 , StorageOrder_v<T1>
6273 , DivTrait_t< TagType_t<T1>, T2 > >;
6274};
6276//*************************************************************************************************
6277
6278
6279
6280
6281//=================================================================================================
6282//
6283// MAPTRAIT SPECIALIZATIONS
6284//
6285//=================================================================================================
6286
6287//*************************************************************************************************
6289template< typename T, typename OP >
6290struct UnaryMapTraitEval2< T, OP
6292{
6293 using ElementType = decltype( std::declval<OP>()( std::declval< ElementType_t<T> >() ) );
6294
6295 using Type = CompressedMatrix< EvaluateTrait_t<ElementType>
6296 , StorageOrder_v<T>
6297 , MapTrait_t< TagType_t<T>, OP > >;
6298};
6300//*************************************************************************************************
6301
6302
6303
6304
6305//=================================================================================================
6306//
6307// EXPANDTRAIT SPECIALIZATIONS
6308//
6309//=================================================================================================
6310
6311//*************************************************************************************************
6313template< typename T // Type to be expanded
6314 , size_t E > // Compile time expansion
6315struct ExpandTraitEval2< T, E
6317{
6318 using Type = CompressedMatrix< ElementType_t<T>
6319 , ( IsColumnVector_v<T> ? columnMajor : rowMajor )
6320 , TagType_t<T> >;
6321};
6323//*************************************************************************************************
6324
6325
6326
6327
6328//=================================================================================================
6329//
6330// REPEATTRAIT SPECIALIZATIONS
6331//
6332//=================================================================================================
6333
6334//*************************************************************************************************
6336template< typename T, size_t R0, size_t R1 >
6337struct RepeatTraitEval2< T, R0, R1, inf
6339{
6340 using Type = CompressedMatrix< ElementType_t<T>
6341 , StorageOrder_v<T>
6342 , TagType_t<T> >;
6343};
6345//*************************************************************************************************
6346
6347
6348
6349
6350//=================================================================================================
6351//
6352// HIGHTYPE SPECIALIZATIONS
6353//
6354//=================================================================================================
6355
6356//*************************************************************************************************
6358template< typename T1, bool SO, typename Tag, typename T2 >
6359struct HighType< CompressedMatrix<T1,SO,Tag>, CompressedMatrix<T2,SO,Tag> >
6360{
6361 using Type = CompressedMatrix< typename HighType<T1,T2>::Type, SO, Tag >;
6362};
6364//*************************************************************************************************
6365
6366
6367
6368
6369//=================================================================================================
6370//
6371// LOWTYPE SPECIALIZATIONS
6372//
6373//=================================================================================================
6374
6375//*************************************************************************************************
6377template< typename T1, bool SO, typename Tag, typename T2 >
6378struct LowType< CompressedMatrix<T1,SO,Tag>, CompressedMatrix<T2,SO,Tag> >
6379{
6380 using Type = CompressedMatrix< typename LowType<T1,T2>::Type, SO, Tag >;
6381};
6383//*************************************************************************************************
6384
6385
6386
6387
6388//=================================================================================================
6389//
6390// SUBMATRIXTRAIT SPECIALIZATIONS
6391//
6392//=================================================================================================
6393
6394//*************************************************************************************************
6396template< typename MT, size_t I, size_t J, size_t M, size_t N >
6397struct SubmatrixTraitEval2< MT, I, J, M, N
6398 , EnableIf_t< IsSparseMatrix_v<MT> > >
6399{
6400 using Type = CompressedMatrix< RemoveConst_t< ElementType_t<MT> >
6401 , StorageOrder_v<MT>
6402 , TagType_t<MT> >;
6403};
6405//*************************************************************************************************
6406
6407
6408
6409
6410//=================================================================================================
6411//
6412// ROWSTRAIT SPECIALIZATIONS
6413//
6414//=================================================================================================
6415
6416//*************************************************************************************************
6418template< typename MT, size_t M >
6419struct RowsTraitEval2< MT, M
6420 , EnableIf_t< IsSparseMatrix_v<MT> > >
6421{
6422 using Type = CompressedMatrix< RemoveConst_t< ElementType_t<MT> >
6423 , false
6424 , TagType_t<MT> >;
6425};
6427//*************************************************************************************************
6428
6429
6430
6431
6432//=================================================================================================
6433//
6434// COLUMNSTRAIT SPECIALIZATIONS
6435//
6436//=================================================================================================
6437
6438//*************************************************************************************************
6440template< typename MT, size_t N >
6441struct ColumnsTraitEval2< MT, N
6442 , EnableIf_t< IsSparseMatrix_v<MT> > >
6443{
6444 using Type = CompressedMatrix< RemoveConst_t< ElementType_t<MT> >
6445 , true
6446 , TagType_t<MT> >;
6447};
6449//*************************************************************************************************
6450
6451} // namespace blaze
6452
6453#endif
Header file for the addition trait.
Header file for auxiliary alias declarations.
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.
Definition: Aliases.h:110
typename ResultType_t< T >::TagType TagType_t
Alias declaration for nested TagType type definitions.
Definition: Aliases.h:530
Header file for run time assertion macros.
Header file for the columns trait.
Constraint on the data type.
Header file for the division trait.
Header file for the EnableIf class template.
Header file for the EvaluateTrait class template.
Header file for the expand trait.
Header file for the HighType type trait.
Header file for the IntegralConstant class template.
Header file for the IsColumnVector type trait.
Header file for the isDefault shim.
Header file for the IsDenseMatrix type trait.
Header file for the IsFloatingPoint type trait.
Header file for the IsIdentity type trait.
Header file for the IsLower type trait.
Header file for the IsMatrix type trait.
Header file for the IsRowVector type trait.
Header file for the IsSMPAssignable type trait.
Header file for the IsScalar type trait.
Header file for the IsSparseMatrix type trait.
Header file for the IsSparseVector type trait.
Header file for the IsStrictlyLower type trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsUpper type trait.
Header file for the Kron product trait.
Header file for the LowType type trait.
Header file for the map trait.
Header file for the MatrixAccessProxy class.
Header file for memory allocation and deallocation functionality.
Header file for the multiplication trait.
Constraint on the data type.
Constraint on the data type.
Header file for the relaxation flag enumeration.
Header file for the RemoveConst type trait.
Header file for the repeat trait.
Header file for the rows trait.
Constraint on the size of two data types.
Data type constraint.
Header file for the Schur product trait.
Header file for the subtraction trait.
Header file for the submatrix trait.
Constraint on the data type.
Header file for the generic transfer algorithm.
Header file for the ValueIndexPair class.
Constraint on the data type.
Efficient implementation of a compressed matrix.
Definition: CompressedMatrix.h:239
size_t m_
The current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:547
Iterator * end_
Pointers one past the last non-zero element of each row.
Definition: CompressedMatrix.h:551
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: CompressedMatrix.h:2767
size_t capacity() const noexcept
Returns the maximum capacity of the compressed matrix.
Definition: CompressedMatrix.h:1546
void subAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the subtraction assignment of a dense matrix.
Definition: CompressedMatrix.h:3026
CompressedMatrix< Type,!SO, Tag > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:332
Iterator upperBound(size_t i, size_t j)
Returns an iterator to the first index greater than the given index.
Definition: CompressedMatrix.h:2633
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:329
CompressedMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: CompressedMatrix.h:2704
size_t n_
The current number of columns of the compressed matrix.
Definition: CompressedMatrix.h:548
SparseMatrix< This, SO > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:328
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:340
void erase(size_t i, size_t j)
Erasing an element from the compressed matrix.
Definition: CompressedMatrix.h:2338
size_t rows() const noexcept
Returns the current number of rows of the compressed matrix.
Definition: CompressedMatrix.h:1516
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the compressed matrix.
Definition: CompressedMatrix.h:1695
CompressedMatrix & transpose()
In-place transpose of the matrix.
Definition: CompressedMatrix.h:2687
bool canSMPAssign() const noexcept
Returns whether the matrix can be used in SMP assignments.
Definition: CompressedMatrix.h:2808
MatrixAccessProxy< This > Reference
Reference to a compressed matrix value.
Definition: CompressedMatrix.h:341
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:2274
void clear()
Clearing the compressed matrix.
Definition: CompressedMatrix.h:1667
Iterator begin(size_t i) noexcept
Returns an iterator to the first non-zero element of row/column i.
Definition: CompressedMatrix.h:1000
Iterator castDown(IteratorBase it) const noexcept
Performs a down-cast of the given iterator.
Definition: CompressedMatrix.h:2039
Iterator set(size_t i, size_t j, const Type &value)
Setting an element of the compressed matrix.
Definition: CompressedMatrix.h:2089
static const Type zero_
Neutral element for accesses to zero elements.
Definition: CompressedMatrix.h:553
void shrinkToFit()
Requesting the removal of unused capacity.
Definition: CompressedMatrix.h:1936
Reference operator()(size_t i, size_t j) noexcept
2D-access to the compressed matrix elements.
Definition: CompressedMatrix.h:888
Iterator lowerBound(size_t i, size_t j)
Returns an iterator to the first index not less than the given index.
Definition: CompressedMatrix.h:2576
void addAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the addition assignment of a dense matrix.
Definition: CompressedMatrix.h:2972
CompressedMatrix< Type,!SO, Tag > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:335
size_t nonZeros() const
Returns the number of non-zero elements in the compressed matrix.
Definition: CompressedMatrix.h:1585
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: CompressedMatrix.h:2788
ValueIndexPair< Type > ElementBase
Base class for the compressed matrix element.
Definition: CompressedMatrix.h:242
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:344
ElementBase * IteratorBase
Iterator over non-constant base elements.
Definition: CompressedMatrix.h:243
void reserve(size_t nonzeros)
Setting the minimum capacity of the compressed matrix.
Definition: CompressedMatrix.h:1793
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first non-zero element of row/column i.
Definition: CompressedMatrix.h:1046
void reserveElements(size_t nonzeros)
Reserving the specified number of compressed matrix elements.
Definition: CompressedMatrix.h:1999
size_t columns() const noexcept
Returns the current number of columns of the compressed matrix.
Definition: CompressedMatrix.h:1531
Tag TagType
Tag type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:338
size_t extendCapacity() const noexcept
Calculating a new matrix capacity.
Definition: CompressedMatrix.h:1978
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: CompressedMatrix.h:371
void swap(CompressedMatrix &sm) noexcept
Swapping the contents of two sparse matrices.
Definition: CompressedMatrix.h:1954
~CompressedMatrix()
The destructor for CompressedMatrix.
Definition: CompressedMatrix.h:853
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:343
Iterator end(size_t i) noexcept
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:1069
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:339
void reset()
Reset to the default initial values.
Definition: CompressedMatrix.h:1627
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: CompressedMatrix.h:944
const Type & ConstReference
Reference to a constant compressed matrix value.
Definition: CompressedMatrix.h:342
void trim()
Removing all excessive capacity from all rows/columns.
Definition: CompressedMatrix.h:1891
void assign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the assignment of a row-major dense matrix.
Definition: CompressedMatrix.h:2831
Iterator * begin_
Pointers to the first non-zero element of each row.
Definition: CompressedMatrix.h:550
CompressedMatrix & operator=(initializer_list< initializer_list< Type > > list) &
List assignment to all matrix elements.
Definition: CompressedMatrix.h:1156
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:549
Iterator insert(size_t i, size_t j, const Type &value)
Inserting an element into the compressed matrix.
Definition: CompressedMatrix.h:2122
IteratorBase castUp(Iterator it) const noexcept
Performs an up-cast of the given iterator.
Definition: CompressedMatrix.h:2058
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last non-zero element of row/column i.
Definition: CompressedMatrix.h:1115
void finalize(size_t i)
Finalizing the element insertion of a row/column.
Definition: CompressedMatrix.h:2307
void schurAssign(const DenseMatrix< MT, SO2 > &rhs)
Default implementation of the Schur product assignment of a dense matrix.
Definition: CompressedMatrix.h:3080
Iterator find(size_t i, size_t j)
Searches for a specific matrix element.
Definition: CompressedMatrix.h:2521
CompressedMatrix< Type, SO, Tag > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:327
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:337
CompressedMatrix()
The default constructor for CompressedMatrix.
Definition: CompressedMatrix.h:598
Base class for dense matrices.
Definition: DenseMatrix.h:82
Access proxy for sparse, matrices.
Definition: MatrixAccessProxy.h:101
Base class for matrices.
Definition: Matrix.h:85
Base class for sparse matrices.
Definition: SparseMatrix.h:77
Index-value-pair for sparse vectors and matrices.
Definition: ValueIndexPair.h:75
constexpr Reference value() noexcept
Access to the current value of the value-index-pair.
Definition: ValueIndexPair.h:370
Initializer list type of the Blaze library.
Pointer difference type of the Blaze library.
Constraint on the data type.
Header file for the SparseMatrix base class.
OutputIterator transfer(InputIterator first, InputIterator last, OutputIterator dest)
Transfers the elements from the given source range to the destination range.
Definition: Transfer.h:71
bool isDefault(const CompressedMatrix< Type, SO, Tag > &m)
Returns whether the given compressed matrix is in default state.
Definition: CompressedMatrix.h:6047
void swap(CompressedMatrix< Type, SO, Tag > &a, CompressedMatrix< Type, SO, Tag > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:6093
bool isIntact(const CompressedMatrix< Type, SO, Tag > &m)
Returns whether the invariants of the given compressed matrix are intact.
Definition: CompressedMatrix.h:6075
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.
Definition: Volatile.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.
Definition: Pointer.h:79
#define BLAZE_CONSTRAINT_MUST_HAVE_SAME_SIZE(T1, T2)
Constraint on the size of two data types.
Definition: SameSize.h:60
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.
Definition: Const.h:79
#define BLAZE_CONSTRAINT_MUST_BE_SAME_TAG(A, B)
Data type constraint.
Definition: SameTag.h:68
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.
Definition: Reference.h:79
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1375
decltype(auto) ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatMapExpr.h:1501
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:766
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:812
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.
Definition: RequiresEvaluation.h:81
typename AddTrait< T1, T2 >::Type AddTrait_t
Auxiliary alias declaration for the AddTrait class template.
Definition: AddTrait.h:163
typename SubTrait< T1, T2 >::Type SubTrait_t
Auxiliary alias declaration for the SubTrait class template.
Definition: SubTrait.h:163
typename MultTrait< T1, T2 >::Type MultTrait_t
Auxiliary alias declaration for the MultTrait class template.
Definition: MultTrait.h:165
constexpr bool IsScalar_v
Auxiliary variable template for the IsScalar type trait.
Definition: IsScalar.h:104
constexpr bool IsMatrix_v
Auxiliary variable template for the IsMatrix type trait.
Definition: IsMatrix.h:124
constexpr bool IsSparseMatrix_v
Auxiliary variable template for the IsSparseMatrix type trait.
Definition: IsSparseMatrix.h:124
constexpr bool IsSparseVector_v
Auxiliary variable template for the IsSparseVector type trait.
Definition: IsSparseVector.h:124
RelaxationFlag
Relaxation flag for strict or relaxed semantics.
Definition: RelaxationFlag.h:66
constexpr Infinity inf
Global Infinity instance.
Definition: Infinity.h:1080
constexpr size_t determineColumns(initializer_list< initializer_list< Type > > list) noexcept
Determines the maximum number of columns specified by the given initializer list.
Definition: InitializerList.h:107
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:644
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:730
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:692
constexpr void reset(Matrix< MT, SO > &matrix)
Resetting the given matrix.
Definition: Matrix.h:806
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:660
void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:1108
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:584
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:518
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:676
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.
Definition: Assert.h:117
MT::Iterator lowerBound(SparseMatrix< MT, SO > &sm, size_t i, size_t j)
Returns an iterator to the first index not less than the given index.
Definition: SparseMatrix.h:194
MT::Iterator find(SparseMatrix< MT, SO > &sm, size_t i, size_t j)
Searches for a specific matrix element.
Definition: SparseMatrix.h:144
void deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:230
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:138
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.
Definition: Exception.h:331
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.
Definition: Exception.h:235
Header file for the exception macros of the math module.
Header file for all forward declarations of the math module.
Header file for the extended initializer_list functionality.
constexpr bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
constexpr bool columnMajor
Storage order flag for column-major matrices.
Definition: StorageOrder.h:99
Header file for all forward declarations for sparse vectors and matrices.
Header file for the StorageOrder type trait.
Header file for the serial shim.
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:351
CompressedMatrix< NewType, SO, Tag > Other
The type of the other CompressedMatrix.
Definition: CompressedMatrix.h:352
Resize mechanism to obtain a CompressedMatrix with different fixed dimensions.
Definition: CompressedMatrix.h:361
CompressedMatrix< Type, SO, Tag > Other
The type of the other CompressedMatrix.
Definition: CompressedMatrix.h:362
Header file for the default storage order for all vectors of the Blaze library.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
Header file for the default transpose flag for all vectors of the Blaze library.
Header file for the IsZero type trait.
Header file for basic type definitions.
Header file for the generic max algorithm.
Header file for the generic min algorithm.