Blaze 3.9
Sparse.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_VIEWS_COLUMNS_SPARSE_H_
36#define _BLAZE_MATH_VIEWS_COLUMNS_SPARSE_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <vector>
44#include <blaze/math/Aliases.h>
82#include <blaze/util/Assert.h>
86#include <blaze/util/mpl/If.h>
87#include <blaze/util/Types.h>
90
91
92namespace blaze {
93
94//=================================================================================================
95//
96// CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR SPARSE MATRICES
97//
98//=================================================================================================
99
100//*************************************************************************************************
108template< typename MT // Type of the sparse matrix
109 , bool SF // Symmetry flag
110 , typename... CCAs > // Compile time column arguments
111class Columns<MT,true,false,SF,CCAs...>
112 : public View< SparseMatrix< Columns<MT,true,false,SF,CCAs...>, true > >
113 , private ColumnsData<CCAs...>
114{
115 private:
116 //**Type definitions****************************************************************************
117 using DataType = ColumnsData<CCAs...>;
118 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
119 //**********************************************************************************************
120
121 //**Compile time flags**************************************************************************
122 using DataType::N;
123 //**********************************************************************************************
124
125 public:
126 //**Type definitions****************************************************************************
128 using This = Columns<MT,true,false,SF,CCAs...>;
129
131 using BaseType = View< SparseMatrix<This,true> >;
132
133 using ViewedType = MT;
134 using ResultType = ColumnsTrait_t<MT,N>;
135 using OppositeType = OppositeType_t<ResultType>;
136 using TransposeType = TransposeType_t<ResultType>;
137 using ElementType = ElementType_t<MT>;
138 using ReturnType = ReturnType_t<MT>;
139 using CompositeType = const Columns&;
140
142 using ConstReference = ConstReference_t<MT>;
143
145 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
146
148 using ConstIterator = ConstIterator_t<MT>;
149
151 using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
152 //**********************************************************************************************
153
154 //**Compilation flags***************************************************************************
156 static constexpr bool smpAssignable = MT::smpAssignable;
157
159 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
160 //**********************************************************************************************
161
162 //**Constructors********************************************************************************
165 template< typename... RCAs >
166 explicit inline Columns( MT& matrix, RCAs... args );
167
168 Columns( const Columns& ) = default;
169 Columns( Columns&& ) = default;
171 //**********************************************************************************************
172
173 //**Destructor**********************************************************************************
176 ~Columns() = default;
178 //**********************************************************************************************
179
180 //**Data access functions***********************************************************************
183 inline Reference operator()( size_t i, size_t j );
184 inline ConstReference operator()( size_t i, size_t j ) const;
185 inline Reference at( size_t i, size_t j );
186 inline ConstReference at( size_t i, size_t j ) const;
187 inline Iterator begin ( size_t j );
188 inline ConstIterator begin ( size_t j ) const;
189 inline ConstIterator cbegin( size_t j ) const;
190 inline Iterator end ( size_t j );
191 inline ConstIterator end ( size_t j ) const;
192 inline ConstIterator cend ( size_t j ) const;
194 //**********************************************************************************************
195
196 //**Assignment operators************************************************************************
199 inline Columns& operator=( initializer_list< initializer_list<ElementType> > list );
200 inline Columns& operator=( const Columns& rhs );
201
202 template< typename MT2, bool SO > inline Columns& operator= ( const Matrix<MT2,SO>& rhs );
203 template< typename MT2, bool SO > inline Columns& operator+=( const Matrix<MT2,SO>& rhs );
204 template< typename MT2, bool SO > inline Columns& operator-=( const Matrix<MT2,SO>& rhs );
205 template< typename MT2, bool SO > inline Columns& operator%=( const Matrix<MT2,SO>& rhs );
207 //**********************************************************************************************
208
209 //**Utility functions***************************************************************************
212 using DataType::idx;
213 using DataType::idces;
214 using DataType::columns;
215
216 inline MT& operand() noexcept;
217 inline const MT& operand() const noexcept;
218
219 inline size_t rows() const noexcept;
220 inline size_t capacity() const noexcept;
221 inline size_t capacity( size_t j ) const noexcept;
222 inline size_t nonZeros() const;
223 inline size_t nonZeros( size_t j ) const;
224 inline void reset();
225 inline void reset( size_t j );
226 inline void reserve( size_t nonzeros );
227 void reserve( size_t j, size_t nonzeros );
228 inline void trim();
229 inline void trim( size_t j );
231 //**********************************************************************************************
232
233 //**Insertion functions*************************************************************************
236 inline Iterator set ( size_t i, size_t j, const ElementType& value );
237 inline Iterator insert ( size_t i, size_t j, const ElementType& value );
238 inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
239 inline void finalize( size_t j );
241 //**********************************************************************************************
242
243 //**Erase functions*****************************************************************************
246 inline void erase( size_t i, size_t j );
247 inline Iterator erase( size_t j, Iterator pos );
248 inline Iterator erase( size_t j, Iterator first, Iterator last );
249
250 template< typename Pred >
251 inline void erase( Pred predicate );
252
253 template< typename Pred >
254 inline void erase( size_t j, Iterator first, Iterator last, Pred predicate );
256 //**********************************************************************************************
257
258 //**Lookup functions****************************************************************************
261 inline Iterator find ( size_t i, size_t j );
262 inline ConstIterator find ( size_t i, size_t j ) const;
263 inline Iterator lowerBound( size_t i, size_t j );
264 inline ConstIterator lowerBound( size_t i, size_t j ) const;
265 inline Iterator upperBound( size_t i, size_t j );
266 inline ConstIterator upperBound( size_t i, size_t j ) const;
268 //**********************************************************************************************
269
270 //**Numeric functions***************************************************************************
273 inline Columns& transpose();
274 inline Columns& ctranspose();
275
276 template< typename Other > inline Columns& scale( const Other& scalar );
278 //**********************************************************************************************
279
280 //**Expression template evaluation functions****************************************************
283 template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
284 template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
285
286 inline bool canSMPAssign() const noexcept;
287
288 template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
289 template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
290 template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
291 template< typename MT2, bool SO > inline void addAssign ( const Matrix<MT2,SO>& rhs );
292 template< typename MT2, bool SO > inline void subAssign ( const Matrix<MT2,SO>& rhs );
293 template< typename MT2, bool SO > inline void schurAssign( const Matrix<MT2,SO>& rhs );
295 //**********************************************************************************************
296
297 private:
298 //**Utility functions***************************************************************************
301 inline size_t extendCapacity( size_t j ) const noexcept;
303 //**********************************************************************************************
304
305 //**Member variables****************************************************************************
308 Operand matrix_;
310 //**********************************************************************************************
311
312 //**Compile time checks*************************************************************************
321 //**********************************************************************************************
322};
324//*************************************************************************************************
325
326
327
328
329//=================================================================================================
330//
331// CONSTRUCTORS
332//
333//=================================================================================================
334
335//*************************************************************************************************
348template< typename MT // Type of the sparse matrix
349 , bool SF // Symmetry flag
350 , typename... CCAs > // Compile time column arguments
351template< typename... RCAs > // Runtime column arguments
352inline Columns<MT,true,false,SF,CCAs...>::Columns( MT& matrix, RCAs... args )
353 : DataType( args... ) // Base class initialization
354 , matrix_ ( matrix ) // The matrix containing the columns
355{
356 if( isChecked( args... ) ) {
357 for( size_t j=0UL; j<columns(); ++j ) {
358 if( matrix_.columns() <= idx(j) ) {
359 BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
360 }
361 }
362 }
363}
365//*************************************************************************************************
366
367
368
369
370//=================================================================================================
371//
372// DATA ACCESS FUNCTIONS
373//
374//=================================================================================================
375
376//*************************************************************************************************
387template< typename MT // Type of the sparse matrix
388 , bool SF // Symmetry flag
389 , typename... CCAs > // Compile time column arguments
390inline typename Columns<MT,true,false,SF,CCAs...>::Reference
391 Columns<MT,true,false,SF,CCAs...>::operator()( size_t i, size_t j )
392{
393 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
394 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
395
396 return matrix_(i,idx(j));
397}
399//*************************************************************************************************
400
401
402//*************************************************************************************************
413template< typename MT // Type of the sparse matrix
414 , bool SF // Symmetry flag
415 , typename... CCAs > // Compile time column arguments
416inline typename Columns<MT,true,false,SF,CCAs...>::ConstReference
417 Columns<MT,true,false,SF,CCAs...>::operator()( size_t i, size_t j ) const
418{
419 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
420 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
421
422 return const_cast<const MT&>( matrix_ )(i,idx(j));
423}
425//*************************************************************************************************
426
427
428//*************************************************************************************************
440template< typename MT // Type of the sparse matrix
441 , bool SF // Symmetry flag
442 , typename... CCAs > // Compile time column arguments
443inline typename Columns<MT,true,false,SF,CCAs...>::Reference
444 Columns<MT,true,false,SF,CCAs...>::at( size_t i, size_t j )
445{
446 if( i >= rows() ) {
447 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
448 }
449 if( j >= columns() ) {
450 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
451 }
452 return (*this)(i,j);
453}
455//*************************************************************************************************
456
457
458//*************************************************************************************************
470template< typename MT // Type of the sparse matrix
471 , bool SF // Symmetry flag
472 , typename... CCAs > // Compile time column arguments
473inline typename Columns<MT,true,false,SF,CCAs...>::ConstReference
474 Columns<MT,true,false,SF,CCAs...>::at( size_t i, size_t j ) const
475{
476 if( i >= rows() ) {
477 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
478 }
479 if( j >= columns() ) {
480 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
481 }
482 return (*this)(i,j);
483}
485//*************************************************************************************************
486
487
488//*************************************************************************************************
497template< typename MT // Type of the sparse matrix
498 , bool SF // Symmetry flag
499 , typename... CCAs > // Compile time column arguments
500inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
502{
503 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
504
505 return matrix_.begin( idx(j) );
506}
508//*************************************************************************************************
509
510
511//*************************************************************************************************
520template< typename MT // Type of the sparse matrix
521 , bool SF // Symmetry flag
522 , typename... CCAs > // Compile time column arguments
523inline typename Columns<MT,true,false,SF,CCAs...>::ConstIterator
525{
526 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
527
528 return matrix_.cbegin( idx(j) );
529}
531//*************************************************************************************************
532
533
534//*************************************************************************************************
543template< typename MT // Type of the sparse matrix
544 , bool SF // Symmetry flag
545 , typename... CCAs > // Compile time column arguments
546inline typename Columns<MT,true,false,SF,CCAs...>::ConstIterator
548{
549 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
550
551 return matrix_.cbegin( idx(j) );
552}
554//*************************************************************************************************
555
556
557//*************************************************************************************************
566template< typename MT // Type of the sparse matrix
567 , bool SF // Symmetry flag
568 , typename... CCAs > // Compile time column arguments
569inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
571{
572 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
573
574 return matrix_.end( idx(j) );
575}
577//*************************************************************************************************
578
579
580//*************************************************************************************************
589template< typename MT // Type of the sparse matrix
590 , bool SF // Symmetry flag
591 , typename... CCAs > // Compile time column arguments
592inline typename Columns<MT,true,false,SF,CCAs...>::ConstIterator
594{
595 BLAZE_USER_ASSERT( j < columns(), "Invalid row access index" );
596
597 return matrix_.cend( idx(j) );
598}
600//*************************************************************************************************
601
602
603//*************************************************************************************************
612template< typename MT // Type of the sparse matrix
613 , bool SF // Symmetry flag
614 , typename... CCAs > // Compile time column arguments
615inline typename Columns<MT,true,false,SF,CCAs...>::ConstIterator
617{
618 BLAZE_USER_ASSERT( j < columns(), "Invalid row access index" );
619
620 return matrix_.cend( idx(j) );
621}
623//*************************************************************************************************
624
625
626
627
628//=================================================================================================
629//
630// ASSIGNMENT OPERATORS
631//
632//=================================================================================================
633
634//*************************************************************************************************
650template< typename MT // Type of the sparse matrix
651 , bool SF // Symmetry flag
652 , typename... CCAs > // Compile time column arguments
653inline Columns<MT,true,false,SF,CCAs...>&
654 Columns<MT,true,false,SF,CCAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
655{
658
659 if( list.size() != rows() ) {
660 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column selection" );
661 }
662
663 const InitializerMatrix<ElementType> tmp( list, columns() );
664
665 if( IsRestricted_v<MT> ) {
666 for( size_t j=0UL; j<columns(); ++j ) {
667 if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, j ) ) {
668 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
669 }
670 }
671 }
672
673 decltype(auto) left( derestrict( *this ) );
674
675 left.reset();
676 smpAssign( left, tmp );
677
678 return *this;
679}
681//*************************************************************************************************
682
683
684//*************************************************************************************************
699template< typename MT // Type of the sparse matrix
700 , bool SF // Symmetry flag
701 , typename... CCAs > // Compile time column arguments
702inline Columns<MT,true,false,SF,CCAs...>&
703 Columns<MT,true,false,SF,CCAs...>::operator=( const Columns& rhs )
704{
707
710
711 if( this == &rhs || ( &matrix_ == &rhs.matrix_ && compareIndices( *this, rhs ) ) )
712 return *this;
713
714 if( rows() != rhs.rows() || columns() != rhs.columns() ) {
715 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
716 }
717
718 if( IsRestricted_v<MT> ) {
719 for( size_t j=0UL; j<columns(); ++j ) {
720 if( !tryAssign( matrix_, column( rhs, j, unchecked ), 0UL, idx(j) ) ) {
721 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
722 }
723 }
724 }
725
726 decltype(auto) left( derestrict( *this ) );
727
728 if( rhs.canAlias( this ) ) {
729 const ResultType tmp( rhs );
730 left.reset();
731 smpAssign( left, tmp );
732 }
733 else {
734 left.reset();
735 smpAssign( left, rhs );
736 }
737
738 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
739
740 return *this;
741}
743//*************************************************************************************************
744
745
746//*************************************************************************************************
761template< typename MT // Type of the sparse matrix
762 , bool SF // Symmetry flag
763 , typename... CCAs > // Compile time column arguments
764template< typename MT2 // Type of the right-hand side matrix
765 , bool SO > // Storage order of the right-hand side matrix
766inline Columns<MT,true,false,SF,CCAs...>&
767 Columns<MT,true,false,SF,CCAs...>::operator=( const Matrix<MT2,SO>& rhs )
768{
771
773
774 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
775 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
776 }
777
778 using Right = CompositeType_t<MT2>;
779 Right right( *rhs );
780
781 if( IsRestricted_v<MT> ) {
782 for( size_t j=0UL; j<columns(); ++j ) {
783 if( !tryAssign( matrix_, column( right, j, unchecked ), 0UL, idx(j) ) ) {
784 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
785 }
786 }
787 }
788
789 decltype(auto) left( derestrict( *this ) );
790
791 if( IsReference_v<Right> && right.canAlias( this ) ) {
792 const ResultType_t<MT2> tmp( right );
793 left.reset();
794 smpAssign( left, tmp );
795 }
796 else {
797 left.reset();
798 smpAssign( left, right );
799 }
800
801 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
802
803 return *this;
804}
806//*************************************************************************************************
807
808
809//*************************************************************************************************
823template< typename MT // Type of the sparse matrix
824 , bool SF // Symmetry flag
825 , typename... CCAs > // Compile time column arguments
826template< typename MT2 // Type of the right-hand side matrix
827 , bool SO > // Storage order of the right-hand side matrix
828inline Columns<MT,true,false,SF,CCAs...>&
829 Columns<MT,true,false,SF,CCAs...>::operator+=( const Matrix<MT2,SO>& rhs )
830{
833
837
838 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
839
841
842 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
843 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
844 }
845
846 const AddType tmp( *this + (*rhs) );
847
848 if( IsRestricted_v<MT> ) {
849 for( size_t j=0UL; j<columns(); ++j ) {
850 if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
851 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
852 }
853 }
854 }
855
856 decltype(auto) left( derestrict( *this ) );
857
858 left.reset();
859 smpAssign( left, tmp );
860
861 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
862
863 return *this;
864}
866//*************************************************************************************************
867
868
869//*************************************************************************************************
883template< typename MT // Type of the sparse matrix
884 , bool SF // Symmetry flag
885 , typename... CCAs > // Compile time column arguments
886template< typename MT2 // Type of the right-hand side matrix
887 , bool SO > // Storage order of the right-hand side matrix
888inline Columns<MT,true,false,SF,CCAs...>&
889 Columns<MT,true,false,SF,CCAs...>::operator-=( const Matrix<MT2,SO>& rhs )
890{
893
897
898 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
899
901
902 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
903 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
904 }
905
906 const SubType tmp( *this - (*rhs) );
907
908 if( IsRestricted_v<MT> ) {
909 for( size_t j=0UL; j<columns(); ++j ) {
910 if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
911 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
912 }
913 }
914 }
915
916 decltype(auto) left( derestrict( *this ) );
917
918 left.reset();
919 smpAssign( left, tmp );
920
921 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
922
923 return *this;
924}
926//*************************************************************************************************
927
928
929//*************************************************************************************************
943template< typename MT // Type of the sparse matrix
944 , bool SF // Symmetry flag
945 , typename... CCAs > // Compile time column arguments
946template< typename MT2 // Type of the right-hand side matrix
947 , bool SO > // Storage order of the right-hand side matrix
948inline Columns<MT,true,false,SF,CCAs...>&
949 Columns<MT,true,false,SF,CCAs...>::operator%=( const Matrix<MT2,SO>& rhs )
950{
953
957
958 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
959
961
962 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
963 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
964 }
965
966 const SchurType tmp( *this % (*rhs) );
967
968 if( IsRestricted_v<MT> ) {
969 for( size_t j=0UL; j<columns(); ++j ) {
970 if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
971 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
972 }
973 }
974 }
975
976 decltype(auto) left( derestrict( *this ) );
977
978 left.reset();
979 smpAssign( left, tmp );
980
981 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
982
983 return *this;
984}
986//*************************************************************************************************
987
988
989
990
991//=================================================================================================
992//
993// UTILITY FUNCTIONS
994//
995//=================================================================================================
996
997//*************************************************************************************************
1003template< typename MT // Type of the sparse matrix
1004 , bool SF // Symmetry flag
1005 , typename... CCAs > // Compile time column arguments
1006inline MT& Columns<MT,true,false,SF,CCAs...>::operand() noexcept
1007{
1008 return matrix_;
1009}
1011//*************************************************************************************************
1012
1013
1014//*************************************************************************************************
1020template< typename MT // Type of the sparse matrix
1021 , bool SF // Symmetry flag
1022 , typename... CCAs > // Compile time column arguments
1023inline const MT& Columns<MT,true,false,SF,CCAs...>::operand() const noexcept
1024{
1025 return matrix_;
1026}
1028//*************************************************************************************************
1029
1030
1031//*************************************************************************************************
1037template< typename MT // Type of the sparse matrix
1038 , bool SF // Symmetry flag
1039 , typename... CCAs > // Compile time column arguments
1040inline size_t Columns<MT,true,false,SF,CCAs...>::rows() const noexcept
1041{
1042 return matrix_.rows();
1043}
1045//*************************************************************************************************
1046
1047
1048//*************************************************************************************************
1054template< typename MT // Type of the sparse matrix
1055 , bool SF // Symmetry flag
1056 , typename... CCAs > // Compile time column arguments
1057inline size_t Columns<MT,true,false,SF,CCAs...>::capacity() const noexcept
1058{
1059 return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
1060}
1062//*************************************************************************************************
1063
1064
1065//*************************************************************************************************
1074template< typename MT // Type of the sparse matrix
1075 , bool SF // Symmetry flag
1076 , typename... CCAs > // Compile time column arguments
1077inline size_t Columns<MT,true,false,SF,CCAs...>::capacity( size_t j ) const noexcept
1078{
1079 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1080
1081 return matrix_.capacity( idx(j) );
1082}
1084//*************************************************************************************************
1085
1086
1087//*************************************************************************************************
1093template< typename MT // Type of the sparse matrix
1094 , bool SF // Symmetry flag
1095 , typename... CCAs > // Compile time column arguments
1097{
1098 size_t nonzeros( 0UL );
1099
1100 for( size_t j=0UL; j<columns(); ++j )
1101 nonzeros += nonZeros( j );
1102
1103 return nonzeros;
1104}
1106//*************************************************************************************************
1107
1108
1109//*************************************************************************************************
1118template< typename MT // Type of the sparse matrix
1119 , bool SF // Symmetry flag
1120 , typename... CCAs > // Compile time column arguments
1121inline size_t Columns<MT,true,false,SF,CCAs...>::nonZeros( size_t j ) const
1122{
1123 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1124
1125 return matrix_.nonZeros( idx(j) );
1126}
1128//*************************************************************************************************
1129
1130
1131//*************************************************************************************************
1137template< typename MT // Type of the sparse matrix
1138 , bool SF // Symmetry flag
1139 , typename... CCAs > // Compile time column arguments
1141{
1142 for( size_t j=0UL; j<columns(); ++j ) {
1143 matrix_.reset( idx(j) );
1144 }
1145}
1147//*************************************************************************************************
1148
1149
1150//*************************************************************************************************
1160template< typename MT // Type of the sparse matrix
1161 , bool SF // Symmetry flag
1162 , typename... CCAs > // Compile time column arguments
1163inline void Columns<MT,true,false,SF,CCAs...>::reset( size_t j )
1164{
1165 matrix_.reset( idx(j) );
1166}
1168//*************************************************************************************************
1169
1170
1171//*************************************************************************************************
1182template< typename MT // Type of the sparse matrix
1183 , bool SF // Symmetry flag
1184 , typename... CCAs > // Compile time column arguments
1185inline void Columns<MT,true,false,SF,CCAs...>::reserve( size_t nonzeros )
1186{
1187 const size_t current( capacity() );
1188
1189 if( nonzeros > current ) {
1190 matrix_.reserve( matrix_.capacity() + nonzeros - current );
1191 }
1192}
1194//*************************************************************************************************
1195
1196
1197//*************************************************************************************************
1210template< typename MT // Type of the sparse matrix
1211 , bool SF // Symmetry flag
1212 , typename... CCAs > // Compile time column arguments
1213void Columns<MT,true,false,SF,CCAs...>::reserve( size_t j, size_t nonzeros )
1214{
1215 matrix_.reserve( idx(j), nonzeros );
1216}
1218//*************************************************************************************************
1219
1220
1221//*************************************************************************************************
1231template< typename MT // Type of the sparse matrix
1232 , bool SF // Symmetry flag
1233 , typename... CCAs > // Compile time column arguments
1234void Columns<MT,true,false,SF,CCAs...>::trim()
1235{
1236 for( size_t j=0UL; j<columns(); ++j ) {
1237 trim( j );
1238 }
1239}
1241//*************************************************************************************************
1242
1243
1244//*************************************************************************************************
1255template< typename MT // Type of the sparse matrix
1256 , bool SF // Symmetry flag
1257 , typename... CCAs > // Compile time column arguments
1258void Columns<MT,true,false,SF,CCAs...>::trim( size_t j )
1259{
1260 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1261
1262 matrix_.trim( idx(j) );
1263}
1265//*************************************************************************************************
1266
1267
1268//*************************************************************************************************
1278template< typename MT // Type of the sparse matrix
1279 , bool SF // Symmetry flag
1280 , typename... CCAs > // Compile time column arguments
1281inline size_t Columns<MT,true,false,SF,CCAs...>::extendCapacity( size_t j ) const noexcept
1282{
1283 using blaze::max;
1284 using blaze::min;
1285
1286 size_t nonzeros( 2UL*capacity( j )+1UL );
1287 nonzeros = max( nonzeros, 7UL );
1288 nonzeros = min( nonzeros, rows() );
1289
1290 BLAZE_INTERNAL_ASSERT( nonzeros > capacity( j ), "Invalid capacity value" );
1291
1292 return nonzeros;
1293}
1295//*************************************************************************************************
1296
1297
1298
1299
1300//=================================================================================================
1301//
1302// INSERTION FUNCTIONS
1303//
1304//=================================================================================================
1305
1306//*************************************************************************************************
1319template< typename MT // Type of the sparse matrix
1320 , bool SF // Symmetry flag
1321 , typename... CCAs > // Compile time column arguments
1322inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
1323 Columns<MT,true,false,SF,CCAs...>::set( size_t i, size_t j, const ElementType& value )
1324{
1325 return matrix_.set( i, idx(j), value );
1326}
1328//*************************************************************************************************
1329
1330
1331//*************************************************************************************************
1345template< typename MT // Type of the sparse matrix
1346 , bool SF // Symmetry flag
1347 , typename... CCAs > // Compile time column arguments
1348inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
1349 Columns<MT,true,false,SF,CCAs...>::insert( size_t i, size_t j, const ElementType& value )
1350{
1351 return matrix_.insert( i, idx(j), value );
1352}
1354//*************************************************************************************************
1355
1356
1357//*************************************************************************************************
1401template< typename MT // Type of the sparse matrix
1402 , bool SF // Symmetry flag
1403 , typename... CCAs > // Compile time column arguments
1404inline void Columns<MT,true,false,SF,CCAs...>::append( size_t i, size_t j, const ElementType& value, bool check )
1405{
1406 if( !check || !isDefault<strict>( value ) )
1407 matrix_.insert( i, idx(j), value );
1408}
1410//*************************************************************************************************
1411
1412
1413//*************************************************************************************************
1427template< typename MT // Type of the sparse matrix
1428 , bool SF // Symmetry flag
1429 , typename... CCAs > // Compile time column arguments
1430inline void Columns<MT,true,false,SF,CCAs...>::finalize( size_t j )
1431{
1432 MAYBE_UNUSED( j );
1433
1434 return;
1435}
1437//*************************************************************************************************
1438
1439
1440
1441
1442//=================================================================================================
1443//
1444// ERASE FUNCTIONS
1445//
1446//=================================================================================================
1447
1448//*************************************************************************************************
1458template< typename MT // Type of the sparse matrix
1459 , bool SF // Symmetry flag
1460 , typename... CCAs > // Compile time column arguments
1461inline void Columns<MT,true,false,SF,CCAs...>::erase( size_t i, size_t j )
1462{
1463 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1464 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1465
1466 matrix_.erase( i, idx(j) );
1467}
1469//*************************************************************************************************
1470
1471
1472//*************************************************************************************************
1482template< typename MT // Type of the sparse matrix
1483 , bool SF // Symmetry flag
1484 , typename... CCAs > // Compile time column arguments
1485inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
1486 Columns<MT,true,false,SF,CCAs...>::erase( size_t j, Iterator pos )
1487{
1488 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1489
1490 return matrix_.erase( idx(j), pos );
1491}
1493//*************************************************************************************************
1494
1495
1496//*************************************************************************************************
1507template< typename MT // Type of the sparse matrix
1508 , bool SF // Symmetry flag
1509 , typename... CCAs > // Compile time column arguments
1510inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
1511 Columns<MT,true,false,SF,CCAs...>::erase( size_t j, Iterator first, Iterator last )
1512{
1513 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1514
1515 return matrix_.erase( idx(j), first, last );
1516}
1518//*************************************************************************************************
1519
1520
1521//*************************************************************************************************
1544template< typename MT // Type of the sparse matrix
1545 , bool SF // Symmetry flag
1546 , typename... CCAs > // Compile time column arguments
1547template< typename Pred > // Type of the unary predicate
1548inline void Columns<MT,true,false,SF,CCAs...>::erase( Pred predicate )
1549{
1550 for( size_t j=0UL; j<columns(); ++j ) {
1551 matrix_.erase( idx(j), begin(j), end(j), predicate );
1552 }
1553}
1555//*************************************************************************************************
1556
1557
1558//*************************************************************************************************
1585template< typename MT // Type of the sparse matrix
1586 , bool SF // Symmetry flag
1587 , typename... CCAs > // Compile time column arguments
1588template< typename Pred > // Type of the unary predicate
1589inline void Columns<MT,true,false,SF,CCAs...>::erase( size_t j, Iterator first, Iterator last, Pred predicate )
1590{
1591 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1592
1593 matrix_.erase( idx(j), first, last, predicate );
1594}
1596//*************************************************************************************************
1597
1598
1599
1600
1601//=================================================================================================
1602//
1603// LOOKUP FUNCTIONS
1604//
1605//=================================================================================================
1606
1607//*************************************************************************************************
1622template< typename MT // Type of the sparse matrix
1623 , bool SF // Symmetry flag
1624 , typename... CCAs > // Compile time column arguments
1625inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
1626 Columns<MT,true,false,SF,CCAs...>::find( size_t i, size_t j )
1627{
1628 return matrix_.find( i, idx(j) );
1629}
1631//*************************************************************************************************
1632
1633
1634//*************************************************************************************************
1649template< typename MT // Type of the sparse matrix
1650 , bool SF // Symmetry flag
1651 , typename... CCAs > // Compile time column arguments
1652inline typename Columns<MT,true,false,SF,CCAs...>::ConstIterator
1653 Columns<MT,true,false,SF,CCAs...>::find( size_t i, size_t j ) const
1654{
1655 return matrix_.find( i, idx(j) );
1656}
1658//*************************************************************************************************
1659
1660
1661//*************************************************************************************************
1675template< typename MT // Type of the sparse matrix
1676 , bool SF // Symmetry flag
1677 , typename... CCAs > // Compile time column arguments
1678inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
1680{
1681 return matrix_.lowerBound( i, idx(j) );
1682}
1684//*************************************************************************************************
1685
1686
1687//*************************************************************************************************
1701template< typename MT // Type of the sparse matrix
1702 , bool SF // Symmetry flag
1703 , typename... CCAs > // Compile time column arguments
1704inline typename Columns<MT,true,false,SF,CCAs...>::ConstIterator
1705 Columns<MT,true,false,SF,CCAs...>::lowerBound( size_t i, size_t j ) const
1706{
1707 return matrix_.lowerBound( i, idx(j) );
1708}
1710//*************************************************************************************************
1711
1712
1713//*************************************************************************************************
1727template< typename MT // Type of the sparse matrix
1728 , bool SF // Symmetry flag
1729 , typename... CCAs > // Compile time column arguments
1730inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
1732{
1733 return matrix_.upperBound( i, idx(j) );
1734}
1736//*************************************************************************************************
1737
1738
1739//*************************************************************************************************
1753template< typename MT // Type of the sparse matrix
1754 , bool SF // Symmetry flag
1755 , typename... CCAs > // Compile time column arguments
1756inline typename Columns<MT,true,false,SF,CCAs...>::ConstIterator
1757 Columns<MT,true,false,SF,CCAs...>::upperBound( size_t i, size_t j ) const
1758{
1759 return matrix_.upperBound( i, idx(j) );
1760}
1762//*************************************************************************************************
1763
1764
1765
1766
1767//=================================================================================================
1768//
1769// NUMERIC FUNCTIONS
1770//
1771//=================================================================================================
1772
1773//*************************************************************************************************
1786template< typename MT // Type of the sparse matrix
1787 , bool SF // Symmetry flag
1788 , typename... CCAs > // Compile time column arguments
1789inline Columns<MT,true,false,SF,CCAs...>&
1791{
1792 if( rows() != columns() ) {
1793 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1794 }
1795
1796 const ResultType tmp( trans( *this ) );
1797
1798 if( IsRestricted_v<MT> ) {
1799 for( size_t j=0UL; j<columns(); ++j ) {
1800 if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
1801 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1802 }
1803 }
1804 }
1805
1806 decltype(auto) left( derestrict( *this ) );
1807
1808 left.reset();
1809 smpAssign( left, tmp );
1810
1811 return *this;
1812}
1814//*************************************************************************************************
1815
1816
1817//*************************************************************************************************
1830template< typename MT // Type of the sparse matrix
1831 , bool SF // Symmetry flag
1832 , typename... CCAs > // Compile time column arguments
1833inline Columns<MT,true,false,SF,CCAs...>&
1835{
1836 if( rows() != columns() ) {
1837 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1838 }
1839
1840 const ResultType tmp( ctrans( *this ) );
1841
1842 if( IsRestricted_v<MT> ) {
1843 for( size_t j=0UL; j<columns(); ++j ) {
1844 if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
1845 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1846 }
1847 }
1848 }
1849
1850 decltype(auto) left( derestrict( *this ) );
1851
1852 left.reset();
1853 smpAssign( left, tmp );
1854
1855 return *this;
1856}
1858//*************************************************************************************************
1859
1860
1861//*************************************************************************************************
1874template< typename MT // Type of the sparse matrix
1875 , bool SF // Symmetry flag
1876 , typename... CCAs > // Compile time column arguments
1877template< typename Other > // Data type of the scalar value
1878inline Columns<MT,true,false,SF,CCAs...>&
1879 Columns<MT,true,false,SF,CCAs...>::scale( const Other& scalar )
1880{
1882
1883 for( size_t j=0UL; j<columns(); ++j ) {
1884 const Iterator last( end(j) );
1885 for( Iterator element=begin(j); element!=last; ++element )
1886 element->value() *= scalar;
1887 }
1888
1889 return *this;
1890}
1892//*************************************************************************************************
1893
1894
1895
1896
1897//=================================================================================================
1898//
1899// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1900//
1901//=================================================================================================
1902
1903//*************************************************************************************************
1914template< typename MT // Type of the sparse matrix
1915 , bool SF // Symmetry flag
1916 , typename... CCAs > // Compile time column arguments
1917template< typename Other > // Data type of the foreign expression
1918inline bool Columns<MT,true,false,SF,CCAs...>::canAlias( const Other* alias ) const noexcept
1919{
1920 return matrix_.isAliased( &unview( *alias ) );
1921}
1923//*************************************************************************************************
1924
1925
1926//*************************************************************************************************
1937template< typename MT // Type of the sparse matrix
1938 , bool SF // Symmetry flag
1939 , typename... CCAs > // Compile time column arguments
1940template< typename Other > // Data type of the foreign expression
1941inline bool Columns<MT,true,false,SF,CCAs...>::isAliased( const Other* alias ) const noexcept
1942{
1943 return matrix_.isAliased( &unview( *alias ) );
1944}
1946//*************************************************************************************************
1947
1948
1949//*************************************************************************************************
1960template< typename MT // Type of the sparse matrix
1961 , bool SF // Symmetry flag
1962 , typename... CCAs > // Compile time column arguments
1963inline bool Columns<MT,true,false,SF,CCAs...>::canSMPAssign() const noexcept
1964{
1965 return false;
1966}
1968//*************************************************************************************************
1969
1970
1971//*************************************************************************************************
1983template< typename MT // Type of the sparse matrix
1984 , bool SF // Symmetry flag
1985 , typename... CCAs > // Compile time column arguments
1986template< typename MT2 // Type of the right-hand side dense matrix
1987 , bool SO > // Storage order of the right-hand side dense matrix
1988inline void Columns<MT,true,false,SF,CCAs...>::assign( const DenseMatrix<MT2,SO>& rhs )
1989{
1992
1993 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
1994 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
1995 BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
1996
1997 for( size_t j=0UL; j<columns(); ++j )
1998 {
1999 const size_t index( idx(j) );
2000 size_t remaining( matrix_.capacity( index ) );
2001
2002 for( size_t i=0UL; i<rows(); ++i )
2003 {
2004 if( remaining == 0UL ) {
2005 matrix_.reserve( index, extendCapacity( j ) );
2006 remaining = matrix_.capacity( index ) - matrix_.nonZeros( index );
2007 }
2008
2009 matrix_.append( i, index, (*rhs)(i,j), true );
2010 --remaining;
2011 }
2012 }
2013}
2015//*************************************************************************************************
2016
2017
2018//*************************************************************************************************
2030template< typename MT // Type of the sparse matrix
2031 , bool SF // Symmetry flag
2032 , typename... CCAs > // Compile time column arguments
2033template< typename MT2 > // Type of the right-hand side sparse matrix
2034inline void Columns<MT,true,false,SF,CCAs...>::assign( const SparseMatrix<MT2,true>& rhs )
2035{
2038
2039 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2040 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2041 BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2042
2043 for( size_t j=0UL; j<columns(); ++j )
2044 {
2045 const size_t index( idx(j) );
2046 size_t remaining( matrix_.capacity( index ) );
2047
2048 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
2049 {
2050 if( remaining == 0UL ) {
2051 matrix_.reserve( index, extendCapacity( j ) );
2052 remaining = matrix_.capacity( index ) - matrix_.nonZeros( index );
2053 }
2054
2055 matrix_.append( element->index(), index, element->value(), true );
2056 --remaining;
2057 }
2058 }
2059}
2061//*************************************************************************************************
2062
2063
2064//*************************************************************************************************
2076template< typename MT // Type of the sparse matrix
2077 , bool SF // Symmetry flag
2078 , typename... CCAs > // Compile time column arguments
2079template< typename MT2 > // Type of the right-hand side sparse matrix
2080inline void Columns<MT,true,false,SF,CCAs...>::assign( const SparseMatrix<MT2,false>& rhs )
2081{
2084
2086
2087 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2088 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2089 BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2090
2091 // Counting the number of elements per column
2092 std::vector<size_t> columnLengths( columns(), 0UL );
2093 for( size_t i=0UL; i<rows(); ++i ) {
2094 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
2095 ++columnLengths[element->index()];
2096 }
2097
2098 // Resizing the sparse matrix
2099 for( size_t j=0UL; j<columns(); ++j ) {
2100 reserve( j, columnLengths[j] );
2101 }
2102
2103 // Appending the elements to the columns of the sparse column selection
2104 for( size_t i=0UL; i<rows(); ++i ) {
2105 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
2106 append( i, element->index(), element->value(), true );
2107 }
2108}
2110//*************************************************************************************************
2111
2112
2113//*************************************************************************************************
2125template< typename MT // Type of the sparse matrix
2126 , bool SF // Symmetry flag
2127 , typename... CCAs > // Compile time column arguments
2128template< typename MT2 // Type of the right-hand side matrix
2129 , bool SO > // Storage order of the right-hand side matrix
2130inline void Columns<MT,true,false,SF,CCAs...>::addAssign( const Matrix<MT2,SO>& rhs )
2131{
2134
2135 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
2136
2138
2139 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2140 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2141
2142 const AddType tmp( serial( *this + (*rhs) ) );
2143 reset();
2144 assign( tmp );
2145}
2147//*************************************************************************************************
2148
2149
2150//*************************************************************************************************
2162template< typename MT // Type of the sparse matrix
2163 , bool SF // Symmetry flag
2164 , typename... CCAs > // Compile time column arguments
2165template< typename MT2 // Type of the right-hand side matrix
2166 , bool SO > // Storage order of the right-hand side matrix
2167inline void Columns<MT,true,false,SF,CCAs...>::subAssign( const Matrix<MT2,SO>& rhs )
2168{
2171
2172 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
2173
2175
2176 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2177 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2178
2179 const SubType tmp( serial( *this - (*rhs) ) );
2180 reset();
2181 assign( tmp );
2182}
2184//*************************************************************************************************
2185
2186
2187//*************************************************************************************************
2199template< typename MT // Type of the sparse matrix
2200 , bool SF // Symmetry flag
2201 , typename... CCAs > // Compile time column arguments
2202template< typename MT2 // Type of the right-hand side matrix
2203 , bool SO > // Storage order of the right-hand side matrix
2204inline void Columns<MT,true,false,SF,CCAs...>::schurAssign( const Matrix<MT2,SO>& rhs )
2205{
2208
2209 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
2210
2213
2214 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2215 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2216
2217 const SchurType tmp( serial( *this % (*rhs) ) );
2218 reset();
2219 assign( tmp );
2220}
2222//*************************************************************************************************
2223
2224
2225
2226
2227
2228
2229
2230
2231//=================================================================================================
2232//
2233// CLASS TEMPLATE SPECIALIZATION FOR GENERAL ROW-MAJOR SPARSE MATRICES
2234//
2235//=================================================================================================
2236
2237//*************************************************************************************************
2245template< typename MT // Type of the sparse matrix
2246 , typename... CCAs > // Compile time column arguments
2247class Columns<MT,false,false,false,CCAs...>
2248 : public View< SparseMatrix< Columns<MT,false,false,false,CCAs...>, true > >
2249 , private ColumnsData<CCAs...>
2250{
2251 private:
2252 //**Type definitions****************************************************************************
2253 using DataType = ColumnsData<CCAs...>;
2254 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
2255 //**********************************************************************************************
2256
2257 //**Compile time flags**************************************************************************
2258 using DataType::N;
2259 //**********************************************************************************************
2260
2261 public:
2262 //**Type definitions****************************************************************************
2264 using This = Columns<MT,false,false,false,CCAs...>;
2265
2267 using BaseType = View< SparseMatrix<This,true> >;
2268
2269 using ViewedType = MT;
2270 using ResultType = ColumnsTrait_t<MT,N>;
2271 using OppositeType = OppositeType_t<ResultType>;
2272 using TransposeType = TransposeType_t<ResultType>;
2273 using ElementType = ElementType_t<MT>;
2274 using ReturnType = ReturnType_t<MT>;
2275 using CompositeType = const Columns&;
2276
2278 using ConstReference = ConstReference_t<MT>;
2279
2281 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
2282 //**********************************************************************************************
2283
2284 //**ColumnsElement class definition*************************************************************
2287 template< typename MatrixType // Type of the sparse matrix
2288 , typename IteratorType > // Type of the sparse matrix iterator
2289 class ColumnsElement
2290 : private SparseElement
2291 {
2292 public:
2293 //**Constructor******************************************************************************
2299 inline ColumnsElement( IteratorType pos, size_t row )
2300 : pos_( pos ) // Iterator to the current position of the sparse column element
2301 , row_( row ) // Index of the according row
2302 {}
2303 //*******************************************************************************************
2304
2305 //**Assignment operator**********************************************************************
2311 template< typename T > inline ColumnsElement& operator=( const T& v ) {
2312 *pos_ = v;
2313 return *this;
2314 }
2315 //*******************************************************************************************
2316
2317 //**Addition assignment operator*************************************************************
2323 template< typename T > inline ColumnsElement& operator+=( const T& v ) {
2324 *pos_ += v;
2325 return *this;
2326 }
2327 //*******************************************************************************************
2328
2329 //**Subtraction assignment operator**********************************************************
2335 template< typename T > inline ColumnsElement& operator-=( const T& v ) {
2336 *pos_ -= v;
2337 return *this;
2338 }
2339 //*******************************************************************************************
2340
2341 //**Multiplication assignment operator*******************************************************
2347 template< typename T > inline ColumnsElement& operator*=( const T& v ) {
2348 *pos_ *= v;
2349 return *this;
2350 }
2351 //*******************************************************************************************
2352
2353 //**Division assignment operator*************************************************************
2359 template< typename T > inline ColumnsElement& operator/=( const T& v ) {
2360 *pos_ /= v;
2361 return *this;
2362 }
2363 //*******************************************************************************************
2364
2365 //**Element access operator******************************************************************
2370 inline const ColumnsElement* operator->() const {
2371 return this;
2372 }
2373 //*******************************************************************************************
2374
2375 //**Value function***************************************************************************
2380 inline decltype(auto) value() const {
2381 return pos_->value();
2382 }
2383 //*******************************************************************************************
2384
2385 //**Index function***************************************************************************
2390 inline size_t index() const {
2391 return row_;
2392 }
2393 //*******************************************************************************************
2394
2395 private:
2396 //**Member variables*************************************************************************
2397 IteratorType pos_;
2398 size_t row_;
2399 //*******************************************************************************************
2400 };
2401 //**********************************************************************************************
2402
2403 //**ColumnsIterator class definition************************************************************
2406 template< typename MatrixType // Type of the sparse matrix
2407 , typename IteratorType > // Type of the sparse matrix iterator
2408 class ColumnsIterator
2409 {
2410 public:
2411 //**Type definitions*************************************************************************
2412 using IteratorCategory = std::forward_iterator_tag;
2413 using ValueType = ColumnsElement<MatrixType,IteratorType>;
2414 using PointerType = ValueType;
2415 using ReferenceType = ValueType;
2416 using DifferenceType = ptrdiff_t;
2417
2418 // STL iterator requirements
2419 using iterator_category = IteratorCategory;
2420 using value_type = ValueType;
2421 using pointer = PointerType;
2422 using reference = ReferenceType;
2423 using difference_type = DifferenceType;
2424 //*******************************************************************************************
2425
2426 //**Constructor******************************************************************************
2429 inline ColumnsIterator()
2430 : matrix_( nullptr ) // The sparse matrix containing the selected column
2431 , row_ ( 0UL ) // The current row index
2432 , column_( 0UL ) // The current column index
2433 , pos_ () // Iterator to the current sparse element
2434 {}
2435 //*******************************************************************************************
2436
2437 //**Constructor******************************************************************************
2444 inline ColumnsIterator( MatrixType& matrix, size_t row, size_t column )
2445 : matrix_( &matrix ) // The sparse matrix containing the selected column
2446 , row_ ( row ) // The current row index
2447 , column_( column ) // The current column index
2448 , pos_ () // Iterator to the current sparse element
2449 {
2450 for( ; row_<matrix_->rows(); ++row_ ) {
2451 pos_ = matrix_->find( row_, column_ );
2452 if( pos_ != matrix_->end( row_ ) ) break;
2453 }
2454 }
2455 //*******************************************************************************************
2456
2457 //**Constructor******************************************************************************
2465 inline ColumnsIterator( MatrixType& matrix, size_t row, size_t column, IteratorType pos )
2466 : matrix_( &matrix ) // The sparse matrix containing the selected column
2467 , row_ ( row ) // The current row index
2468 , column_( column ) // The current column index
2469 , pos_ ( pos ) // Iterator to the current sparse element
2470 {
2471 BLAZE_INTERNAL_ASSERT( matrix.find( row, column ) == pos, "Invalid initial iterator position" );
2472 }
2473 //*******************************************************************************************
2474
2475 //**Constructor******************************************************************************
2480 template< typename MatrixType2, typename IteratorType2 >
2481 inline ColumnsIterator( const ColumnsIterator<MatrixType2,IteratorType2>& it )
2482 : matrix_( it.matrix_ ) // The sparse matrix containing the selected column
2483 , row_ ( it.row_ ) // The current row index
2484 , column_( it.column_ ) // The current column index
2485 , pos_ ( it.pos_ ) // Iterator to the current sparse element
2486 {}
2487 //*******************************************************************************************
2488
2489 //**Prefix increment operator****************************************************************
2494 inline ColumnsIterator& operator++() {
2495 ++row_;
2496 for( ; row_<matrix_->rows(); ++row_ ) {
2497 pos_ = matrix_->find( row_, column_ );
2498 if( pos_ != matrix_->end( row_ ) ) break;
2499 }
2500
2501 return *this;
2502 }
2503 //*******************************************************************************************
2504
2505 //**Postfix increment operator***************************************************************
2510 inline const ColumnsIterator operator++( int ) {
2511 const ColumnsIterator tmp( *this );
2512 ++(*this);
2513 return tmp;
2514 }
2515 //*******************************************************************************************
2516
2517 //**Element access operator******************************************************************
2522 inline ReferenceType operator*() const {
2523 return ReferenceType( pos_, row_ );
2524 }
2525 //*******************************************************************************************
2526
2527 //**Element access operator******************************************************************
2532 inline PointerType operator->() const {
2533 return PointerType( pos_, row_ );
2534 }
2535 //*******************************************************************************************
2536
2537 //**Equality operator************************************************************************
2543 template< typename MatrixType2, typename IteratorType2 >
2544 inline bool operator==( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2545 return row_ == rhs.row_;
2546 }
2547 //*******************************************************************************************
2548
2549 //**Inequality operator**********************************************************************
2555 template< typename MatrixType2, typename IteratorType2 >
2556 inline bool operator!=( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2557 return !( *this == rhs );
2558 }
2559 //*******************************************************************************************
2560
2561 //**Subtraction operator*********************************************************************
2567 inline DifferenceType operator-( const ColumnsIterator& rhs ) const {
2568 size_t counter( 0UL );
2569 for( size_t i=rhs.row_; i<row_; ++i ) {
2570 if( matrix_->find( i, column_ ) != matrix_->end( i ) )
2571 ++counter;
2572 }
2573 return counter;
2574 }
2575 //*******************************************************************************************
2576
2577 private:
2578 //**Member variables*************************************************************************
2579 MatrixType* matrix_;
2580 size_t row_;
2581 size_t column_;
2582 IteratorType pos_;
2583 //*******************************************************************************************
2584
2585 //**Friend declarations**********************************************************************
2586 template< typename MatrixType2, typename IteratorType2 > friend class ColumnsIterator;
2587 template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CCAs2 > friend class Columns;
2588 //*******************************************************************************************
2589 };
2590 //**********************************************************************************************
2591
2592 //**Type definitions****************************************************************************
2594 using ConstIterator = ColumnsIterator< const MT, ConstIterator_t<MT> >;
2595
2597 using Iterator = If_t< IsConst_v<MT>, ConstIterator, ColumnsIterator< MT, Iterator_t<MT> > >;
2598 //**********************************************************************************************
2599
2600 //**Compilation flags***************************************************************************
2602 static constexpr bool smpAssignable = MT::smpAssignable;
2603
2605 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
2606 //**********************************************************************************************
2607
2608 //**Constructors********************************************************************************
2611 template< typename... RCAs >
2612 explicit inline Columns( MT& matrix, RCAs... args );
2613
2614 Columns( const Columns& ) = default;
2615 Columns( Columns&& ) = default;
2617 //**********************************************************************************************
2618
2619 //**Destructor**********************************************************************************
2622 ~Columns() = default;
2624 //**********************************************************************************************
2625
2626 //**Data access functions***********************************************************************
2629 inline Reference operator()( size_t i, size_t j );
2630 inline ConstReference operator()( size_t i, size_t j ) const;
2631 inline Reference at( size_t i, size_t j );
2632 inline ConstReference at( size_t i, size_t j ) const;
2633 inline Iterator begin ( size_t j );
2634 inline ConstIterator begin ( size_t j ) const;
2635 inline ConstIterator cbegin( size_t j ) const;
2636 inline Iterator end ( size_t j );
2637 inline ConstIterator end ( size_t j ) const;
2638 inline ConstIterator cend ( size_t j ) const;
2640 //**********************************************************************************************
2641
2642 //**Assignment operators************************************************************************
2645 inline Columns& operator=( initializer_list< initializer_list<ElementType> > list );
2646 inline Columns& operator=( const Columns& rhs );
2647
2648 template< typename MT2, bool SO > inline Columns& operator= ( const Matrix<MT2,SO>& rhs );
2649 template< typename MT2, bool SO > inline Columns& operator+=( const Matrix<MT2,SO>& rhs );
2650 template< typename MT2, bool SO > inline Columns& operator-=( const Matrix<MT2,SO>& rhs );
2651 template< typename MT2, bool SO > inline Columns& operator%=( const Matrix<MT2,SO>& rhs );
2653 //**********************************************************************************************
2654
2655 //**Utility functions***************************************************************************
2658 using DataType::idx;
2659 using DataType::idces;
2660 using DataType::columns;
2661
2662 inline MT& operand() noexcept;
2663 inline const MT& operand() const noexcept;
2664
2665 inline size_t rows() const noexcept;
2666 inline size_t capacity() const noexcept;
2667 inline size_t capacity( size_t j ) const noexcept;
2668 inline size_t nonZeros() const;
2669 inline size_t nonZeros( size_t j ) const;
2670 inline void reset();
2671 inline void reset( size_t j );
2672 inline void reserve( size_t nonzeros );
2673 void reserve( size_t j, size_t nonzeros );
2674 inline void trim();
2675 inline void trim( size_t j );
2677 //**********************************************************************************************
2678
2679 //**Insertion functions*************************************************************************
2682 inline Iterator set ( size_t i, size_t j, const ElementType& value );
2683 inline Iterator insert ( size_t i, size_t j, const ElementType& value );
2684 inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
2685 inline void finalize( size_t j );
2687 //**********************************************************************************************
2688
2689 //**Erase functions*****************************************************************************
2692 inline void erase( size_t i, size_t j );
2693 inline Iterator erase( size_t j, Iterator pos );
2694 inline Iterator erase( size_t j, Iterator first, Iterator last );
2695
2696 template< typename Pred >
2697 inline void erase( Pred predicate );
2698
2699 template< typename Pred >
2700 inline void erase( size_t j, Iterator first, Iterator last, Pred predicate );
2702 //**********************************************************************************************
2703
2704 //**Lookup functions****************************************************************************
2707 inline Iterator find ( size_t i, size_t j );
2708 inline ConstIterator find ( size_t i, size_t j ) const;
2709 inline Iterator lowerBound( size_t i, size_t j );
2710 inline ConstIterator lowerBound( size_t i, size_t j ) const;
2711 inline Iterator upperBound( size_t i, size_t j );
2712 inline ConstIterator upperBound( size_t i, size_t j ) const;
2714 //**********************************************************************************************
2715
2716 //**Numeric functions***************************************************************************
2719 inline Columns& transpose();
2720 inline Columns& ctranspose();
2721
2722 template< typename Other > inline Columns& scale( const Other& scalar );
2724 //**********************************************************************************************
2725
2726 //**Expression template evaluation functions****************************************************
2729 template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
2730 template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
2731
2732 inline bool canSMPAssign() const noexcept;
2733
2734 template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
2735 template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
2736 template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
2737 template< typename MT2, bool SO > inline void addAssign ( const Matrix<MT2,SO>& rhs );
2738 template< typename MT2, bool SO > inline void subAssign ( const Matrix<MT2,SO>& rhs );
2739 template< typename MT2, bool SO > inline void schurAssign( const Matrix<MT2,SO>& rhs );
2741 //**********************************************************************************************
2742
2743 private:
2744 //**Member variables****************************************************************************
2747 Operand matrix_;
2749 //**********************************************************************************************
2750
2751 //**Compile time checks*************************************************************************
2761 //**********************************************************************************************
2762};
2764//*************************************************************************************************
2765
2766
2767
2768
2769//=================================================================================================
2770//
2771// CONSTRUCTORS
2772//
2773//=================================================================================================
2774
2775//*************************************************************************************************
2788template< typename MT // Type of the sparse matrix
2789 , typename... CCAs > // Compile time column arguments
2790template< typename... RCAs > // Runtime column arguments
2791inline Columns<MT,false,false,false,CCAs...>::Columns( MT& matrix, RCAs... args )
2792 : DataType( args... ) // Base class initialization
2793 , matrix_ ( matrix ) // The matrix containing the columns
2794{
2795 if( isChecked( args... ) ) {
2796 for( size_t j=0UL; j<columns(); ++j ) {
2797 if( matrix_.columns() <= idx(j) ) {
2798 BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2799 }
2800 }
2801 }
2802}
2804//*************************************************************************************************
2805
2806
2807
2808
2809//=================================================================================================
2810//
2811// DATA ACCESS FUNCTIONS
2812//
2813//=================================================================================================
2814
2815//*************************************************************************************************
2826template< typename MT // Type of the sparse matrix
2827 , typename... CCAs > // Compile time column arguments
2828inline typename Columns<MT,false,false,false,CCAs...>::Reference
2829 Columns<MT,false,false,false,CCAs...>::operator()( size_t i, size_t j )
2830{
2831 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2832 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2833
2834 return matrix_(i,idx(j));
2835}
2837//*************************************************************************************************
2838
2839
2840//*************************************************************************************************
2851template< typename MT // Type of the sparse matrix
2852 , typename... CCAs > // Compile time column arguments
2853inline typename Columns<MT,false,false,false,CCAs...>::ConstReference
2854 Columns<MT,false,false,false,CCAs...>::operator()( size_t i, size_t j ) const
2855{
2856 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2857 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2858
2859 return const_cast<const MT&>( matrix_ )(i,idx(j));
2860}
2862//*************************************************************************************************
2863
2864
2865//*************************************************************************************************
2877template< typename MT // Type of the sparse matrix
2878 , typename... CCAs > // Compile time column arguments
2879inline typename Columns<MT,false,false,false,CCAs...>::Reference
2880 Columns<MT,false,false,false,CCAs...>::at( size_t i, size_t j )
2881{
2882 if( i >= rows() ) {
2883 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
2884 }
2885 if( j >= columns() ) {
2886 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
2887 }
2888 return (*this)(i,j);
2889}
2891//*************************************************************************************************
2892
2893
2894//*************************************************************************************************
2906template< typename MT // Type of the sparse matrix
2907 , typename... CCAs > // Compile time column arguments
2908inline typename Columns<MT,false,false,false,CCAs...>::ConstReference
2909 Columns<MT,false,false,false,CCAs...>::at( size_t i, size_t j ) const
2910{
2911 if( i >= rows() ) {
2912 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
2913 }
2914 if( j >= columns() ) {
2915 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
2916 }
2917 return (*this)(i,j);
2918}
2920//*************************************************************************************************
2921
2922
2923//*************************************************************************************************
2932template< typename MT // Type of the sparse matrix
2933 , typename... CCAs > // Compile time column arguments
2934inline typename Columns<MT,false,false,false,CCAs...>::Iterator
2936{
2937 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2938
2939 return Iterator( matrix_, 0UL, idx(j) );
2940}
2942//*************************************************************************************************
2943
2944
2945//*************************************************************************************************
2954template< typename MT // Type of the sparse matrix
2955 , typename... CCAs > // Compile time column arguments
2956inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
2958{
2959 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2960
2961 return ConstIterator( matrix_, 0UL, idx(j) );
2962}
2964//*************************************************************************************************
2965
2966
2967//*************************************************************************************************
2976template< typename MT // Type of the sparse matrix
2977 , typename... CCAs > // Compile time column arguments
2978inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
2980{
2981 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2982
2983 return ConstIterator( matrix_, 0UL, idx(j) );
2984}
2986//*************************************************************************************************
2987
2988
2989//*************************************************************************************************
2998template< typename MT // Type of the sparse matrix
2999 , typename... CCAs > // Compile time column arguments
3000inline typename Columns<MT,false,false,false,CCAs...>::Iterator
3002{
3003 BLAZE_USER_ASSERT( j < columns(), "Invalid row access index" );
3004
3005 return Iterator( matrix_, rows(), idx(j) );
3006}
3008//*************************************************************************************************
3009
3010
3011//*************************************************************************************************
3020template< typename MT // Type of the sparse matrix
3021 , typename... CCAs > // Compile time column arguments
3022inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
3024{
3025 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3026
3027 return ConstIterator( matrix_, rows(), idx(j) );
3028}
3030//*************************************************************************************************
3031
3032
3033//*************************************************************************************************
3042template< typename MT // Type of the sparse matrix
3043 , typename... CCAs > // Compile time column arguments
3044inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
3046{
3047 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3048
3049 return ConstIterator( matrix_, rows(), idx(j) );
3050}
3052//*************************************************************************************************
3053
3054
3055
3056
3057//=================================================================================================
3058//
3059// ASSIGNMENT OPERATORS
3060//
3061//=================================================================================================
3062
3063//*************************************************************************************************
3079template< typename MT // Type of the sparse matrix
3080 , typename... CCAs > // Compile time column arguments
3081inline Columns<MT,false,false,false,CCAs...>&
3082 Columns<MT,false,false,false,CCAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
3083{
3086
3087 if( list.size() != rows() ) {
3088 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column selection" );
3089 }
3090
3091 const InitializerMatrix<ElementType> tmp( list, columns() );
3092
3093 if( IsRestricted_v<MT> ) {
3094 for( size_t j=0UL; j<columns(); ++j ) {
3095 if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, j ) ) {
3096 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3097 }
3098 }
3099 }
3100
3101 decltype(auto) left( derestrict( *this ) );
3102
3103 smpAssign( left, tmp );
3104
3105 return *this;
3106}
3108//*************************************************************************************************
3109
3110
3111//*************************************************************************************************
3126template< typename MT // Type of the sparse matrix
3127 , typename... CCAs > // Compile time column arguments
3128inline Columns<MT,false,false,false,CCAs...>&
3129 Columns<MT,false,false,false,CCAs...>::operator=( const Columns& rhs )
3130{
3133
3136
3137 if( this == &rhs || ( &matrix_ == &rhs.matrix_ && compareIndices( *this, rhs ) ) )
3138 return *this;
3139
3140 if( rows() != rhs.rows() || columns() != rhs.columns() ) {
3141 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3142 }
3143
3144 if( IsRestricted_v<MT> ) {
3145 for( size_t j=0UL; j<columns(); ++j ) {
3146 if( !tryAssign( matrix_, column( rhs, j, unchecked ), 0UL, idx(j) ) ) {
3147 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3148 }
3149 }
3150 }
3151
3152 decltype(auto) left( derestrict( *this ) );
3153
3154 if( rhs.canAlias( this ) ) {
3155 const ResultType tmp( rhs );
3156 left.reset();
3157 smpAssign( left, tmp );
3158 }
3159 else {
3160 left.reset();
3161 smpAssign( left, rhs );
3162 }
3163
3164 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3165
3166 return *this;
3167}
3169//*************************************************************************************************
3170
3171
3172//*************************************************************************************************
3187template< typename MT // Type of the sparse matrix
3188 , typename... CCAs > // Compile time column arguments
3189template< typename MT2 // Type of the right-hand side matrix
3190 , bool SO > // Storage order of the right-hand side matrix
3191inline Columns<MT,false,false,false,CCAs...>&
3192 Columns<MT,false,false,false,CCAs...>::operator=( const Matrix<MT2,SO>& rhs )
3193{
3196
3198
3199 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
3200 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3201 }
3202
3203 using Right = CompositeType_t<MT2>;
3204 Right right( *rhs );
3205
3206 if( IsRestricted_v<MT> ) {
3207 for( size_t j=0UL; j<columns(); ++j ) {
3208 if( !tryAssign( matrix_, column( right, j, unchecked ), 0UL, idx(j) ) ) {
3209 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3210 }
3211 }
3212 }
3213
3214 decltype(auto) left( derestrict( *this ) );
3215
3216 if( IsReference_v<Right> && right.canAlias( this ) ) {
3217 const ResultType_t<MT2> tmp( right );
3218 if( IsSparseMatrix_v< ResultType_t<MT2> > )
3219 left.reset();
3220 smpAssign( left, tmp );
3221 }
3222 else {
3223 if( IsSparseMatrix_v<MT2> )
3224 left.reset();
3225 smpAssign( left, right );
3226 }
3227
3228 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3229
3230 return *this;
3231}
3233//*************************************************************************************************
3234
3235
3236//*************************************************************************************************
3250template< typename MT // Type of the sparse matrix
3251 , typename... CCAs > // Compile time column arguments
3252template< typename MT2 // Type of the right-hand side matrix
3253 , bool SO > // Storage order of the right-hand side matrix
3254inline Columns<MT,false,false,false,CCAs...>&
3255 Columns<MT,false,false,false,CCAs...>::operator+=( const Matrix<MT2,SO>& rhs )
3256{
3259
3263
3264 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
3265
3267
3268 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
3269 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3270 }
3271
3272 const AddType tmp( *this + (*rhs) );
3273
3274 if( IsRestricted_v<MT> ) {
3275 for( size_t j=0UL; j<columns(); ++j ) {
3276 if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
3277 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3278 }
3279 }
3280 }
3281
3282 decltype(auto) left( derestrict( *this ) );
3283
3284 if( IsSparseMatrix_v<AddType> ) {
3285 left.reset();
3286 }
3287
3288 smpAssign( left, tmp );
3289
3290 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3291
3292 return *this;
3293}
3295//*************************************************************************************************
3296
3297
3298//*************************************************************************************************
3312template< typename MT // Type of the sparse matrix
3313 , typename... CCAs > // Compile time column arguments
3314template< typename MT2 // Type of the right-hand side matrix
3315 , bool SO > // Storage order of the right-hand side matrix
3316inline Columns<MT,false,false,false,CCAs...>&
3317 Columns<MT,false,false,false,CCAs...>::operator-=( const Matrix<MT2,SO>& rhs )
3318{
3321
3325
3326 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
3327
3329
3330 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
3331 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3332 }
3333
3334 const SubType tmp( *this - (*rhs) );
3335
3336 if( IsRestricted_v<MT> ) {
3337 for( size_t j=0UL; j<columns(); ++j ) {
3338 if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
3339 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3340 }
3341 }
3342 }
3343
3344 decltype(auto) left( derestrict( *this ) );
3345
3346 if( IsSparseMatrix_v<SubType> ) {
3347 left.reset();
3348 }
3349
3350 smpAssign( left, tmp );
3351
3352 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3353
3354 return *this;
3355}
3357//*************************************************************************************************
3358
3359
3360//*************************************************************************************************
3374template< typename MT // Type of the sparse matrix
3375 , typename... CCAs > // Compile time column arguments
3376template< typename MT2 // Type of the right-hand side matrix
3377 , bool SO > // Storage order of the right-hand side matrix
3378inline Columns<MT,false,false,false,CCAs...>&
3379 Columns<MT,false,false,false,CCAs...>::operator%=( const Matrix<MT2,SO>& rhs )
3380{
3383
3387
3388 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
3389
3391
3392 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
3393 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3394 }
3395
3396 const SchurType tmp( *this % (*rhs) );
3397
3398 if( IsRestricted_v<MT> ) {
3399 for( size_t j=0UL; j<columns(); ++j ) {
3400 if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
3401 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3402 }
3403 }
3404 }
3405
3406 decltype(auto) left( derestrict( *this ) );
3407
3408 if( IsSparseMatrix_v<SchurType> ) {
3409 left.reset();
3410 }
3411
3412 smpAssign( left, tmp );
3413
3414 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3415
3416 return *this;
3417}
3419//*************************************************************************************************
3420
3421
3422
3423
3424//=================================================================================================
3425//
3426// UTILITY FUNCTIONS
3427//
3428//=================================================================================================
3429
3430//*************************************************************************************************
3436template< typename MT // Type of the sparse matrix
3437 , typename... CCAs > // Compile time column arguments
3438inline MT& Columns<MT,false,false,false,CCAs...>::operand() noexcept
3439{
3440 return matrix_;
3441}
3443//*************************************************************************************************
3444
3445
3446//*************************************************************************************************
3452template< typename MT // Type of the sparse matrix
3453 , typename... CCAs > // Compile time column arguments
3454inline const MT& Columns<MT,false,false,false,CCAs...>::operand() const noexcept
3455{
3456 return matrix_;
3457}
3459//*************************************************************************************************
3460
3461
3462//*************************************************************************************************
3468template< typename MT // Type of the sparse matrix
3469 , typename... CCAs > // Compile time column arguments
3470inline size_t Columns<MT,false,false,false,CCAs...>::rows() const noexcept
3471{
3472 return matrix_.rows();
3473}
3475//*************************************************************************************************
3476
3477
3478//*************************************************************************************************
3484template< typename MT // Type of the sparse matrix
3485 , typename... CCAs > // Compile time column arguments
3486inline size_t Columns<MT,false,false,false,CCAs...>::capacity() const noexcept
3487{
3488 return rows() * columns();
3489}
3491//*************************************************************************************************
3492
3493
3494//*************************************************************************************************
3503template< typename MT // Type of the sparse matrix
3504 , typename... CCAs > // Compile time column arguments
3505inline size_t Columns<MT,false,false,false,CCAs...>::capacity( size_t j ) const noexcept
3506{
3507 MAYBE_UNUSED( j );
3508
3509 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3510
3511 return rows();
3512}
3514//*************************************************************************************************
3515
3516
3517//*************************************************************************************************
3523template< typename MT // Type of the sparse matrix
3524 , typename... CCAs > // Compile time column arguments
3526{
3527 size_t nonzeros( 0UL );
3528
3529 for( size_t i=0UL; i<rows(); ++i ) {
3530 const auto end( matrix_.end( i ) );
3531 for( size_t j=0UL; j<columns(); ++j ) {
3532 auto pos = matrix_.find( i, idx(j) );
3533 if( pos != end ) {
3534 ++nonzeros;
3535 }
3536 }
3537 }
3538
3539 return nonzeros;
3540}
3542//*************************************************************************************************
3543
3544
3545//*************************************************************************************************
3554template< typename MT // Type of the sparse matrix
3555 , typename... CCAs > // Compile time column arguments
3556inline size_t Columns<MT,false,false,false,CCAs...>::nonZeros( size_t j ) const
3557{
3558 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3559
3560 size_t counter( 0UL );
3561
3562 const ConstIterator last( end(j) );
3563 for( ConstIterator element=begin(j); element!=last; ++element ) {
3564 ++counter;
3565 }
3566
3567 return counter;
3568}
3570//*************************************************************************************************
3571
3572
3573//*************************************************************************************************
3579template< typename MT // Type of the sparse matrix
3580 , typename... CCAs > // Compile time column arguments
3582{
3583 for( size_t j=0UL; j<columns(); ++j ) {
3584 reset( j );
3585 }
3586}
3588//*************************************************************************************************
3589
3590
3591//*************************************************************************************************
3601template< typename MT // Type of the sparse matrix
3602 , typename... CCAs > // Compile time column arguments
3604{
3605 const size_t index( idx(j) );
3606
3607 const size_t ibegin( ( IsLower_v<MT> )
3608 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
3609 ?( index+1UL )
3610 :( index ) )
3611 :( 0UL ) );
3612 const size_t iend ( ( IsUpper_v<MT> )
3613 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
3614 ?( index )
3615 :( index+1UL ) )
3616 :( rows() ) );
3617
3618 for( size_t i=ibegin; i<iend; ++i ) {
3619 matrix_.erase( i, index );
3620 }
3621}
3623//*************************************************************************************************
3624
3625
3626//*************************************************************************************************
3637template< typename MT // Type of the sparse matrix
3638 , typename... CCAs > // Compile time column arguments
3639inline void Columns<MT,false,false,false,CCAs...>::reserve( size_t nonzeros )
3640{
3641 MAYBE_UNUSED( nonzeros );
3642
3643 return;
3644}
3646//*************************************************************************************************
3647
3648
3649//*************************************************************************************************
3662template< typename MT // Type of the sparse matrix
3663 , typename... CCAs > // Compile time column arguments
3664void Columns<MT,false,false,false,CCAs...>::reserve( size_t j, size_t nonzeros )
3665{
3666 MAYBE_UNUSED( j, nonzeros );
3667
3668 return;
3669}
3671//*************************************************************************************************
3672
3673
3674//*************************************************************************************************
3684template< typename MT // Type of the sparse matrix
3685 , typename... CCAs > // Compile time column arguments
3686void Columns<MT,false,false,false,CCAs...>::trim()
3687{
3688 return;
3689}
3691//*************************************************************************************************
3692
3693
3694//*************************************************************************************************
3705template< typename MT // Type of the sparse matrix
3706 , typename... CCAs > // Compile time column arguments
3707void Columns<MT,false,false,false,CCAs...>::trim( size_t j )
3708{
3709 MAYBE_UNUSED( j );
3710
3711 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3712
3713 return;
3714}
3716//*************************************************************************************************
3717
3718
3719
3720
3721//=================================================================================================
3722//
3723// INSERTION FUNCTIONS
3724//
3725//=================================================================================================
3726
3727//*************************************************************************************************
3740template< typename MT // Type of the sparse matrix
3741 , typename... CCAs > // Compile time column arguments
3742inline typename Columns<MT,false,false,false,CCAs...>::Iterator
3743 Columns<MT,false,false,false,CCAs...>::set( size_t i, size_t j, const ElementType& value )
3744{
3745 return Iterator( matrix_, i, idx(j), matrix_.set( i, idx(j), value ) );
3746}
3748//*************************************************************************************************
3749
3750
3751//*************************************************************************************************
3765template< typename MT // Type of the sparse matrix
3766 , typename... CCAs > // Compile time column arguments
3767inline typename Columns<MT,false,false,false,CCAs...>::Iterator
3768 Columns<MT,false,false,false,CCAs...>::insert( size_t i, size_t j, const ElementType& value )
3769{
3770 return Iterator( matrix_, i, idx(j), matrix_.insert( i, idx(j), value ) );
3771}
3773//*************************************************************************************************
3774
3775
3776//*************************************************************************************************
3820template< typename MT // Type of the sparse matrix
3821 , typename... CCAs > // Compile time column arguments
3822inline void Columns<MT,false,false,false,CCAs...>::append( size_t i, size_t j, const ElementType& value, bool check )
3823{
3824 if( !check || !isDefault<strict>( value ) )
3825 matrix_.insert( i, idx(j), value );
3826}
3828//*************************************************************************************************
3829
3830
3831//*************************************************************************************************
3845template< typename MT // Type of the sparse matrix
3846 , typename... CCAs > // Compile time column arguments
3847inline void Columns<MT,false,false,false,CCAs...>::finalize( size_t j )
3848{
3849 MAYBE_UNUSED( j );
3850
3851 return;
3852}
3854//*************************************************************************************************
3855
3856
3857
3858
3859//=================================================================================================
3860//
3861// ERASE FUNCTIONS
3862//
3863//=================================================================================================
3864
3865//*************************************************************************************************
3875template< typename MT // Type of the sparse matrix
3876 , typename... CCAs > // Compile time column arguments
3877inline void Columns<MT,false,false,false,CCAs...>::erase( size_t i, size_t j )
3878{
3879 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3880 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3881
3882 matrix_.erase( i, idx(j) );
3883}
3885//*************************************************************************************************
3886
3887
3888//*************************************************************************************************
3898template< typename MT // Type of the sparse matrix
3899 , typename... CCAs > // Compile time column arguments
3900inline typename Columns<MT,false,false,false,CCAs...>::Iterator
3901 Columns<MT,false,false,false,CCAs...>::erase( size_t j, Iterator pos )
3902{
3903 const size_t row( pos.row_ );
3904
3905 if( row == rows() )
3906 return pos;
3907
3908 matrix_.erase( row, pos.pos_ );
3909 return Iterator( matrix_, row+1UL, idx(j) );
3910}
3912//*************************************************************************************************
3913
3914
3915//*************************************************************************************************
3926template< typename MT // Type of the sparse matrix
3927 , typename... CCAs > // Compile time column arguments
3928inline typename Columns<MT,false,false,false,CCAs...>::Iterator
3929 Columns<MT,false,false,false,CCAs...>::erase( size_t j, Iterator first, Iterator last )
3930{
3931 MAYBE_UNUSED( j );
3932
3933 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3934
3935 for( ; first!=last; ++first ) {
3936 matrix_.erase( first.row_, first.pos_ );
3937 }
3938
3939 return last;
3940}
3942//*************************************************************************************************
3943
3944
3945//*************************************************************************************************
3968template< typename MT // Type of the sparse matrix
3969 , typename... CCAs > // Compile time column arguments
3970template< typename Pred > // Type of the unary predicate
3971inline void Columns<MT,false,false,false,CCAs...>::erase( Pred predicate )
3972{
3973 for( size_t j=0UL; j<columns(); ++j ) {
3974 for( Iterator element=begin(j); element!=end(j); ++element ) {
3975 if( predicate( element->value() ) )
3976 matrix_.erase( element.row_, element.pos_ );
3977 }
3978 }
3979}
3981//*************************************************************************************************
3982
3983
3984//*************************************************************************************************
4011template< typename MT // Type of the sparse matrix
4012 , typename... CCAs > // Compile time column arguments
4013template< typename Pred > // Type of the unary predicate
4014inline void Columns<MT,false,false,false,CCAs...>::erase( size_t j, Iterator first, Iterator last, Pred predicate )
4015{
4016 MAYBE_UNUSED( j );
4017
4018 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4019
4020 for( ; first!=last; ++first ) {
4021 if( predicate( first->value() ) )
4022 matrix_.erase( first.row_, first.pos_ );
4023 }
4024}
4026//*************************************************************************************************
4027
4028
4029
4030
4031//=================================================================================================
4032//
4033// LOOKUP FUNCTIONS
4034//
4035//=================================================================================================
4036
4037//*************************************************************************************************
4052template< typename MT // Type of the sparse matrix
4053 , typename... CCAs > // Compile time column arguments
4054inline typename Columns<MT,false,false,false,CCAs...>::Iterator
4056{
4057 const size_t index( idx(j) );
4058 const Iterator_t<MT> pos( matrix_.find( i, index ) );
4059
4060 if( pos != matrix_.end( i ) )
4061 return Iterator( matrix_, i, index, pos );
4062 else
4063 return end( j );
4064}
4066//*************************************************************************************************
4067
4068
4069//*************************************************************************************************
4084template< typename MT // Type of the sparse matrix
4085 , typename... CCAs > // Compile time column arguments
4086inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
4087 Columns<MT,false,false,false,CCAs...>::find( size_t i, size_t j ) const
4088{
4089 const size_t index( idx(j) );
4090 const ConstIterator_t<MT> pos( matrix_.find( i, index ) );
4091
4092 if( pos != matrix_.end( i ) )
4093 return ConstIterator( matrix_, i, index, pos );
4094 else
4095 return end( j );
4096}
4098//*************************************************************************************************
4099
4100
4101//*************************************************************************************************
4115template< typename MT // Type of the sparse matrix
4116 , typename... CCAs > // Compile time column arguments
4117inline typename Columns<MT,false,false,false,CCAs...>::Iterator
4119{
4120 const size_t index( idx(j) );
4121
4122 for( ; i<rows(); ++i )
4123 {
4124 const Iterator_t<MT> pos( matrix_.find( i, index ) );
4125
4126 if( pos != matrix_.end( i ) )
4127 return Iterator( matrix_, i, index, pos );
4128 }
4129
4130 return end( j );
4131}
4133//*************************************************************************************************
4134
4135
4136//*************************************************************************************************
4150template< typename MT // Type of the sparse matrix
4151 , typename... CCAs > // Compile time column arguments
4152inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
4153 Columns<MT,false,false,false,CCAs...>::lowerBound( size_t i, size_t j ) const
4154{
4155 const size_t index( idx(j) );
4156
4157 for( ; i<rows(); ++i )
4158 {
4159 const ConstIterator_t<MT> pos( matrix_.find( i, index ) );
4160
4161 if( pos != matrix_.end( i ) )
4162 return ConstIterator( matrix_, i, index, pos );
4163 }
4164
4165 return end( j );
4166}
4168//*************************************************************************************************
4169
4170
4171//*************************************************************************************************
4185template< typename MT // Type of the sparse matrix
4186 , typename... CCAs > // Compile time column arguments
4187inline typename Columns<MT,false,false,false,CCAs...>::Iterator
4189{
4190 return lowerBound( i+1UL, j );
4191}
4193//*************************************************************************************************
4194
4195
4196//*************************************************************************************************
4210template< typename MT // Type of the sparse matrix
4211 , typename... CCAs > // Compile time column arguments
4212inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
4213 Columns<MT,false,false,false,CCAs...>::upperBound( size_t i, size_t j ) const
4214{
4215 return lowerBound( i+1UL, j );
4216}
4218//*************************************************************************************************
4219
4220
4221
4222
4223//=================================================================================================
4224//
4225// NUMERIC FUNCTIONS
4226//
4227//=================================================================================================
4228
4229//*************************************************************************************************
4242template< typename MT // Type of the sparse matrix
4243 , typename... CCAs > // Compile time column arguments
4244inline Columns<MT,false,false,false,CCAs...>&
4246{
4249
4250 if( rows() != columns() ) {
4251 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4252 }
4253
4254 const ResultType tmp( trans( *this ) );
4255
4256 if( IsRestricted_v<MT> ) {
4257 for( size_t j=0UL; j<columns(); ++j ) {
4258 if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
4259 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4260 }
4261 }
4262 }
4263
4264 decltype(auto) left( derestrict( *this ) );
4265
4266 left.reset();
4267 smpAssign( left, tmp );
4268
4269 return *this;
4270}
4272//*************************************************************************************************
4273
4274
4275//*************************************************************************************************
4288template< typename MT // Type of the sparse matrix
4289 , typename... CCAs > // Compile time column arguments
4290inline Columns<MT,false,false,false,CCAs...>&
4292{
4295
4296 if( rows() != columns() ) {
4297 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4298 }
4299
4300 const ResultType tmp( ctrans( *this ) );
4301
4302 if( IsRestricted_v<MT> ) {
4303 for( size_t j=0UL; j<columns(); ++j ) {
4304 if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
4305 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4306 }
4307 }
4308 }
4309
4310 decltype(auto) left( derestrict( *this ) );
4311
4312 left.reset();
4313 smpAssign( left, tmp );
4314
4315 return *this;
4316}
4318//*************************************************************************************************
4319
4320
4321//*************************************************************************************************
4334template< typename MT // Type of the sparse matrix
4335 , typename... CCAs > // Compile time column arguments
4336template< typename Other > // Data type of the scalar value
4337inline Columns<MT,false,false,false,CCAs...>&
4338 Columns<MT,false,false,false,CCAs...>::scale( const Other& scalar )
4339{
4343
4344 for( size_t i=0UL; i<rows(); ++i ) {
4345 const auto end( matrix_.end( i ) );
4346 for( size_t j=0UL; j<columns(); ++j ) {
4347 auto pos = matrix_.find( i, idx(j) );
4348 if( pos != end ) {
4349 pos->value() *= scalar;
4350 }
4351 }
4352 }
4353
4354 return *this;
4355}
4357//*************************************************************************************************
4358
4359
4360
4361
4362//=================================================================================================
4363//
4364// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4365//
4366//=================================================================================================
4367
4368//*************************************************************************************************
4379template< typename MT // Type of the sparse matrix
4380 , typename... CCAs > // Compile time column arguments
4381template< typename Other > // Data type of the foreign expression
4382inline bool Columns<MT,false,false,false,CCAs...>::canAlias( const Other* alias ) const noexcept
4383{
4384 return matrix_.isAliased( &unview( *alias ) );
4385}
4387//*************************************************************************************************
4388
4389
4390//*************************************************************************************************
4401template< typename MT // Type of the sparse matrix
4402 , typename... CCAs > // Compile time column arguments
4403template< typename Other > // Data type of the foreign expression
4404inline bool Columns<MT,false,false,false,CCAs...>::isAliased( const Other* alias ) const noexcept
4405{
4406 return matrix_.isAliased( &unview( *alias ) );
4407}
4409//*************************************************************************************************
4410
4411
4412//*************************************************************************************************
4423template< typename MT // Type of the sparse matrix
4424 , typename... CCAs > // Compile time column arguments
4425inline bool Columns<MT,false,false,false,CCAs...>::canSMPAssign() const noexcept
4426{
4427 return false;
4428}
4430//*************************************************************************************************
4431
4432
4433//*************************************************************************************************
4445template< typename MT // Type of the sparse matrix
4446 , typename... CCAs > // Compile time column arguments
4447template< typename MT2 // Type of the right-hand side dense matrix
4448 , bool SO > // Storage order of the right-hand side dense matrix
4449inline void Columns<MT,false,false,false,CCAs...>::assign( const DenseMatrix<MT2,SO>& rhs )
4450{
4453
4454 using RT = If_t< IsComputation_v<MT2>, ElementType_t<MT>, const ElementType_t<MT2>& >;
4455
4456 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
4457 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
4458
4459 for( size_t i=0UL; i<rows(); ++i ) {
4460 for( size_t j=0UL; j<columns(); ++j ) {
4461 RT value( (*rhs)(i,j) );
4462 if( !isDefault<strict>( value ) )
4463 matrix_.set( i, idx(j), std::move( value ) );
4464 else matrix_.erase( i, idx(j) );
4465 }
4466 }
4467}
4469//*************************************************************************************************
4470
4471
4472//*************************************************************************************************
4484template< typename MT // Type of the sparse matrix
4485 , typename... CCAs > // Compile time column arguments
4486template< typename MT2 > // Type of the right-hand side sparse matrix
4487inline void Columns<MT,false,false,false,CCAs...>::assign( const SparseMatrix<MT2,false>& rhs )
4488{
4491
4493
4494 using RT = If_t< IsComputation_v<MT2>, ElementType_t<MT>, const ElementType_t<MT2>& >;
4495
4496 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
4497 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
4498 BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4499
4500 for( size_t i=0UL; i<rows(); ++i ) {
4501 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element ) {
4502 RT value( element->value() );
4503 if( !isDefault<strict>( value ) )
4504 matrix_.set( i, idx( element->index() ), std::move( value ) );
4505 else matrix_.erase( i, idx( element->index() ) );
4506 }
4507 }
4508}
4510//*************************************************************************************************
4511
4512
4513//*************************************************************************************************
4525template< typename MT // Type of the sparse matrix
4526 , typename... CCAs > // Compile time column arguments
4527template< typename MT2 > // Type of the right-hand side sparse matrix
4528inline void Columns<MT,false,false,false,CCAs...>::assign( const SparseMatrix<MT2,true>& rhs )
4529{
4532
4533 using RT = If_t< IsComputation_v<MT2>, ElementType_t<MT>, const ElementType_t<MT2>& >;
4534
4535 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
4536 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
4537 BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4538
4539 for( size_t j=0UL; j<columns(); ++j ) {
4540 const size_t index( idx(j) );
4541 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element ) {
4542 RT value( element->value() );
4543 if( !isDefault<strict>( value ) )
4544 matrix_.set( element->index(), index, std::move( value ) );
4545 else matrix_.erase( element->index(), index );
4546 }
4547 }
4548}
4550//*************************************************************************************************
4551
4552
4553//*************************************************************************************************
4565template< typename MT // Type of the sparse matrix
4566 , typename... CCAs > // Compile time column arguments
4567template< typename MT2 // Type of the right-hand side matrix
4568 , bool SO > // Storage order of the right-hand side matrix
4569inline void Columns<MT,false,false,false,CCAs...>::addAssign( const Matrix<MT2,SO>& rhs )
4570{
4573
4574 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4575
4577
4578 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
4579 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
4580
4581 const AddType tmp( serial( *this + (*rhs) ) );
4582 reset();
4583 assign( tmp );
4584}
4586//*************************************************************************************************
4587
4588
4589//*************************************************************************************************
4601template< typename MT // Type of the sparse matrix
4602 , typename... CCAs > // Compile time column arguments
4603template< typename MT2 // Type of the right-hand side matrix
4604 , bool SO > // Storage order of the right-hand side matrix
4605inline void Columns<MT,false,false,false,CCAs...>::subAssign( const Matrix<MT2,SO>& rhs )
4606{
4609
4610 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4611
4613
4614 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
4615 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
4616
4617 const SubType tmp( serial( *this - (*rhs) ) );
4618 reset();
4619 assign( tmp );
4620}
4622//*************************************************************************************************
4623
4624
4625//*************************************************************************************************
4637template< typename MT // Type of the sparse matrix
4638 , typename... CCAs > // Compile time column arguments
4639template< typename MT2 // Type of the right-hand side matrix
4640 , bool SO > // Storage order of the right-hand side matrix
4641inline void Columns<MT,false,false,false,CCAs...>::schurAssign( const Matrix<MT2,SO>& rhs )
4642{
4645
4646 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
4647
4650
4651 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
4652 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
4653
4654 const SchurType tmp( serial( *this % (*rhs) ) );
4655 reset();
4656 assign( tmp );
4657}
4659//*************************************************************************************************
4660
4661
4662
4663
4664
4665
4666
4667
4668//=================================================================================================
4669//
4670// CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC ROW-MAJOR SPARSE MATRICES
4671//
4672//=================================================================================================
4673
4674//*************************************************************************************************
4682template< typename MT // Type of the sparse matrix
4683 , typename... CCAs > // Compile time column arguments
4684class Columns<MT,false,false,true,CCAs...>
4685 : public View< SparseMatrix< Columns<MT,false,false,true,CCAs...>, true > >
4686 , private ColumnsData<CCAs...>
4687{
4688 private:
4689 //**Type definitions****************************************************************************
4690 using DataType = ColumnsData<CCAs...>;
4691 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
4692 //**********************************************************************************************
4693
4694 //**Compile time flags**************************************************************************
4695 using DataType::N;
4696 //**********************************************************************************************
4697
4698 public:
4699 //**Type definitions****************************************************************************
4701 using This = Columns<MT,false,false,true,CCAs...>;
4702
4704 using BaseType = View< SparseMatrix<This,true> >;
4705
4706 using ViewedType = MT;
4707 using ResultType = ColumnsTrait_t<MT,N>;
4708 using OppositeType = OppositeType_t<ResultType>;
4709 using TransposeType = TransposeType_t<ResultType>;
4710 using ElementType = ElementType_t<MT>;
4711 using ReturnType = ReturnType_t<MT>;
4712 using CompositeType = const Columns&;
4713
4715 using ConstReference = ConstReference_t<MT>;
4716
4718 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
4719
4721 using ConstIterator = ConstIterator_t<MT>;
4722
4724 using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
4725 //**********************************************************************************************
4726
4727 //**Compilation flags***************************************************************************
4729 static constexpr bool smpAssignable = MT::smpAssignable;
4730
4732 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
4733 //**********************************************************************************************
4734
4735 //**Constructors********************************************************************************
4738 template< typename... RCAs >
4739 explicit inline Columns( MT& matrix, RCAs... args );
4740
4741 Columns( const Columns& ) = default;
4742 Columns( Columns&& ) = default;
4744 //**********************************************************************************************
4745
4746 //**Destructor**********************************************************************************
4749 ~Columns() = default;
4751 //**********************************************************************************************
4752
4753 //**Data access functions***********************************************************************
4756 inline Reference operator()( size_t i, size_t j );
4757 inline ConstReference operator()( size_t i, size_t j ) const;
4758 inline Reference at( size_t i, size_t j );
4759 inline ConstReference at( size_t i, size_t j ) const;
4760 inline Iterator begin ( size_t j );
4761 inline ConstIterator begin ( size_t j ) const;
4762 inline ConstIterator cbegin( size_t j ) const;
4763 inline Iterator end ( size_t j );
4764 inline ConstIterator end ( size_t j ) const;
4765 inline ConstIterator cend ( size_t j ) const;
4767 //**********************************************************************************************
4768
4769 //**Assignment operators************************************************************************
4772 Columns& operator=( const Columns& ) = delete;
4774 //**********************************************************************************************
4775
4776 //**Utility functions***************************************************************************
4779 using DataType::idx;
4780 using DataType::idces;
4781 using DataType::columns;
4782
4783 inline MT& operand() noexcept;
4784 inline const MT& operand() const noexcept;
4785
4786 inline size_t rows() const noexcept;
4787 inline size_t capacity() const noexcept;
4788 inline size_t capacity( size_t j ) const noexcept;
4789 inline size_t nonZeros() const;
4790 inline size_t nonZeros( size_t j ) const;
4791 inline void reset();
4792 inline void reset( size_t j );
4793 inline void reserve( size_t nonzeros );
4794 void reserve( size_t j, size_t nonzeros );
4795 inline void trim();
4796 inline void trim( size_t j );
4798 //**********************************************************************************************
4799
4800 //**Insertion functions*************************************************************************
4803 inline Iterator set ( size_t i, size_t j, const ElementType& value );
4804 inline Iterator insert ( size_t i, size_t j, const ElementType& value );
4805 inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
4806 inline void finalize( size_t j );
4808 //**********************************************************************************************
4809
4810 //**Erase functions*****************************************************************************
4813 inline void erase( size_t i, size_t j );
4814 inline Iterator erase( size_t j, Iterator pos );
4815 inline Iterator erase( size_t j, Iterator first, Iterator last );
4816
4817 template< typename Pred >
4818 inline void erase( Pred predicate );
4819
4820 template< typename Pred >
4821 inline void erase( size_t j, Iterator first, Iterator last, Pred predicate );
4823 //**********************************************************************************************
4824
4825 //**Lookup functions****************************************************************************
4828 inline Iterator find ( size_t i, size_t j );
4829 inline ConstIterator find ( size_t i, size_t j ) const;
4830 inline Iterator lowerBound( size_t i, size_t j );
4831 inline ConstIterator lowerBound( size_t i, size_t j ) const;
4832 inline Iterator upperBound( size_t i, size_t j );
4833 inline ConstIterator upperBound( size_t i, size_t j ) const;
4835 //**********************************************************************************************
4836
4837 //**Expression template evaluation functions****************************************************
4840 template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
4841 template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
4842
4843 inline bool canSMPAssign() const noexcept;
4845 //**********************************************************************************************
4846
4847 private:
4848 //**Member variables****************************************************************************
4851 Operand matrix_;
4853 //**********************************************************************************************
4854
4855 //**Compile time checks*************************************************************************
4865 //**********************************************************************************************
4866};
4868//*************************************************************************************************
4869
4870
4871
4872
4873//=================================================================================================
4874//
4875// CONSTRUCTORS
4876//
4877//=================================================================================================
4878
4879//*************************************************************************************************
4892template< typename MT // Type of the sparse matrix
4893 , typename... CCAs > // Compile time column arguments
4894template< typename... RCAs > // Runtime column arguments
4895inline Columns<MT,false,false,true,CCAs...>::Columns( MT& matrix, RCAs... args )
4896 : DataType( args... ) // Base class initialization
4897 , matrix_ ( matrix ) // The matrix containing the columns
4898{
4899 if( isChecked( args... ) ) {
4900 for( size_t j=0UL; j<columns(); ++j ) {
4901 if( matrix_.columns() <= idx(j) ) {
4902 BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
4903 }
4904 }
4905 }
4906}
4908//*************************************************************************************************
4909
4910
4911
4912
4913//=================================================================================================
4914//
4915// DATA ACCESS FUNCTIONS
4916//
4917//=================================================================================================
4918
4919//*************************************************************************************************
4930template< typename MT // Type of the sparse matrix
4931 , typename... CCAs > // Compile time column arguments
4932inline typename Columns<MT,false,false,true,CCAs...>::Reference
4933 Columns<MT,false,false,true,CCAs...>::operator()( size_t i, size_t j )
4934{
4935 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4936 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4937
4938 return matrix_(idx(j),i);
4939}
4941//*************************************************************************************************
4942
4943
4944//*************************************************************************************************
4955template< typename MT // Type of the sparse matrix
4956 , typename... CCAs > // Compile time column arguments
4957inline typename Columns<MT,false,false,true,CCAs...>::ConstReference
4958 Columns<MT,false,false,true,CCAs...>::operator()( size_t i, size_t j ) const
4959{
4960 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4961 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4962
4963 return const_cast<const MT&>( matrix_ )(idx(j),i);
4964}
4966//*************************************************************************************************
4967
4968
4969//*************************************************************************************************
4981template< typename MT // Type of the sparse matrix
4982 , typename... CCAs > // Compile time column arguments
4983inline typename Columns<MT,false,false,true,CCAs...>::Reference
4984 Columns<MT,false,false,true,CCAs...>::at( size_t i, size_t j )
4985{
4986 if( i >= rows() ) {
4987 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4988 }
4989 if( j >= columns() ) {
4990 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4991 }
4992 return (*this)(i,j);
4993}
4995//*************************************************************************************************
4996
4997
4998//*************************************************************************************************
5010template< typename MT // Type of the sparse matrix
5011 , typename... CCAs > // Compile time column arguments
5012inline typename Columns<MT,false,false,true,CCAs...>::ConstReference
5013 Columns<MT,false,false,true,CCAs...>::at( size_t i, size_t j ) const
5014{
5015 if( i >= rows() ) {
5016 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
5017 }
5018 if( j >= columns() ) {
5019 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
5020 }
5021 return (*this)(i,j);
5022}
5024//*************************************************************************************************
5025
5026
5027//*************************************************************************************************
5036template< typename MT // Type of the sparse matrix
5037 , typename... CCAs > // Compile time column arguments
5038inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5040{
5041 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5042
5043 return matrix_.begin( idx(j) );
5044}
5046//*************************************************************************************************
5047
5048
5049//*************************************************************************************************
5058template< typename MT // Type of the sparse matrix
5059 , typename... CCAs > // Compile time column arguments
5060inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5062{
5063 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5064
5065 return matrix_.cbegin( idx(j) );
5066}
5068//*************************************************************************************************
5069
5070
5071//*************************************************************************************************
5080template< typename MT // Type of the sparse matrix
5081 , typename... CCAs > // Compile time column arguments
5082inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5084{
5085 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5086
5087 return matrix_.cbegin( idx(j) );
5088}
5090//*************************************************************************************************
5091
5092
5093//*************************************************************************************************
5102template< typename MT // Type of the sparse matrix
5103 , typename... CCAs > // Compile time column arguments
5104inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5106{
5107 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5108
5109 return matrix_.end( idx(j) );
5110}
5112//*************************************************************************************************
5113
5114
5115//*************************************************************************************************
5124template< typename MT // Type of the sparse matrix
5125 , typename... CCAs > // Compile time column arguments
5126inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5128{
5129 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5130
5131 return matrix_.cend( idx(j) );
5132}
5134//*************************************************************************************************
5135
5136
5137//*************************************************************************************************
5146template< typename MT // Type of the sparse matrix
5147 , typename... CCAs > // Compile time column arguments
5148inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5150{
5151 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5152
5153 return matrix_.cend( idx(j) );
5154}
5156//*************************************************************************************************
5157
5158
5159
5160
5161//=================================================================================================
5162//
5163// UTILITY FUNCTIONS
5164//
5165//=================================================================================================
5166
5167//*************************************************************************************************
5173template< typename MT // Type of the sparse matrix
5174 , typename... CCAs > // Compile time column arguments
5175inline MT& Columns<MT,false,false,true,CCAs...>::operand() noexcept
5176{
5177 return matrix_;
5178}
5180//*************************************************************************************************
5181
5182
5183//*************************************************************************************************
5189template< typename MT // Type of the sparse matrix
5190 , typename... CCAs > // Compile time column arguments
5191inline const MT& Columns<MT,false,false,true,CCAs...>::operand() const noexcept
5192{
5193 return matrix_;
5194}
5196//*************************************************************************************************
5197
5198
5199//*************************************************************************************************
5205template< typename MT // Type of the sparse matrix
5206 , typename... CCAs > // Compile time column arguments
5207inline size_t Columns<MT,false,false,true,CCAs...>::rows() const noexcept
5208{
5209 return matrix_.rows();
5210}
5212//*************************************************************************************************
5213
5214
5215//*************************************************************************************************
5221template< typename MT // Type of the sparse matrix
5222 , typename... CCAs > // Compile time column arguments
5223inline size_t Columns<MT,false,false,true,CCAs...>::capacity() const noexcept
5224{
5225 return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
5226}
5228//*************************************************************************************************
5229
5230
5231//*************************************************************************************************
5240template< typename MT // Type of the sparse matrix
5241 , typename... CCAs > // Compile time column arguments
5242inline size_t Columns<MT,false,false,true,CCAs...>::capacity( size_t j ) const noexcept
5243{
5244 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5245
5246 return matrix_.capacity( idx(j) );
5247}
5249//*************************************************************************************************
5250
5251
5252//*************************************************************************************************
5258template< typename MT // Type of the sparse matrix
5259 , typename... CCAs > // Compile time column arguments
5261{
5262 size_t nonzeros( 0UL );
5263
5264 for( size_t j=0UL; j<columns(); ++j )
5265 nonzeros += nonZeros( j );
5266
5267 return nonzeros;
5268}
5270//*************************************************************************************************
5271
5272
5273//*************************************************************************************************
5282template< typename MT // Type of the sparse matrix
5283 , typename... CCAs > // Compile time column arguments
5284inline size_t Columns<MT,false,false,true,CCAs...>::nonZeros( size_t j ) const
5285{
5286 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5287
5288 return matrix_.nonZeros( idx(j) );
5289}
5291//*************************************************************************************************
5292
5293
5294//*************************************************************************************************
5300template< typename MT // Type of the sparse matrix
5301 , typename... CCAs > // Compile time column arguments
5303{
5304 for( size_t j=0UL; j<columns(); ++j ) {
5305 matrix_.reset( idx(j) );
5306 }
5307}
5309//*************************************************************************************************
5310
5311
5312//*************************************************************************************************
5322template< typename MT // Type of the sparse matrix
5323 , typename... CCAs > // Compile time column arguments
5324inline void Columns<MT,false,false,true,CCAs...>::reset( size_t j )
5325{
5326 matrix_.reset( idx(j) );
5327}
5329//*************************************************************************************************
5330
5331
5332//*************************************************************************************************
5343template< typename MT // Type of the sparse matrix
5344 , typename... CCAs > // Compile time column arguments
5345inline void Columns<MT,false,false,true,CCAs...>::reserve( size_t nonzeros )
5346{
5347 const size_t current( capacity() );
5348
5349 if( nonzeros > current ) {
5350 matrix_.reserve( matrix_.capacity() + nonzeros - current );
5351 }
5352}
5354//*************************************************************************************************
5355
5356
5357//*************************************************************************************************
5369template< typename MT // Type of the sparse matrix
5370 , typename... CCAs > // Compile time column arguments
5371void Columns<MT,false,false,true,CCAs...>::reserve( size_t j, size_t nonzeros )
5372{
5373 matrix_.reserve( idx(j), nonzeros );
5374}
5376//*************************************************************************************************
5377
5378
5379//*************************************************************************************************
5389template< typename MT // Type of the sparse matrix
5390 , typename... CCAs > // Compile time column arguments
5391void Columns<MT,false,false,true,CCAs...>::trim()
5392{
5393 for( size_t j=0UL; j<columns(); ++j ) {
5394 trim( j );
5395 }
5396}
5398//*************************************************************************************************
5399
5400
5401//*************************************************************************************************
5412template< typename MT // Type of the sparse matrix
5413 , typename... CCAs > // Compile time column arguments
5414void Columns<MT,false,false,true,CCAs...>::trim( size_t j )
5415{
5416 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5417
5418 matrix_.trim( idx(j) );
5419}
5421//*************************************************************************************************
5422
5423
5424
5425
5426//=================================================================================================
5427//
5428// INSERTION FUNCTIONS
5429//
5430//=================================================================================================
5431
5432//*************************************************************************************************
5445template< typename MT // Type of the sparse matrix
5446 , typename... CCAs > // Compile time column arguments
5447inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5448 Columns<MT,false,false,true,CCAs...>::set( size_t i, size_t j, const ElementType& value )
5449{
5450 return matrix_.set( idx(j), i, value );
5451}
5453//*************************************************************************************************
5454
5455
5456//*************************************************************************************************
5470template< typename MT // Type of the sparse matrix
5471 , typename... CCAs > // Compile time column arguments
5472inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5473 Columns<MT,false,false,true,CCAs...>::insert( size_t i, size_t j, const ElementType& value )
5474{
5475 return matrix_.insert( idx(j), i, value );
5476}
5478//*************************************************************************************************
5479
5480
5481//*************************************************************************************************
5525template< typename MT // Type of the sparse matrix
5526 , typename... CCAs > // Compile time column arguments
5527inline void Columns<MT,false,false,true,CCAs...>::append( size_t i, size_t j, const ElementType& value, bool check )
5528{
5529 if( !check || !isDefault<strict>( value ) )
5530 matrix_.insert( idx(j), i, value );
5531}
5533//*************************************************************************************************
5534
5535
5536//*************************************************************************************************
5550template< typename MT // Type of the sparse matrix
5551 , typename... CCAs > // Compile time column arguments
5552inline void Columns<MT,false,false,true,CCAs...>::finalize( size_t j )
5553{
5554 MAYBE_UNUSED( j );
5555
5556 return;
5557}
5559//*************************************************************************************************
5560
5561
5562
5563
5564//=================================================================================================
5565//
5566// ERASE FUNCTIONS
5567//
5568//=================================================================================================
5569
5570//*************************************************************************************************
5580template< typename MT // Type of the sparse matrix
5581 , typename... CCAs > // Compile time column arguments
5582inline void Columns<MT,false,false,true,CCAs...>::erase( size_t i, size_t j )
5583{
5584 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
5585 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5586
5587 matrix_.erase( idx(j), i );
5588}
5590//*************************************************************************************************
5591
5592
5593//*************************************************************************************************
5603template< typename MT // Type of the sparse matrix
5604 , typename... CCAs > // Compile time column arguments
5605inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5606 Columns<MT,false,false,true,CCAs...>::erase( size_t j, Iterator pos )
5607{
5608 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5609
5610 return matrix_.erase( idx(j), pos );
5611}
5613//*************************************************************************************************
5614
5615
5616//*************************************************************************************************
5627template< typename MT // Type of the sparse matrix
5628 , typename... CCAs > // Compile time column arguments
5629inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5630 Columns<MT,false,false,true,CCAs...>::erase( size_t j, Iterator first, Iterator last )
5631{
5632 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5633
5634 return matrix_.erase( idx(j), first, last );
5635}
5637//*************************************************************************************************
5638
5639
5640//*************************************************************************************************
5663template< typename MT // Type of the sparse matrix
5664 , typename... CCAs > // Compile time column arguments
5665template< typename Pred > // Type of the unary predicate
5666inline void Columns<MT,false,false,true,CCAs...>::erase( Pred predicate )
5667{
5668 for( size_t j=0UL; j<columns(); ++j ) {
5669 matrix_.erase( idx(j), begin(j), end(j), predicate );
5670 }
5671}
5673//*************************************************************************************************
5674
5675
5676//*************************************************************************************************
5703template< typename MT // Type of the sparse matrix
5704 , typename... CCAs > // Compile time column arguments
5705template< typename Pred > // Type of the unary predicate
5706inline void Columns<MT,false,false,true,CCAs...>::erase( size_t j, Iterator first, Iterator last, Pred predicate )
5707{
5708 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5709
5710 matrix_.erase( idx(j), first, last, predicate );
5711}
5713//*************************************************************************************************
5714
5715
5716
5717
5718//=================================================================================================
5719//
5720// LOOKUP FUNCTIONS
5721//
5722//=================================================================================================
5723
5724//*************************************************************************************************
5739template< typename MT // Type of the sparse matrix
5740 , typename... CCAs > // Compile time column arguments
5741inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5742 Columns<MT,false,false,true,CCAs...>::find( size_t i, size_t j )
5743{
5744 return matrix_.find( idx(j), i );
5745}
5747//*************************************************************************************************
5748
5749
5750//*************************************************************************************************
5765template< typename MT // Type of the sparse matrix
5766 , typename... CCAs > // Compile time column arguments
5767inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5768 Columns<MT,false,false,true,CCAs...>::find( size_t i, size_t j ) const
5769{
5770 return matrix_.find( idx(j), i );
5771}
5773//*************************************************************************************************
5774
5775
5776//*************************************************************************************************
5790template< typename MT // Type of the sparse matrix
5791 , typename... CCAs > // Compile time column arguments
5792inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5794{
5795 return matrix_.lowerBound( idx(j), i );
5796}
5798//*************************************************************************************************
5799
5800
5801//*************************************************************************************************
5815template< typename MT // Type of the sparse matrix
5816 , typename... CCAs > // Compile time column arguments
5817inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5818 Columns<MT,false,false,true,CCAs...>::lowerBound( size_t i, size_t j ) const
5819{
5820 return matrix_.lowerBound( idx(j), i );
5821}
5823//*************************************************************************************************
5824
5825
5826//*************************************************************************************************
5840template< typename MT // Type of the sparse matrix
5841 , typename... CCAs > // Compile time column arguments
5842inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5844{
5845 return matrix_.upperBound( idx(j), i );
5846}
5848//*************************************************************************************************
5849
5850
5851//*************************************************************************************************
5865template< typename MT // Type of the sparse matrix
5866 , typename... CCAs > // Compile time column arguments
5867inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5868 Columns<MT,false,false,true,CCAs...>::upperBound( size_t i, size_t j ) const
5869{
5870 return matrix_.upperBound( idx(j), i );
5871}
5873//*************************************************************************************************
5874
5875
5876
5877
5878//=================================================================================================
5879//
5880// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5881//
5882//=================================================================================================
5883
5884//*************************************************************************************************
5895template< typename MT // Type of the sparse matrix
5896 , typename... CCAs > // Compile time column arguments
5897template< typename Other > // Data type of the foreign expression
5898inline bool Columns<MT,false,false,true,CCAs...>::canAlias( const Other* alias ) const noexcept
5899{
5900 return matrix_.isAliased( &unview( *alias ) );
5901}
5903//*************************************************************************************************
5904
5905
5906//*************************************************************************************************
5917template< typename MT // Type of the sparse matrix
5918 , typename... CCAs > // Compile time column arguments
5919template< typename Other > // Data type of the foreign expression
5920inline bool Columns<MT,false,false,true,CCAs...>::isAliased( const Other* alias ) const noexcept
5921{
5922 return matrix_.isAliased( &unview( *alias ) );
5923}
5925//*************************************************************************************************
5926
5927
5928//*************************************************************************************************
5939template< typename MT // Type of the sparse matrix
5940 , typename... CCAs > // Compile time column arguments
5941inline bool Columns<MT,false,false,true,CCAs...>::canSMPAssign() const noexcept
5942{
5943 return false;
5944}
5946//*************************************************************************************************
5947
5948} // namespace blaze
5949
5950#endif
Header file for the addition trait.
Header file for auxiliary alias declarations.
Header file for run time assertion macros.
Header file for the blaze::checked and blaze::unchecked instances.
Constraints on the storage order of matrix types.
Header file for the implementation of the ColumnsData class template.
Header file for the columns trait.
constexpr const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:751
Constraint on the data type.
Header file for the If class template.
Header file for the IsComputation type trait class.
Header file for the IsConst type trait.
Header file for the isDefault shim.
Header file for the IsExpression type trait class.
Header file for the IsLower type trait.
Header file for the IsReference type trait.
Header file for the IsRestricted type trait.
Header file for the IsSparseMatrix type trait.
Header file for the IsStrictlyLower type trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsUniLower type trait.
Header file for the IsUniUpper type trait.
Header file for the IsUpper type trait.
Header file for the MAYBE_UNUSED function template.
Constraint on the data type.
Constraint on the data type.
Constraints on the storage order of matrix types.
Header file for the Schur product trait.
Header file for the subtraction trait.
Constraint on the data type.
Constraint on the data type.
Initializer list type of the Blaze library.
Pointer difference type of the Blaze library.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Header file for the implementation of a matrix representation of an initializer list.
Header file for the SparseMatrix base class.
Header file for the View base class.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:137
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.
Definition: Pointer.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.
Definition: Reference.h:79
auto operator/=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Division assignment operator for the division of a dense matrix by a scalar value ( ).
Definition: DenseMatrix.h:574
decltype(auto) min(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise minimum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1339
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
auto operator+=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Addition assignment operator for the addition of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:386
auto operator*=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:510
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:812
decltype(auto) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:9640
auto operator-=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Subtraction assignment operator for the subtraction of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:448
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:207
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: RowMajorMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.
Definition: RequiresEvaluation.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_HERMITIAN_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Hermitian.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.
Definition: TransExpr.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.
Definition: Submatrix.h:81
#define BLAZE_CONSTRAINT_MUST_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Symmetric.h:60
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.
Definition: Computation.h:81
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.
Definition: SparseMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: UniTriangular.h:81
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: ColumnMajorMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COLUMNS_TYPE(T)
Constraint on the data type.
Definition: Columns.h:81
constexpr bool IsSparseMatrix_v
Auxiliary variable template for the IsSparseMatrix type trait.
Definition: IsSparseMatrix.h:124
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:253
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:293
MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:628
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
MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:562
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
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
void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:1221
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
void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:1195
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:137
#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
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:75
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
MT::Iterator upperBound(SparseMatrix< MT, SO > &sm, size_t i, size_t j)
Returns an iterator to the first index greater than the given index.
Definition: SparseMatrix.h:244
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
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
#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
#define BLAZE_THROW_LOGIC_ERROR(MESSAGE)
Macro for the emission of a std::logic_error exception.
Definition: Exception.h:187
constexpr bool isChecked(const Ts &... args)
Extracting blaze::Check arguments from a given list of arguments.
Definition: Check.h:225
constexpr Unchecked unchecked
Global Unchecked instance.
Definition: Check.h:146
Header file for the exception macros of the math module.
Header file for the extended initializer_list functionality.
Header file for the SparseElement base class.
Header file for basic type definitions.
Header file for the generic max algorithm.
Header file for the generic min algorithm.
Header file for the implementation of the Columns base template.